您的位置:首页 > 其它

gcc编译过程简析

2014-10-21 22:59 260 查看
今天360面试,问了一道gcc编译的问题,说实话这个问题在之前真看过,不过不知道多就之前了,所以忘记了,只答出了由.xxc直接到目标文件xx.o然后直接到可执行文件了。

正文

gcc的整个编译过程分为四个阶段:预编译,编译,汇编以及链接
这里准备一个test.c文件作为例子进行说明
<pre name="code" class="cpp">#include <stdio.h>

#define HELLO "hello world"
int main(){
printf("%s\n",HELLO);
return 0;
}




预编译: 

将源文件中所有的#开头的内存做处理,宏替换就是在这里完成的。

通过命令gcc -E test.c -o test.i 进行预编译,看一下test.i的主要内容

# 943 "/usr/include/stdio.h" 3 4

# 2 "test.c" 2

int main(){
printf("%s\n","hello world");
return 0;
}

可以看到宏定义被替换了。同时还包含一些stdio.h中的声明

编译

编译就是将test.i编程成汇编代码。通过命令gcc -S test.i -o test.s
.file "test.c"
.section  .rodata
.LC0:
.string "hello world"
.text
.globl  main
.type main, @function
main:
.LFB0:
.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
movl  $.LC0, (%esp)
call  puts
movl  $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident  "GCC: (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2"
.section  .note.GNU-stack,"",@progbits

汇编

汇编的过程就是将test.s汇编代码生成对应的机器码,也就是通常我们所说的目标文件。
通过命令gcc -c test.s -o test.o 



链接

链接就是将目标文件中使用到的符号进行依赖关系处理,找到一些静态库以及动态库,链接的过程极为复杂,记得有一本经典的书讲的很好。
通过ld命令进行链接操作生成最后的可执行文件

参考

http://blog.chinaunix.net/uid-20196318-id-28797.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: