编译简述

编译一个每个人都写过的hello world程序,就经历了程序编译的全部过程

gcc hello.c -o  hello

可以分为 预处理--->编译--->汇编--->链接

1,预编译

    处理#号开头的语句,如include文件、宏替换、移除注释等,

命令:gcc -E helloc.c -o hello.i

2,编译

    最复杂部分,经过词法分析、语法分析、语义分析、优化过程,生成汇编文件

由预编译后的文件生成汇编文件命令:gcc -S hello.i -o hello.s

或者直接由源码生成汇编文件:gcc -S hello.c -o hellos.s

其实这个gcc编译过程实质是调用一个叫cc1的可执行程序来完成,这是一个编译程序,其一般位于/user/lib/gcc/下,(c++文件对应cc1plus,java对应jc1)

3,汇编

将汇编文件生成机器指令

命令:gcc -c hello.s -o hello.o

由于生成机器指令是通过汇编器as完成,所以也可以使用如下命令

as hello.s -o hello.o

也可以直接源码到机器指令:

gcc -c hello.c -o hello.o

4,链接

      将多个*.o文件链接成可执行文件,通过链接器ld完成,其本质就是把一些指令对其他符号地址的引用加以修正,如地址和空间分配、符号绑定、重定位等。简单例子就是在A文件中要引用B文件的一个fun方法,由于两个文件单独编译分别生成A.o、B.o,但A.o中并不知道B.o中fun的方法地址,而链接就修正A.o中fun的地址,将其指向一个正确的方法地址。

命令:ld A.o B.o -o AB (也可以增加-e指定程序入口,如-e main)

那么具体A.o或者B.o中哪些符号需要重定位尼,保存在.rel.text中,叫重定位表,可以通过objdump -r A.o查看



猜你喜欢

转载自blog.csdn.net/zkuili/article/details/80373439