C语言学习笔记之 编译器编译流程
编译器编译流程
- 预处理(.i)
- 编译(.s)
- 汇编(.o)
- 链接(.exe .out)
示例文件:main.c
// main.c
#include <stdio.h>
#define NAME 'C'
// 主函数
int main() {
printf("Hello %c\n",NAME);
return 0;
}
预处理
展开头文件,宏替换,去掉注释,条件编译
命令:
gcc -E main.c -o main.i
main.i最后五行:
# 5 "main.c"
int main() {
printf("Hello %c\n",'C');
return 0;
}
可以看到,注释已经被去掉,宏也被替换了
编译
检查语法,生成汇编
命令:
gcc -S main.i -o main.s
main.s内容(汇编代码):
.file "main.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "Hello %c\12\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB13:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
movl $67, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE13:
.ident "GCC: (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 5.3.0"
.def _printf; .scl 2; .type 32; .endef
汇编
汇编代码转机器码
命令:
gcc -c main.s -o main.o
此时main.o是二进制文件,不能直接打开
Python中打开内容如下:
b'L\x01\x06\x00\x00\x00\x00\x00\xdc\x01\x00\x00\x12\x00\x00\x00\x00\x00\x04\x01.text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x04\x01\x00\x00\xb4\x01\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00 \x000`.data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x000\xc0.bss\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x000\xc0.rdata\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x000\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x000@/4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00<\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x000@/15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00|\x01\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00@\x000@U\x89\xe5\x83\xe4\xf0\x83\xec\x10\xe8\x00\x00\x00\x00\xc7D$\x04C\x00\x00\x00\xc7\x04$\x00\x00\x00\x00\xe8\x00\x00\x00\x00\xb8\x00\x00\x00\x00\xc9\xc3\x90\x90\x90Hello %c\n\x00\x00\x00GCC: (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 5.3.0\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x01zR\x00\x01|\x08\x01\x1b\x0c\x04\x04\x88\x01\x00\x00\x1c\x00\x00\x00\x1c\x00\x00\x00\x04\x00\x00\x00)\x00\x00\x00\x00A\x0e\x08\x85\x02B\r\x05e\xc5\x0c\x04\x04\x00\x00\n\x00\x00\x00\x10\x00\x00\x00\x14\x00\x19\x00\x00\x00\n\x00\x00\x00\x06\x00\x1e\x00\x00\x00\x11\x00\x00\x00\x14\x00 \x00\x00\x00\x04\x00\x00\x00\x14\x00.file\x00\x00\x00\x00\x00\x00\x00\xfe\xff\x00\x00g\x01main.c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_main\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.text\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x01)\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.data\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.bss\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.rdata\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x01\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x01?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x03\x018\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00___main\x00\x00\x00\x00\x00\x00\x00 \x00\x02\x00_printf\x00\x00\x00\x00\x00\x00\x00 \x00\x02\x00.\x00\x00\x00.rdata$zzz\x00.eh_frame\x00.rdata$zzz\x00.eh_frame\x00'
链接
链接到一起生成可执行文件
命令:
gcc main.o -o main