$ gcc -E hello.c -o hello.i // 将源文件hello.c文件预处理生成hello.i// GCC的选项-E使GCC在进行完预处理后即停止
hello.i文件可以作为普通文本文件打开进行查看,其代码片段如下所示:// hello.i代码片段extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));# 942 "/usr/include/stdio.h" 3 4# 2 "hello.c" 2# 3 "hello.c"intmain(void){printf("Hello World!" "n");return 0;}
2.编译编译过程就是对预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码 。
使用gcc进行编译的命令如下:
$ gcc -S hello.i -o hello.s // 将预处理生成的hello.i文件编译生成汇编程序hello.s// GCC的选项-S使GCC在执行完编译后停止,生成汇编程序
上述命令生成的汇编程序hello.s的代码片段如下所示,其全部为汇编代码 。// hello.s代码片段main:.LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6movl $.LC0, %edicall putsmovl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc
3.汇编汇编过程调用对汇编代码进行处理,生成处理器能识别的指令,保存在后缀为.o的目标文件中 。由于每一个汇编语句几乎都对应一条处理器指令,因此,汇编相对于编译过程比较简单,通过调用Binutils中的汇编器as根据汇编指令和处理器指令的对照表一一翻译即可 。
当程序由多个源代码文件构成时,每个文件都要先完成汇编工作,生成.o目标文件后,才能进入下一步的链接工作 。注意:目标文件已经是最终程序的某一部分了,但是在链接之前还不能执行 。
使用gcc进行汇编的命令如下:
$ gcc -c hello.s -o hello.o // 将编译生成的hello.s文件汇编生成目标文件hello.o// GCC的选项-c使GCC在执行完汇编后停止,生成目标文件//或者直接调用as进行汇编$ as -c hello.s -o hello.o //使用Binutils中的as将hello.s文件汇编生成目标文件
注意:hello.o目标文件为ELF(Executable and Linkable Format)格式的可重定向文件 。4.链接
链接也分为静态链接和动态链接,其要点如下:
- 静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大 。链接器将函数的代码从其所在地(不同的目标文件或静态链接库中)拷贝到最终的可执行程序中 。为创建可执行文件,链接器必须要完成的主要任务是:符号解析(把目标文件中符号的定义和引用联系起来)和重定位(把符号定义和内存地址对应起来然后修改所有对符号的引用) 。
- 动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去 。
- 在Linux系统中,gcc编译链接时的动态库搜索路径的顺序通常为:首先从gcc命令的参数-L指定的路径寻找;再从环境变量LIBRARY_PATH指定的路径寻址;再从默认路径/lib、/usr/lib、/usr/local/lib寻找 。
- 在Linux系统中,执行二进制文件时的动态库搜索路径的顺序通常为:首先搜索编译目标代码时指定的动态库搜索路径;再从环境变量LD_LIBRARY_PATH指定的路径寻址;再从配置文件/etc/ld.so.conf中指定的动态库搜索路径;再从默认路径/lib、/usr/lib寻找 。
- 在Linux系统中,可以用ldd命令查看一个可执行程序依赖的共享库 。
- 在Linux系统中,gcc编译链接时的动态库搜索路径的顺序通常为:首先从gcc命令的参数-L指定的路径寻找;再从环境变量LIBRARY_PATH指定的路径寻址;再从默认路径/lib、/usr/lib、/usr/local/lib寻找 。
- 如果使用命令“gcc hello.c -o hello”则会使用动态库进行链接,生成的ELF可执行文件的大小(使用Binutils的size命令查看)和链接的动态库(使用Binutils的ldd命令查看)如下所示:
$ gcc hello.c -o hello$ size hello //使用size查看大小text data bss dec hex filename1183 552 8 1743 6cf hello$ ldd hello //可以看出该可执行文件链接了很多其他动态库,主要是Linux的glibc动态库linux-vdso.so.1 => (0x00007fffefd7c000)libc.so.6 => /lib/x
推荐阅读
- 程序员告诉你微信营销号如何防封、解封
- 从零安装一个Linux操作系统几种方法,以Ubuntu18.04为例
- 史上最详细的Linux网卡ifcfg-eth0配置详解
- 用C语言编写CPU使用率限制程序
- 小程序如何引流推广?学会这几点就不难了
- 简易的Mac驱动程序
- Linux useradd 命令介绍
- linux开放指定端口命令
- Linux中如何对硬盘进行分区、格式化、挂载使用
- Linux中如何添加SWAP