1.syntax用法
GNU汇编器的.syntax
.syntax命令是ARM架构独有的命令,语法为 .syntax [unified | divided];作用是在汇编ARM指令时,指定按照什么样的语法规则进行汇编。如果在编写汇编语言时不使用该命令指定语法规则,那么默认采用.syntax divided,此时使用旧的汇编风格,ARM和THUMB指令有着各自的语法。正是在这种情况下,汇编器报了第1节中所说的错误,可能是指令采用了新的汇编风格,和旧的不兼容。
- 立即数不需要#前缀
- 可能会出现IT指令,如果出现,则根据后面的条件码进行验证。在ARM模式下,它不会生成机器码,而在THUMB模式下则会生成机器码
- 对于ARM指令,条件码总是出现在指令的最后;对于THUMB指令,条件码可以被使用,但仅限于IT指令的范围内
- V6T2架构(及更高版本)的所有新指令都可用(这些指令中,divided语法仅支持少部分)
- 支持.N和.W后缀
示例如下:
// Enable UAL syntax
.syntax unified
2 以 . 开头的名称
汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“伪”字。.section指示把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。GNU伪指令具体可参考Using as - Table of Contents (gnu.org)
例如.section .text.boot, "ax", %progbits
Section 类型如下
表示定义文本段boot,ax表示权限,ax是 allocation execute的缩写,表示该节区可分配并且可执行;%progbits是type字段的标记:PROGBITS: 程序内容,包含代码、数据、调试相关信息
.type symbol,%type:指定symbol的类型,如下
.global 表示该symbol对链接文件是可见的,如果在部分程序中定义了符号,那么它的值将对与它链接的其他部分程序可用。否则,symbol将从链接到同一程序的另一个文件中的同名符号获取其属性。
.weak,弱符号:其他同名符号优先级高于该符号;当其他同名不可用时才使用该符号里的定义。
.equ 类似宏定义,将常量或者其他什么分配给一个符号;
上述语法的使用方法示例:
3 ARM 汇编语法格式
- 注释
在arm汇编中,注释可以用// 或者#来注释整行,也可以用/* */来跨行注释
- 符号
符号symbol是核心概念,是一个程序的桥梁,程序员使用符号来命名各种内容,链接器使用符号进行链接,调试器使用符号进行定位调试。符号常用字母、数字、_、.、$进行表示。全局符号使用.global,本地符号使用.L
4 常用伪指令
伪指令,用于给汇编器发送命令,让汇编器按照既定命令进行汇编,也就是说,在汇编完成后,伪指令的使命就结束了。常见伪指令如下:
4.1 数据定义伪指令
.byte | 8位数当做数据嵌入汇编 | |
.hword/.short | 16位数当做数据嵌入汇编 | |
.long/.int | 32位数当做数据嵌入汇编 | |
.word | 32位数当做数据嵌入汇编 | |
.quad | 64位数当做数据嵌入汇编 | |
.float | 浮点数当做数据嵌入汇编 | |
.rept .endr | 重复执行伪操作 | .rept 10 .byte 3 .endr == .byte 3 .byte 3 .byte 3 |
.equ | 给符号赋值 | .equ data1,10 //给data1符号赋值10 |
4.2 函数相关伪指令
.global | 定义全局符号,可以是函数或者全局变量 | |
.include | 引用头文件 | |
.if .else .endif | 控制语句 | |
.ifdef symbol | 判断symbol是否定义 | |
.ifndef symbol | 判断symbol是否没有定义 | |
.ifc str1,str2 | 判断字符串是否相等 | |
.ifeq exp | 判断exp是否为0 | |
.ifge exp | 判断exp是否大于等于0 | |
.ifle exp | 判断exp是否小于等于0 | |
.ifne exp | 判断exp是否不等于0 |
4.3 段相关伪指令
.section,这个比较容易和ld文件搞混。
这里就将汇编,.section表示在该section里的汇编会被链接到某个段里,常用格式如下
.section name,”flags”
.section 伪指令定义的段会一个段的名称开始,以下一个段或者文件的结尾结束;
.pushsection和.popsection
二者配对使用,将代码链接到指定的段,其他代码还保留在原来的段中;
4.4 宏相关伪指令
.macro name args ...
宏名称、宏参数。
当宏里使用参数时,需加前缀”\”
例如
.macro add a1,a2
Add r0,\a1,\a2
.endm
5.ARMV8-R 指令编码格式
这里讨论A32指令编码格式
A32指令包含4-bit的condition code,状态如下:
根据不同的op0/1可以解码成不同的指令集,如下:
注意这是给机器识别的指令。那我们实际写汇编该怎么弄呢?我们下一篇挨个分析: