c语言编程笔录

首页 >   > 笔记大全

笔记大全

c语言编译后生成什么文件

更新时间:2023-06-27

前言

在解答这个问题之前,我们需要了解一些基本概念。C语言是一种高级编程语言,程序员使用C语言编写源代码,然后使用编译器将源代码转换为可执行文件。C语言的编译过程可以分为预处理、编译、汇编和链接四个阶段。每个阶段都有特定的任务和输出文件。

1. 预处理阶段

在编译C语言代码之前,预处理器会对源代码进行处理。预处理器的任务包括处理宏定义、条件编译和头文件包含等。预处理器的输出通常是一个经过宏展开和条件编译处理的中间代码文件,该文件以".i"为扩展名。

示例代码:
/* main.c */
#include 

#define MAX_NUM 100

int main() {
    printf("Max number: %d\n", MAX_NUM);
    return 0;
}

预处理后的代码(main.i):
# 1 "main.c"
# 1 ""
# 1 ""
# 1 "main.c" 
# 1 "/usr/include/stdio.h" 1 3 4
...
# 5 "main.c" 2

int main() {
    printf("Max number: %d\n", 100);
    return 0;
}

2. 编译阶段

在编译阶段,编译器会将预处理后的代码转换成汇编语言。汇编语言是一种低级语言,与机器代码有直接的对应关系。编译器的输出是一个以".s"为扩展名的汇编代码文件。

示例代码:
/* main.c */
#include 

#define MAX_NUM 100

int main() {
    printf("Max number: %d\n", MAX_NUM);
    return 0;
}

编译后的汇编代码(main.s):
...
        .globl _main
        .def _main; .scl 2; .type 32; .endef
_main:
        pushl %ebp
        movl %esp, %ebp

        subl $4, %esp
        movl $100, -4(%ebp)

        pushl -4(%ebp)
        pushl $.LC0
        call _printf
        addl $8, %esp

        movl $0, %eax

        movl %ebp, %esp
        popl %ebp
        ret
...

3. 汇编阶段

在汇编阶段,汇编器会将汇编语言代码转换为机器代码。机器代码是计算机可以直接执行的指令。汇编器的输出是一个以".o"为扩展名的目标文件,也称为目标代码文件。

示例代码:
/* main.c */
#include 

#define MAX_NUM 100

int main() {
    printf("Max number: %d\n", MAX_NUM);
    return 0;
}

汇编后的机器代码(main.o):
...
        55                      push    ebp
        89 E5                   mov     ebp, esp

        83 EC 04                sub     esp, 4
        C7 45 FC 64 00 00 00    mov     dword ptr [ebp-4], 100

        FF 75 FC                push    dword ptr [ebp-4]
        68 04 00 00 00          push    4
        E8 FC FF FF FF          call    _printf
        83 C4 08                add     esp, 8

        B8 00 00 00 00          mov     eax, 0

        89 EC                   mov     esp, ebp
        5D                      pop     ebp
        C3                      ret
...

4. 链接阶段

在链接阶段,链接器将目标文件与其他库文件进行链接,生成最终的可执行文件。链接器的任务包括解析符号引用、地址重定向和符号表生成等。链接器的输出是一个以可执行文件或库文件为扩展名的文件。

示例代码(单一文件):
/* main.c */
#include 

#define MAX_NUM 100

int main() {
    printf("Max number: %d\n", MAX_NUM);
    return 0;
}

链接后的可执行文件(main):
...
        08048B81 68 A0 83 04 08    push    080483A0
        08048B86 E8 6F FF FF FF    call    08048AF9
        08048B8B 83 C4 08          add     esp, 8
        08048B8E B8 00 00 00 00    mov     eax, 0
        08048B93 C9                leave
        08048B94 C3                ret

示例代码(与库文件链接):
/* main.c */
#include 
#include 

int main() {
    double result=sqrt(16.0);
    printf("Square root of 16: %f\n", result);
    return 0;
}

链接后的可执行文件(main):
...
        08048B61 E8 F0 FE FF FF    call    sqrt
        08048B66 D9 05 9C 83 04 08    fld     dword ptr [0804839C]
        ...
        08048BAE C3                ret
...