gcc/g++是GNU工程的C和C++编译器。
//test.c
#include <stdio.h>
#define number 12345int main()
{
int res = number*number;
printf("hello world %d = \n",res);
}
gcc test.c -o test
上面这段命令实际上经历了四个阶段:
- 预处理(preprocessing)
- 编译(compilation)
- 汇编(assembly)
- 连接(linking)
# 908 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# 938 "/usr/include/stdio.h" 3 4
# 2 "test.c" 2
int main()
{
int res = 12345*12345;
printf("hello world %d = \n",res);
}
gcc -S test.i -o test.s
作用:Gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,Gcc把代码翻译成汇编语言
内容:
.file "test.c"
.section .rodata
.LC0:
.string "hello world %d = \n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $152399025, 28(%esp)
movl $.LC0, %eax
movl 28(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)"
.section .note.GNU-stack,"",@progbits
3.汇编阶段(assembly)
gcc -C test.s -o test.o
作用:将编译出来的.s 文件汇编成二进制目标代码.o 文件,我们可以通过objdump 程序来查看test.o 的内容
内容:
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 e4 f0 and $0xfffffff0,%esp
6: 83 ec 20 sub $0x20,%esp
9: c7 44 24 1c b1 6c 15 movl $0x9156cb1,0x1c(%esp)
10: 09
11: b8 00 00 00 00 mov $0x0,%eax
16: 8b 54 24 1c mov 0x1c(%esp),%edx
1a: 89 54 24 04 mov %edx,0x4(%esp)
1e: 89 04 24 mov %eax,(%esp)
21: e8 fc ff ff ff call 22 <main+0x22>
26: c9 leave
27: c3 ret
4.链接(linking)
gcc test.o -o test
作用:将编译输出的.o文件链接为最终可执行文件test,可以通过objdump程序来查看链接后的输出test文件的内容
内容:
test: file format elf32-i386
Disassembly of section .init:
08048294 <_init>:
8048294: 55 push %ebp
8048295: 89 e5 mov %esp,%ebp
8048297: 53 push %ebx
8048298: 83 ec 04 sub $0x4,%esp
804829b: e8 00 00 00 00 call 80482a0 <_init+0xc>
80482a0: 5b pop %ebx
80482a1: 81 c3 a8 13 00 00 add $0x13a8,%ebx
80482a7: 8b 93 fc ff ff ff mov -0x4(%ebx),%edx
80482ad: 85 d2 test %edx,%edx
80482af: 74 05 je 80482b6 <_init+0x22>
80482b1: e8 1e 00 00 00 call 80482d4 <__gmon_start__@plt>
80482b6: e8 e5 00 00 00 call 80483a0 <frame_dummy>
80482bb: e8 a0 01 00 00 call 8048460 <__do_global_ctors_aux>
80482c0: 58 pop %eax
80482c1: 5b pop %ebx
80482c2: c9 leave
80482c3: c3 ret
Disassembly of section .plt:
080482c4 <__gmon_start__@plt-0x10>:
80482c4: ff 35 4c 96 04 08 pushl 0x804964c
80482ca: ff 25 50 96 04 08 jmp *0x8049650
80482d0: 00 00 add %al,(%eax)
...
080482d4 <__gmon_start__@plt>:
80482d4: ff 25 54 96 04 08 jmp *0x8049654
80482da: 68 00 00 00 00 push $0x0
80482df: e9 e0 ff ff ff jmp 80482c4 <_init+0x30>
......
小结:
编译程序的4个过程:
预处理:gcc -E test.c -o test.i
编译:gcc –S test.i –o test.s
汇编:gcc –c test.s –o test.o
链接:gcc test.o -o test