以前搞编程都是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    %rbpmovq    %rsp, %rbp.seh_setframe   %rbp, 0subq    $32, %rsp.seh_stackalloc 32.seh_endprologuecall    __mainleaq    .LC0(%rip), %rcxcall    printfmovl    $0, %eaxaddq    $32, %rsppopq    %rbpret.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 .xdataU __main
0000000000000000 T mainU 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

c语言编译过程及对应命令相关推荐

  1. GCC 使用-C语言编译过程

    任何一种高级语言,要想在机器上执行,必须翻译为机器能读懂的机器语言.编译器就相当于翻译官,将高级语言翻译为机器语言. GCC 最初只用了编译 C 语言程序,全称是 GNU C Compiler.后来扩 ...

  2. C语言1066字符类型统计,C语言编译过程及数据类型

    写在前面 C语言可以称得上是高级语言中的低级语言,接下来一段时间,我会写一下文章关于c语言,把它的神秘面纱一 一揭开.下面主要是c语言的C语言编译过程及数据类型 源文件编译过程 为了使计算机能执行高级 ...

  3. Linux-C C语言编译过程

    Linux-C C语言编译过程 一.简述     GCC(GNU Compiler Collection,即 GNU 编译器套装),是一套由 GNU  开发的编程 语言编译器.简单介绍使用gcc编译器 ...

  4. C语言:gcc编译过程及make命令、makefile语法规则

    gcc编译过程 编译过程: make && makefile make概述 makefile语法规则 make命令格式 Makefile案例 之所以写成多个文件,是出于模拟多模块编程的 ...

  5. C语言编译过程总结详解

    C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标文件.操作 ...

  6. Go 语言编译过程概述

    Golang 是一门需要编译才能运行的编程语言,也就说代码在运行之前需要通过编译器生成二进制机器码,随后二进制文件才能在目标机器上运行,如果我们想要了解 Go 语言的实现原理,理解它的编译过程就是一个 ...

  7. 源代码C语言编译过程

    从源代码生成可执行文件可以分为四个步骤,分别是预处理(Preprocessing).编译(Compilation).汇编(Assembly)和链接(Linking). 下图是 GCC 生成 a.out ...

  8. adb: createprocessw failed: 系统找不到指定的路径_gcc编译过程、gcc命令参数、静态库和动态库搜索路径...

    一.gcc编译过程 gcc -E hello.c -o hello.s //预处理 gcc -S hello.s -o hello.i //编译 gcc -c hello.i -o hello.o / ...

  9. c语言预处理命令12个,C语言编译预处理和预处理命令

    1.预处理概念:编译程序时,编译器将对程序文件作至少两个阶段的编译预处理,预处理程序预处理阶段和编译程序预处理阶段. 预处理程序预处理阶段:C预处理程序先于C编译程序运行.预处理程序从前向后根据预处理 ...

最新文章

  1. Nginx —— configure的命令参数(nginx编译选项)
  2. Java黑皮书课后题第7章:7.2(倒置输入的数)编写程序,读取10个整数,然后按照和读入顺序相反的顺序将它们显示出来
  3. Tomcat结合Apache、Nginx实现高性能的web服务器
  4. 光信噪比 (OSNR) 的概念及其重要性
  5. 【动态规划】天上掉馅饼
  6. SQL Server中的报表–如何使用数据透视表和日期计算来获取有价值的报表
  7. 避免门事件 巧妙清除搜狗浏览器记录
  8. 反击ARP欺骗 我和网络执法官的战斗
  9. Java面试题2.0--solr
  10. 婚礼邀请函微信小程序
  11. 裂变活动成功的前提:回报大于付出
  12. 小程序接入h5页面_微信小程序跳转外部链接(h5页面)以及数据交互
  13. fmod文档解析音频_将音频插入Word 2007文档
  14. gmai邮箱怎么注册啊
  15. libvirt介绍和使用
  16. 数据库 SQL Server 检测到基于一致性的逻辑 I/O 错误 页撕裂 执行 读取 期间,发生了该错误 恢复
  17. 【深度学习】【积分梯度】深度网络的公理归因(Axiomatic Attribution for Deep Networks)
  18. 工作记录(20191215)
  19. vue v-for 中 img图片渲染不出来的解决方法
  20. openfalcon介绍

热门文章

  1. SIP DTMF telephone-event
  2. 阿里云安装 Redis ,win10使用RDM连接管理redis
  3. Android 读shp属性字段
  4. 服务器端代理proxy实现跨域访问
  5. 限制对比度自适应直方图均衡化算法(CLAHE)实现
  6. 数据结构(一)——链表与邻接表、栈与队列、KMP
  7. 再谈用全域安全防御网络攻击
  8. linux系统自动登出时间设置,ssh修改超时自动登出时间的方法
  9. UVM设计模式 ( 二 ) 参数化类、静态变量/方法/类、单例模式、UVM_ROOT、工厂模式、UVM_FACTORY
  10. 自动喷水灭火系统设计规范