第一篇文章

一、前言

最近在看CSAPP(深入理解计算机系统)然后以前也学过C语言,但是从来没有深究写好的C代码是怎么编译再到执行的。

所以现在自己学习,然后记录下来。

以最常用的hello world!程序为例  程序名:  main.c

#include <stdio.h>

int main()
{
printf("Hello world!\n");
return 0;
}

二、C程序编译过程

hello程序的生命周期是从一个高级C语言程序开始的,为了能够运行hello.c程序,每一条C语句都被其他程序转化为一系列的低级机器语言指令。然后这些指令按照一种称为可执行目标程序的格式打包,以二进制磁盘文件的形式存放起来。目标程序也称为可执行目标文件


编译一个 C程序可以分为四阶段:预处理阶段 ---> 生成汇编代码阶段 ---> 汇编阶段 ---> 链接阶段


各个阶段的代码可以通过gcc指令来生成

如果没有gcc可以用下面指令安装

sudo apt-get  build-dep  gcc

安装完之后可以根据以下指令查看是否安装成功

gcc --version

安装好后用下面指令生成中间文件

gcc main.c                      直接生成可执行文件 a.out
gcc -E main.c -o hello.i 生成预处理后的代码
gcc –S main.c -o hello.s 生成汇编代码
gcc –c main.c -o hello.o 生成目标代码

三、阶段过程

  1、预处理阶段

gcc -E main.c -o hello.i        生成预处理后的代码

  预处理器(cpp)根据以字符 # 开头的命令,修改原始的C程序。比如mian.c中第一行的 #include<stdio.h> 命令就告诉预处理器读取系统头文件stdio.h的内容,并且把它直接插入程序文本中。同时删除注释行,添加行号和文件名标识。这样就得到了另一个C程序,通常是以  .i  作为文件扩展名。 所以经过预编译的 .i 文件是不包含宏定义的。

  处理完后我们来看看 hello.i 文件。发现原来的7行代码变成了700多行,我们的代码在最后面。而前面多出来的代码就是 .c 中#include<stdio.h>展开的代码。

  2、编译阶段

gcc –S main.c -o hello.s     生成汇编代码

  编译是将源文件(hello.i)翻译成汇编文件(hello.s)的过程。中间包含词法、语法分析等步骤,具体过程可以参考《编译原理》。

  打开汇编代码我们会发现里面有很多以   . 开头的行,所有这些以 . 开头的行都是指导汇编器和链接器工作的伪指令。 我们通常可以忽略这些行。

  去掉这些行后剩下的部分。

  3、汇编阶段

  

gcc –c main.c -o hello.o        生成目标代码

汇编阶段是把编译阶段生成的  .s 文件转成 .o 的二进制目标代码。汇编器(as)将 hello.s 翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,它的字节编码是机器语言指令而不是字符。如果我们在文本编译器中打开 hello.o 文件,看到的将是一堆乱码。

你非要看就是这样

  4、链接阶段

  这个阶段就是把汇编后的机器指令集变成可以直接运行的文件,而对目标文件进行链接主要是因为在目标文件中可能用到了在其他文件当中定义的字段(或者函数),通过链接来把多个不同目标文件关联到一起。

  hello 程序调用了printf 函数,它是每个 C 编译器都会提供的标准C库中的一个函数,printf 函数存在于一个名为 printf.o 的单独预编译好了的标准文件中,而这个文件必须以某种方式合并到我们的 hello.o 程序中,链接器(ld)就负责处理这种合并,结果就得到 hello 文件,它是一个可执行目标文件(简称:可执行文件),可以被加载到内存中,有系统执行。

这一部分可以参考《程序员的自我修养》

