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)++++](#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可以解码成不同的指令集,如下:
注意这是给机器识别的指令。那我们实际写汇编该怎么弄呢?我们下一篇挨个分析: