一. GCC编译过程

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            // 链接。将生成的二进制代码与系统库函数进行链接,生成可执行文件

各阶段的代码内容如下:

hello.c (原始C代码)

#include <stdio.h>

int main()
{
printf("hello, world\n");
}

hello.i (头文件替换后的C代码)

#  "hello.c"
# "<built-in>"
# "<命令行>"
# "hello.c"
# "/usr/include/stdio.h"
...
...
...
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# "/usr/include/stdio.h" # "hello.c" int main()
{
printf("hello, world\n");
}

hello.s (汇编代码)

.file    "hello.c"
.section .rodata
.LC0:
.string "hello, world"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset
.cfi_offset , -
movl %esp, %ebp
.cfi_def_cfa_register
andl $-, %esp
subl $, %esp
movl $.LC0, (%esp)
call puts
leave
.cfi_restore
.cfi_def_cfa ,
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits

hello.o (二进制代码)

457f 464c      

011c
000d 000a 83e5 f0e4 ec83 c710
fce8 ffff c9ff 00c3 6c6c
2c6f 726f 646c 3a43
6e75 4c2f 6e69 206f 2e34
2e36 2d33 746e 2e34
2e36 7a01
7c01 0c1b 001c
00000a0 001c 080e
00000b0 0d42 0cc5 2e00
00000c0 746d 2e00 2e00
00000d0 2e00 2e6c
00000e0 2e00 2e00 722e 646f
00000f0 632e 6d6f 656d 746e 2e00 6f6e
472e 554e 732d 6b63 2e00
2e6c 665f 656d *
001f 001b
03e8
000b 00001a0 004c

二.技术背景

  • 计算机的早期,程序都是直接运行在硬件之上,自己负责硬件的管理工作;程序员也使用二进制进行编程,需要处理各种边界条件和安全问题。
  • 后来人们不能忍受了,于是开发出了操作系统,让它来管理各种硬件,同时发明了汇编语言,减轻程序员的负担。
  • 随着软件规模的不断增大,使用汇编语言编程开始变得捉襟见肘,不仅学习成本高,开发效率也很低,于是C语言诞生了。C语言编译器先将C代码翻译为汇编代码,再由汇编器将汇编代码翻译成机器指令。

 

1.GCC编译过程的更多相关文章

  1. Linux学习---GCC编译过程

    (一)GCC编译过程 预处理 cpp -o a.i a.c     //生成预处理文件 等同于[gcc -E] //预处理为将宏定义(#define)等进行替换. 编译 /user/lib/gcc/i ...

  2. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

  3. unix gcc编译过程

    gcc编译过程 现代编译器常见的编译过程: 源文件-->预处理-->编译/优化-->汇编-->链接-->可执行文件 对于gcc而言: 第一步 预处理       命令: ...

  4. gcc 编译过程

    gcc 编译过程从 hello.c 到 hello(或 a.out)文件, 必须历经 hello.i. hello.s. hello.o,最后才得到 hello(或a.out)文件,分别对应着预处理. ...

  5. GCC编译过程

    以下是C程序一般的编译过程: gcc的编译流程分为四个步骤,分别为:· 预处理(Pre-Processing) 对C语言进行预处理,生成*.i文件.· 编译(Compiling) 将上一步生成的*.i ...

  6. Linux系统GCC常用命令和GCC编译过程描述

    前言: GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理 C语言.GCC 很快地扩展,变得可处理 C++.后来又 扩展能够支持更多编程语言,如Fortran. ...

  7. gcc编译过程简述

    在linux系统上,从源文件到目标文件的转化是由编译器完成的.以hello.c程序的编译为例,如下: dfcao@linux: gcc -o hello hello.c 在这里,gcc编译器读取源文件 ...

  8. system 系统调用、gcc编译过程

    system 库函数的功能是执行操作系统的命令或者运行指定的程序 #include <stdio.h> #include <stdlib.h>//引入库 int main() ...

  9. 和菜鸟一起学c之gcc编译过程及其常用编译选项【转】

    转自:http://blog.csdn.net/eastmoon502136/article/details/8162626 版权声明:本文为博主东月之神原创文章,未经博主允许不得转载. 上篇文章,知 ...

随机推荐

  1. iOS-Runtime、对象模型、消息转发

    Objective-C只是在C语言层面上加了些关键字和语法.真正让Objective-C如此强大的是它的运行时.它很小但却很强大.它的核心是消息分发. Message 执行一个方法,有些语言.编译器会 ...

  2. andriod 启动日历

    Intent intent=new Intent();intent.setComponent(new ComponentName("com.android.calendar", & ...

  3. python笔记5-python2写csv文件中文乱码问题

    前言 python2最大的坑在于中文编码问题,遇到中文报错首先加u,再各种encode.decode. 当list.tuple.dict里面有中文时,打印出来的是Unicode编码,这个是无解的. 对 ...

  4. 一.RocketMQ消息中间件 windwos使用

    ⦁    能够保证严格的消息顺序⦁    提供丰富的消息拉取模式⦁    高效的订阅者水平扩展能力⦁    实时的消息订阅机制⦁    亿级的消息堆积能力⦁    下载https://github.c ...

  5. iOS:转载:同步、异步、并行、串行的详解

    理解 iOS 开发中 GCD 相关的同步(synchronization)\ 异步(asynchronization),串行(serial)\ 并行(concurrency)概念 2014年11月21 ...

  6. GPU bubbles

    https://software.intel.com/en-us/articles/performance-analysis-and-optimization-for-pc-based-vr-appl ...

  7. SQL通过身份证获取信息

    SELECT t.identity_number '身份证号',SUBSTR(t.identity_number,1,2) AS "省份",SUBSTR(t.identity_nu ...

  8. 开发 nodejs REST 个人感想

    本来想拿 nodejs 做个 ip 查询小应用的,做的时候想着把基础弄好再做应用,没想到做着做着就变成 spring 了 可能太多数人觉得不知道怎么用,以后我会写详细点使用教程 个人感觉自己做出来的东 ...

  9. 转: APK签名校验绕过

    转: http://drops.wooyun.org/mobile/4296 APK签名校验绕过 3xpl0it · 2014/12/11 10:41 0x01 Android签名机制 将APK重命名 ...

  10. (剑指Offer)面试题37:两个链表的第一个公共结点

    题目: 输入两个链表,找出它们的第一个公共结点. 链表结点的定义如下: struct ListNode{ int val; ListNode* next; ListNode(int x):val(x) ...