C程序从编译到运行的更多相关文章

  1. .NET程序的编译和运行

    程序的编译和运行,总得来说大体是:首先写好的程序是源代码,然后编译器编译为本地机器语言,最后在本地操作系统运行. 下图为传统代码编译运行过程: .NET的编译和运行过程与之类似,首先编写好的源代码,然 ...

  2. DOS环境下含包并引用第三方jar的java程序的编译及运行

    DOS环境下含包并引用第三方jar的java程序的编译及运行 1.程序目录机构 bin:class文件生成目录 lib:第三方jar包目录 src:源程序文件目录 2.程序代码: 3.程序编译 jav ...

  3. Java与C++程序在编译和运行上的区别

    Java.C++都属于高级语言,而计算机能认识执行的只是机器码(即二进制),所以高级语言都必须经过直接或间接的转换成汇编以后,才能运行: 对于C/C++这类高级计算机语言,它们的编译器(例如Unix下 ...

  4. Linux下C程序的编译,运行,及调试

    先查看linux有没有gcc 和 gdb $ gcc -v $ gdb -v 如果没有安装gcc,可以 $ yum install gcc 要获取管理员权限才能安装软件,$ su root (有的li ...

  5. java 应用程序的编译和运行

    1.java 文件的编译和执行步骤. 第一步:使用编辑器编辑  后缀为java的文件,里面包含主类(包含 main()函数), 源文件的命名规则是,如果源文件中有多个类,那么只能有一个类是public ...

  6. .NET概念:.NET程序编译和运行

    .NET概念:.NET程序编译和运行 分类: c#程序设计 2012-02-29 15:46 3001人阅读 评论(2) 收藏 举报 .net编译器语言microsoftassemblyvb.net ...

  7. Java程序编译和运行的过程

    Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来简单的说明整个流程. 如下图,Java程序从源文件创建到程序运行要经过两大步骤:1.源文件由编译器编译成字节码(ByteCode)  2 ...

  8. Java程序编译和运行的过程【转】

    转自:http://www.360doc.com/content/14/0218/23/9440338_353675002.shtml Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来 ...

  9. .NET程序编译和运行

    一次面试的时候遇到的一道题目,简要说明.NET的编译过程,在网上看了很多资料,简单总结如下: 1.一般的编译过程 通常高级语言的程序编译过程是:首先写好的程序是源代码,然后编译器编译为本地机器语言,最 ...

随机推荐

  1. JVM垃圾回收器总结

    常见七种垃圾回收器以及使用的垃圾回收算法总结:

  2. C++ primer plus读书笔记——第6章 分支语句和逻辑运算符

    第6章 分支语句和逻辑运算符 1. 逻辑运算符的优先级比关系运算符的优先级低. 2. &&的优先级高于||. 3. cctype中的函数P179. 4. switch(integer- ...

  3. Java初始化数据域的途径

    Java调用构造器的具体处理步骤: 1.所有数据域被初始化为默认值(0,false或null); 2.按照在类声明中出现的次序,依次执行所有域的初始化语句和初始化块: 3.如果构造器第一行调用了第二个 ...

  4. Java中对象池的本质是什么?(实战分析版)

    简介 对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是可以集中管理池中对象,减少频繁创建和销毁长期使用的对象,从而提 ...

  5. 关于Java的 long,float 类型

    发现了这么一个坑: 1.2f+3.4f=4.60000014305114751.2d+3.4d=4.6

  6. Solon Aop 特色开发(1)注入或手动获取配置

    常规操作,先启动 Solon public class App{ public void main(String[] args){ Solon.start(App.class, args); } } ...

  7. Logstash 的命令行入门 ( 附上相关实验步骤 )

    Logstash 的命令行入门 ( 附上相关实验步骤 ) 在之前的博客中,我们已经在 Macbook Big Sur 环境下安装了 ELK 的相关软件,并且已经可以成功运行对应的模块: 如果没有安装的 ...

  8. 【Web前端HTML5&CSS3】08-盒模型补充

    笔记来源:尚硅谷Web前端HTML5&CSS3初学者零基础入门全套完整版 目录 盒模型补充及田径场实战 1. 盒子大小 2. 轮廓 3. 阴影 4. 圆角 圆 椭圆 盒模型补充及田径场实战 1 ...

  9. ruby基础(二)

    ruby语法基础 1.方法 方法时对象定义的与该对象相关的操作.在Ruby中,对象的所有的操作都被封装成 方法. 语法糖:语法糖是一种为了照顾一般人的习惯而产生的特殊语法. ruby中一切数据都是对象 ...

  10. centos7 Nacos+Elasticsearch+SkyWalking

    安装包下载 nacos 下载地址:https://github.com/alibaba/nacos/releases es 下载地址:https://www.elastic.co/cn/downloa ...