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)

大家都在看

  • 编译原理 实验1《词法分析程序设计与实现》

    1、定义目标语言的可用符号表 2、定义程序输入输出 3、代码 – (1)头文件 analysis.h (2)测试 main.cpp 4、测试 – (1)输入…

    Java 2023年6月5日
    0136
  • 深入浅出的分析 Properties

    作者:炸鸡可乐原文出处:www.pzblog.cn 一、摘要 在集合系列的第一章,咱们了解到,Map 的实现类有 HashMap、LinkedHashMap、TreeMap、Ide…

    Java 2023年6月9日
    077
  • 基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(v6.6.6版)

    TableGo_20191026 v6.6.6 正式发布,此次版本更新如下:1、新增通过自定义模板生成Word文档的功能,可以使用FreeMarker模板生成自定义格式的数据库文档…

    Java 2023年6月9日
    096
  • JPA自定义实体的id

    背景:继上一篇文章,已经实现客户端数据库数据,存入服务器,但是,两张表的id不一样,应该是id设置自增了,所以虽然从客户端查出的实体带id,但是存入服务器时id被抹掉,按照服务端表…

    Java 2023年6月8日
    090
  • 网络编程详解

    1.1 概述 计算机网络:计算机网络是指将 地理位置不同的具有独立功能的 多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及 网络通信协议的管理和协调下,…

    Java 2023年6月6日
    083
  • nginx重新整理——————http请求的11个阶段中的preaccess[十四]

    前言 简单整理一下preaccess。 正文 主要是介绍一下上文提及到的limit_req以及limit_conn。 里面是http_limit_conn_module 默认编译进…

    Java 2023年5月30日
    061
  • 二进制转换与位运算

    在应用程序常用的进制包含 二进制 八进制 &am…

    Java 2023年6月16日
    082
  • 记一次docker compose的低级错误

    记一次docker compose的低级错误 问题 ​ 今天在学习dockercompose的时候,启动docker compose up,结果却出现异常 Error respon…

    Java 2023年6月8日
    083
  • 3、计算机系统漫游

    1 计算机的信息 2 编译系统 3 硬件系统 4 高速缓存 5 存储器层次结构 6 操作系统 6.1 操作系统的抽象表示 6.2 进程 6.3 线程 6.4 虚拟内存 7 系统之间…

    Java 2023年6月7日
    0107
  • spring事务传播行为详解

    简单的理解就是多个事务方法相互调用时,事务如何在这些方法间传播。 举个栗子,方法A是一个事务的方法,方法A执行过程中调用了方法B,那么方法B有无事务以及方法B对事务的要求不同都会对…

    Java 2023年5月30日
    079
  • nginx 代理https后,应用redirect https变成http

    nginx配置https,tomcat正常http接受nginx转发。nginx 代理https后,(java代码redirect地址)应用redirect https变成http…

    Java 2023年5月30日
    076
  • 快速掌握 Base 64 | Java JS 密码系列

    Java 密码系列 – Java 和 JS Base 64 Base 64 不属于密码技术,仅是编码方式。但由于在 Java、JavaScript、区块链等出现的频率较…

    Java 2023年6月16日
    081
  • Java,求一个字符串中指定字符出现的次数

    如题,这里介绍两种方式 1、把字符串转化成字符数组,然后通过for循环比对出结果 这种方式虽然明面上看着有for循环,实际执行速度却很快,也很好理解。 2、用string的spli…

    Java 2023年6月5日
    098
  • Spring Boot Cache使用与整合

    Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Caffeine、Ehcache等),但本身不直接提供缓存功能的实现。它支持注解方式使用缓存,非常方便。 Sp…

    Java 2023年5月30日
    090
  • java中的日志配置

    slf4j是java中常用的日志框架,有许多具体实现,比如slf4j-simple等。 一、maven配置 org.slf4j   slf4j-api   1.7.26   com…

    Java 2023年5月29日
    081
  • MySQL面试题

    MySql项目中使用的存储引擎 5.0之前默认存储引擎为MyISAM引擎 索引只有一种,被索引的字段值作为索引数据,叶子节点还包含该记录数据页地址 不支持事务 没有undo log…

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