c语言编译过程及对应命令

6 篇文章 0 订阅
2 篇文章 1 订阅

以前搞编程都是IDE,虽然也知道编译这么几个步骤,但如何实现还真不是太清楚,工作在搞linux内核驱动开发,平时做个实验也只是:gcc hello.c -o hello
前段时正好在看些汇编,也就顺便学习了这些,趁着没事,分享一下。
在这里插入图片描述

0、源代码

#include <stdio.h>
int main(void){
	printf("hello_world");
	return 0;
}

1、预处理

gcc -E hello.c -o hello.i

实质上是处理“#”,将#include包含的头文件直接拷贝到hello.c当中;将#define定义的宏进行替换,同时将代码中没用的注释部分删除等

具体做的事儿如下:

  • 将所有的#define删除,并且展开所有的宏定义,说白了就是字符替换
  • 处理所有的条件编译指令,#ifdef #ifndef #endif等,就是带#的那些
  • 处理#include,将#include指向的文件插入到该行处删除所有注释
  • 添加行号和文件标示,这样的在调试和编译出错的时候才知道是是哪个文件的哪一行
  • 保留#pragma编译器指令,因为编译器需要使用它们。
# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "hello.c"
# 1 "G:/mingw64/x86_64-w64-mingw32/include/stdio.h" 1 3
# 9 "G:/mingw64/x86_64-w64-mingw32/include/stdio.h" 3
# 1 "G:/mingw64/x86_64-w64-mingw32/include/crtdefs.h" 1 3
# 10 "G:/mingw64/x86_64-w64-mingw32/include/crtdefs.h" 3
# 1 "G:/mingw64/x86_64-w64-mingw32/include/_mingw.h" 1 3
# 12 "G:/mingw64/x86_64-w64-mingw32/include/_mingw.h" 3
.....
.....
.....
# 1400 "G:/mingw64/x86_64-w64-mingw32/include/stdio.h" 2 3
# 2 "hello.c" 2

# 2 "hello.c"
int main(void){
 printf("hello_world");
 return 0;
}

2、编译

gcc -S hello.i -o hello.s

这里可以将hello.i换成hello.c

编译的过程实质上是把高级语言翻译成汇编语言的过程,即对hello.c做了这些事儿

  • 词法分析
  • 语法分析
  • 语义分析
  • 优化后生成相应的汇编代码

高级语言->汇编语言

$ cat hello.s
        .file   "hello.c"
        .text
        .def    __main; .scl    2;      .type   32;     .endef
        .section .rdata,"dr"
.LC0:
        .ascii "hello_world\0"
        .text
        .globl  main
        .def    main;   .scl    2;      .type   32;     .endef
        .seh_proc       main
main:
        pushq   %rbp
        .seh_pushreg    %rbp
        movq    %rsp, %rbp
        .seh_setframe   %rbp, 0
        subq    $32, %rsp
        .seh_stackalloc 32
        .seh_endprologue
        call    __main
        leaq    .LC0(%rip), %rcx
        call    printf
        movl    $0, %eax
        addq    $32, %rsp
        popq    %rbp
        ret
        .seh_endproc
        .ident  "GCC: (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project) 8.1.0"
        .def    printf; .scl    2;      .type   32;     .endef

3、汇编

gcc -c hello.s -o hello.o
这里可以将hello.s换成hello.c

这个过程就是把汇编指令翻译成机器语言(二进制文件)

$ nm -C hello.o
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 p .pdata
0000000000000000 r .rdata
0000000000000000 r .rdata$zzz
0000000000000000 t .text
0000000000000000 r .xdata
                 U __main
0000000000000000 T main
                 U printf

4、链接

gcc hello.o -o hello

最后就是链接,也就是把将翻译成的二进制与需要用到库绑定在一块,生成可执行文件。这时间的hello.o是不能执行的,hello是可以的。

$ ./hello 
hello_world

总结

预处理:gcc -E hello.c -o hello.i

编 译:gcc -S hello.i -o hello.s

汇 编:gcc -c hello.s -o hello.o

链 接:gcc hello.o -o hello

直接编译:gcc hello.c -o hello

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值