1、编译系统

1 编译系统

1.1 引入编译系统

一个简单的 C语言程序:hello.c

#include
int main(){
    int a=1;
    int b=2;
    int c=a+b;
    printf("hello c\n");
    return c;
}

高级语言:C语言,需要先转换成低级的机器语言,才能被计算机所执行。转换过程,就是编译过程,由编译系统来完成这个转换。

1.2 编译系统的组成

编译系统由预处理器、编译器、汇编器、和链接器四部分组成。如图所示:

1、编译系统

高级语言转换成可执行的机器语言,过程经过以上四个阶段。

1.2.1 预处理器

预处理阶段,预处理器根据以字符#开头的命令,修改原始的C程序。例如:#include

1.2.2 编译器

编译阶段,编译器将文本文件 hello.i 翻译成文本文件 hello.s ,由C程序变为汇编程序。这里引入汇编语言:是机器语言的文本表示,给出程序中的每一条指令。

1.2.3 汇编器

汇编阶段:汇编器将hello.s翻译成机器语言指令,把指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中。hello.o文件是二进制文件。

1.2.4 链接器

链接阶段:链接器负责将目标文件和外部符号进行连接,得到一个可执行二进制文件,可以被加载到内存中,由系统执行。例如hello程序调用了printf函数,它是每个C编译器都提供的标准C库中的一个函数。printf函数存在于一个名为printf.o的单独的预编译好的目标文件中,这个文件必须以某种方式合并到hello程序中。

2 GCC

  1. GCC是C语言的编译器
  2. 谓编译器,可以简单地将其理解为”翻译器”。实际上,计算机只认识二进制指令(仅有 0 和 1 组成的指令),我们日常编写的 C 语言代码、C++ 代码、Java 代码等,计算机根本无法识别,只有将程序中的每条语句翻译成对应的二进制指令,计算机才能执行。
  3. 调用 gcc 相关指令,将我们编写的程序编译成一个二进制可执行文件。

3 编译过程演示

以hello.c程序为源代码进行分步编译,利用GCC 编译器逐步对源代码进行预处理、编译、汇编以及链接操作。

3.1 预处理操作

预处理,主要是处理那些源文件和头文件中以 # 开头的命令(比如 #include、#define、#ifdef 等),并删除程序中所有的注释 // 和 //

执行指令 gcc -E ,生成.i 文件,完成预处理操作。

gcc 指令添加 -E 选项,即可控制 GCC 编译器仅对源代码做预处理操作。
gcc 指令添加 -o 选项,将预处理结果写入到文件hello.i中。

[root@VM-8-8-centos data]# gcc -E -o hello.i hello.c
[root@VM-8-8-centos data]# ls
hello.c  hello.i

预处理结果较长,这里先不展开分析。

1、编译系统

3.2 汇编操作

执行指令: gcc -S ,GCC 编译器将指定文件加工至编译阶段,并生成对应的汇编代码 .s 文件,完成编译操作。

[root@VM-8-8-centos data]# gcc -S hello.i
[root@VM-8-8-centos data]# ls
hello.c  hello.i  hello.s

得到的汇编代码如下:

1、编译系统

注意:所有以”.”开头的行为都是指导编译器和链接器工作的伪指令,通常可以忽略这些行。
因此可以简化为以下版本,并添加注释说明(后续补上)

    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    $1, -4(%rbp)
    movl    $2, -8(%rbp)
    movl    -8(%rbp), %eax
    movl    -4(%rbp), %edx
    addl    %edx, %eax
    movl    %eax, -12(%rbp)
    movl    $.LC0, %edi
    call    puts
    movl    -12(%rbp), %eax
    leave

3.3 编译操作

执行指令: gcc -c , GCC 编译器将指定文件加工至汇编阶段,并生成相应的可重定位的 .o 目标文件,完成编译操作。

[root@VM-8-8-centos data]# gcc -c hello.s
[root@VM-8-8-centos data]# ls
hello.c  hello.i  hello.o  hello.s

编译后变成可执行的二进制代码,可以用其他编辑工具将其打开。

3.4 链接操作

执行指令 gcc hello.o 完成链接操作,生成一个可执行的.out文件。默认生成的文件名为的a.out,可以通过 – o 选项指定文件的名称

[root@VM-8-8-centos data]# gcc hello.o -o hello.out
[root@VM-8-8-centos data]# ls
hello.c  hello.i  hello.o  hello.out  hello.s
[root@VM-8-8-centos data]#

.out文件是可执行文件。使用命令: ./hello.out 。执行结果是在屏幕上输出 hello c

[root@VM-8-8-centos data]# ./hello.out
hello c

4 关于GCC指令

上述例子采用分步操作,也可以忽略中间过程,一般我们都是使用 gcc -c 选项,令编译器将指定文件加工至汇编阶段。

  1. 如果指定文件为源程序文件(例如 hello.c),则 gcc -c 指令会对 hello.c 文件执行预处理、编译以及汇编这 3 步操作;
  2. 如果指定文件为刚刚经过预处理后的文件(例如 hello.i),则 gcc -c 指令对 hello.i 文件执行编译和汇编这 2 步操作;
  3. 如果指定文件为刚刚经过编译后的文件(例如 hello.s),则 gcc -c 指令只对 hello.s 文件执行汇编这 1 步操作。

gcc指令解析:

1、编译系统

Original: https://www.cnblogs.com/knowledgeispower/p/16662852.html
Author: 拿了桔子跑-范德依彪
Title: 1、编译系统

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585092/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 从BWM生产学习工厂模式

    工厂模式应用非常之广,在 JDK底层源码以及各大主流框架中随处可见,一般以 Factory结尾命名的类,比如 Mybatis中的 SqlSessionFactory, Spring…

    Java 2023年6月6日
    069
  • 【力扣】525. 连续数组

    给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。 示例 1: 输入: nums = [0,1]输出: 2说明: [0, 1…

    Java 2023年6月8日
    054
  • Redis基本操作

    windows 下载 https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100 然后解压 打开服务 然后…

    Java 2023年6月7日
    058
  • 4、多态

    多态概念(一共三点满足就行) 1、 继承 2、程序运行时将子类对象赋值给父类 3、通过父类去调用子类的方法 一、父类类型做方法的参数 <span class=”kwd”&gt…

    Java 2023年6月6日
    085
  • 2013年蓝桥杯省赛C组笔记

    猜年龄(简单枚举) 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。一次,他参加某个重要会议,年轻的脸孔引人注目。于…

    Java 2023年6月7日
    065
  • Java-Dubbo学习及整合SpringBoot

    Dubbo是Java的RPC框架,具有三大核心功能:面向接口的远程方法调用,智能容错和负载均衡,以及服务的自动注册和发现 Dubbo架构图: 节点角色说明: 节点 说明 Provi…

    Java 2023年6月8日
    070
  • Java-ThreadPool线程池总结

    ThreadPool 线程池的优势 线程池做的工作主要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出的线程排队等候,…

    Java 2023年6月8日
    065
  • RocketMq 完整部署

    RocketMq 部署 环境 物理机部署 自定义日志目录 自定义参数和数据存放位置 服务启动 启动name server 启动broker 关停服务 尝试发送消息 常见报错 部署 …

    Java 2023年6月6日
    0101
  • NGINX中root和alias的区别

    nginx指定文件路径有两种方式root和alias。主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。 locati…

    Java 2023年5月30日
    067
  • 【Java】finally用法

    一.概述 二. finally会执行的情况 1.有catch(无异常) 3.有catch(try异常) 4.有catch(catch异常) 5.有catch(try/catch都异…

    Java 2023年5月29日
    096
  • Springboot使用Maven Profile和Spring Profile进行多环境配置

    https://www.jianshu.com/p/b7c75b0c364c Original: https://www.cnblogs.com/tszr/p/16506781.h…

    Java 2023年5月30日
    064
  • 洛谷P3366 【模板】最小生成树(Boruvka算法)

    题意 题目链接 Sol 自己yy着写了一下Boruvka算法。 算法思想很简单,就是每次贪心的用两个联通块之间最小的边去合并。 复杂度(O(n \log n)),然鹅没有Krusk…

    Java 2023年5月30日
    095
  • Java四类八种数据类型

    第一类:逻辑型boolean 第二类:文本型char 第三类:整数型(byte、short、int、long) char类型占2个字节short从-32768到32767int从-…

    Java 2023年5月29日
    083
  • Mysql基础篇-查询、函数、多表、事务

    基础篇 1.1 mysql用户和权限管理 查询用户 USER mysql; SELECT * FROM user; 创建用户 CREATE USER ‘&#x7528;&a…

    Java 2023年6月8日
    075
  • springBoot于tomcat7搭建websocket服务

    最近在项目中需要服务端进行推送服务,于是决定使用webSocket进行双向通讯。刚开始觉得应该没问题,参考网上的博客进行开发配置。我们的开发环境使用的是springBoot、tom…

    Java 2023年5月30日
    078
  • 智力大冲浪 C++

    小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者 m 元。先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布…

    Java 2023年6月5日
    099
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球