• 编译的过程
  1. 宏定义符号的预处理,即宏替换,还有#include的内容给copy进来,#if等条件编译不满足项的也去掉。
  2. 编译:xx.c -> xx.s(词法分析,语法分析,得到的汇编程序) -> xx.o目标代码(这个本身就是可执行的二进制(就是前面的汇编指令按照指令集机器码对照表转过来的)文件了,只是因为使用到的某些函数还跳转不了,所以才需要第二步链接),仅仅只是编译本xx.c文件看看有没有语法错误而已,和标识符地址分配。
  3. 链接:xx.c里面用到了printf这样的库函数,因此需要将xx.o里面的printf符号跟libc.a(Linux中为glibc.a)这个库进行链接,这样main.c里面的所有函数都得到了正确跳转,从而得到了完整的可执行二进制代码文件。其中链接又分为静态链接(gcc所做的事)和动态连接(操作系统的加载器自己做),具体看这个深入浅出静态链接和动态链接

注:libc.a为一个操作系统的底层基本库,里面有printf,string,io,thread等的实现,几乎所有的其它库或者程序都会依赖它,自己写个hello world也得用到printf函数,而此函数的头文件是stdio.h,而此头文件对应的源文件就编译进了libc.a库里。

  • 与gcc并列的工具,binutils工具提供了一系列用来创建、管理和维护二进制目标文件的工具程序,如汇编(as)、连接(ld)、静态库归档(ar)、反汇编 (objdump)、elf结构分析工具(readelf)、无效调试信息和符号的工具(strip)等。通常,binutils与gcc是紧密相集成 的,没有binutils的话,gcc是不能正常工作的。
  1. 库文件操作命令:ar ----非常好的东东。。让你能查看函数库里的详细情况和用多个对象文件生成一个库文件。经常用法:
    • ar -t libname.a //显示所有对象文件(.o文件)的列表.例: # ar t libtest.a
      libtest1.o
      libtest2.o
    • ar -rv libname.a  objfile1.o objfile2.o ... objfilen.o  //把objfile1.o--objfilen.o打包成一个库文件
  2. nm --列出目标文件(.o)的符号清单。。NND,太激动了。刚知道此命令时让我三天没睡好觉。我就使劲用了一把。
  3. objdump  文件命令功能强的惊人。能实现上述两个命令(ar,nm)的 很多功能。它主要是查看对象文件的内容信息。具体查看这个文章gcc的ar,nm,objdump,objcopy