编译工具集详解(二)| 学习笔记

简介: 快速学习编译工具集详解。

开发者学堂课程【剑池系列开发工具 :编译工具集详解(二)】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/734/detail/13097


编译工具集详解(一)

 

三、编译

面是编译套件的一个核心,是编译的部分。如图:

image.png

是一个非常简单的一个 c 语言,编译成汇编,左边到右边,可以看到它是从高级语言变到了汇编代码了。这可以使用,因为很多情况下编辑可能会用到自己手写代码的一个需求,从头开始写代码会比较繁琐。用这种方式,先写一个 c 语言,用编辑编成一个汇编代码,在此基础上慢慢的改进,做一些新的优化也可以。其实编译最核心的是到底用了哪套指令集,这样编辑才能根据指定器编译出可以正常执行的代码。以九系列的指令集为例,九系列它主要包含目前的1906,1902,c906,c910,处理器这么多架构,也有在上面做了一些扩展的指令集,一些性能增强的指令集,像910,会增加一些算术运算,会操作储存指令的一些加速的指令。这些指令都需要通过相对应的所正在使用的一些芯片所使用的指令集,去加相应的选项,才能编出想要的一个指令集,列出对应的一些处理器的对应的选项,基本上是通过-m 指定指定值的。

像1906是rv32,其实每个字母它都有它的一个特定含义,e 表示只要16位的寄存器。m 是乘除法的一个指令。第一个指令集的一个 flag,代表压缩指令集,是refer 里的16位指令集。sti 是上面列的是 thead 的扩展的一些性能增强的一些指令集。以此类推其处理器也是同样的一个道理。

接下来是优化选项,高级语言高级带其实可以有无数种的汇编代码训练去翻译,只要保证可以达到c语言班的逻辑含义,编译追求,主要有两方面的追求,一方面,它使用尽量少的代码去生成一段逻辑,使代码的占用空间更小,另一方面是被执行到的指令,尽可能地少地体现编译出来的程序的性能,优化到一个极致,两者是需要取舍的,有成百上千的去控制各种优化,下列是客户可能关心的一些选项,有一些偏向性的需求,第一方面是代码量,是 Code size,是针对一些MB领域的,先用领域的客户可能更追求的一些,一个方向是需要编出来的代码量是比较少的,一般编译选项是推荐 OS,用 ffunction-sections-fdata-sections,最后链接到 -section 去优化 Code size,Os 其实是编译相关的,会让编出来的代码占用的空间更小,后面两个选项,是编译加上了链接结合起来的一个优化,后面如果涉及到链接知识的时候可以一起使用,第二个推荐选项是-o2,性能优化推荐o2,很多客户都会问为什么不用-o3,那讲一下-o3,它会做一些非常极端的优化,可能有些时候出来的效果可能会比 o2差,所以推荐大家去使用 o2和 o3,如果有特定部分的代码,对性能的要求非常高,可以用 o3去单独的优化这片代码,但其它产品还是建议去做 o2 优化。

image.png

abi 的概念,是编译器里面也非常关心的一个概念。是 application binary interface 的一个缩写。中文翻译的叫应用程序二进制接口。用一个比较通俗的一个概念去解释它,它相当于一个协议,是当二进制文件,包括 object,archive,是所有的这些机器代码的二进制文件,它都遵循协议时,不管是编译器生成后再用协议汇编写,当大家都遵循协议时,编出来的东西可以正常的链接跟执行。这相当于一个协议一个约定,但当有一个文件没有遵循协议的时候,链接或者执行的时候会出错。

所以这是一个比较重要的一个概念,abi 包含很多内容较为关注的两点内容,一个是函数调用规则,还有一个是数据宽度,调用规则是计算器在函数调用的时候的一些使用规则,左边图列举了的一个基本的函数调用规则的一个概念。

普通处理器,refer 开头的它有32个寄存器,像 e 系列只有16个,但是像 c 系列都是有32个,这边是有很多,比方说有些寄存器它是用来做函数返回用的,函数返回的地址会在存在寄存器上。函数使用到寄存器是需要保存的,那也有些是不需要保存,像 temp 这样的寄存器。

image.png

右边这张图是列出了数据位宽。每个题结构,很多情况下都相似的,但又有一些独特的东西,以 rv32,rv64 为例,一个是四字节,另外一个是八字节,这是 abi 的主要部分。所有的东西要遵循一套规则,最后编出来的东西才是可以正常使用的。后面具体讲一下,其实900系列里面其实也是有细分的,也是有不同的,如果去开发的时候,两个文件用了不同的选项,拼在一起去执行的时候可能产生问题,这是需要注意的。

举个例子, e902,它的 abi 是对应的是 ilp 32e,在右边看到 ilp32,其实是表示目标平台是32位架构的,之前 PPT看到的数据位宽跟 rv64 会不一样,E 代表1902用了16个通用寄存器。是上面那张表格看到的前16个,e906 这边有几种,一种是 ilp 32,是不带 f 或者 d,这里面的表示13位架构也有32的处理器,但是浮点类型的参数,是通过普通寄存器存储的。但是如果1902它配了硬件和浮点单元,推荐 abi 里面加 f 或者 d 使用,硬件浮点寄存器去传参数。c906 在规则上和1902,1906是类似的,是 ilp64 的,是64位架构的。

image.png

最后一个编译部分是调试信息。有些客户可能是会反映这些问题,调试是看能否对应到相应的 c 语言的代码行号,有一个选项是需要去添加的,是 -g3,添加到选项之后,调试时会有调试信息。

image.png

 

四、汇编

汇编是从汇编代码翻译到二进制,是机器代码,例子如下,

image.png

左边汇编代码,右边是二进制代码,用反汇编电器将它反汇编出来,但是红框其实是真实的储存在 main.o 文件里面的二进制代码。是只有芯片可以读懂的一串数字,可以用反汇编将它返回编程。

汇编器其实需要讲的是很多客户,需要用到手写汇编的一个需求。熟悉汇编有两种方式,一种是内嵌汇编,一种是纯汇编格式,如果只是一个非常简单的一些内嵌,只是希望在c语言里面的一个代码,推荐用内嵌的方式去写。语法有一个关键字 asm volatile (assembly code),需要写的汇编代码,当然有一些非常细节的一些格式,如果真的要写东西时,推荐去读手册,写内嵌汇编的代码。后面一个是全汇编格式的汇编格式,之前等讲编译的时候也有讲到,可以有一个 c 文件编出汇编,在此基础上去改也行。当然可以直接去手写一个汇编文件。要对执行器比较熟悉,如果有一些问题,也可以翻指定集手册,第二个概念,是伪指令,是除了标准的技能,应急手册提供的指令外,汇编器其实还提供了另外一个在这些指定集之上的一个汇编指令格式,叫做伪指令,是写起来更方便,更易于理解。可能会将几条指令包装一下,变成一条伪指令。不需要关心对应哪条汇编指令,详细内容也可以去手册上面查,不针对每条指令展开讲,只有用到的时候,去看这些东西才是有意义的。如果要写的可以仔细查一下内嵌汇编的格式。因为有些代码是编写的, c 语言可能要调用汇编写的代码,调用关系如下:

image.png

第一个例子是 c 语言里用汇编写函数,需要去申领函数,去调最后链接时,链接到汇编写的, object 的文件可以正常链接去调用 c 函数,用到 jal 指令,它是函数调用的一个指令,遵照汇编规则,哪些寄存器负责保存,哪些寄存器负责返回值,写一个汇编代码,可以正常运行。

相关文章
|
8月前
|
数据安全/隐私保护 iOS开发 开发者
iOS 逆向编程(十八)Reveal 详细安装(以及安装问题解决)(上)
iOS 逆向编程(十八)Reveal 详细安装(以及安装问题解决)
368 0
|
8月前
|
监控 iOS开发
iOS 逆向编程(十八)Reveal 详细安装(以及安装问题解决)(下)
iOS 逆向编程(十八)Reveal 详细安装(以及安装问题解决)(下)
179 0
|
11天前
|
存储 程序员 索引
笨办法学 Python3 第五版(预览)(二)(4)
笨办法学 Python3 第五版(预览)(二)(4)
33 1
|
1月前
|
JSON 开发工具 开发者
CMake进阶教程:深入FetchContent与ExternalProject模块
CMake进阶教程:深入FetchContent与ExternalProject模块
79 0
|
3月前
|
Linux 编译器 C语言
【linux系统编程】编辑器gcc/g++
【linux系统编程】编辑器gcc/g++
|
编译器 开发工具 C语言
编译工具集详解(一)| 学习笔记
快速学习编译工具集详解。
61 0
编译工具集详解(一)| 学习笔记
|
Java 编译器 Linux
编译工具集详解(三)| 学习笔记
快速学习编译工具集详解。
230 0
编译工具集详解(三)| 学习笔记
|
Java 关系型数据库 MySQL
入门案例(开发环境配置)|学习笔记
快速学习入门案例(开发环境配置)
78 0
入门案例(开发环境配置)|学习笔记
|
开发者 Python
函数的⽂档说明 | 手把手教你入门Python之四十一
本节重点介绍函数的⽂档说明,函数应⽤:打印图形和数学计算
1720 0
函数的⽂档说明 | 手把手教你入门Python之四十一