gcc 编译四个阶段

gcc/g++是GNU工程的C和C++编译器。

//test.c

#include <stdio.h>

#define number 12345
int main()
{
        int res = number*number;
        printf("hello world %d = \n",res);

}

gcc test.c -o test

上面这段命令实际上经历了四个阶段:

  • 预处理(preprocessing)
  •  编译(compilation)
  • 汇编(assembly)
  • 连接(linking)
1. 预处理阶段:

gcc -E test.c -o test

作用:对test.c 进行预处理,在头部将stdio.h插入到test.c,并将宏替换成相应的内容,输出为test.i预处理文件
内容:
......
......
extern char *ctermid (char *__s) __attribute__ ((__nothrow__));
# 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);
}


2.编译阶段(compilation)

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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值