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
汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(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 类似宏定义,将常量或者其他什么分配给一个符号;
上述语法的使用方法示例:
在arm汇编中,注释可以用// 或者#来注释整行,也可以用/* */来跨行注释
符号symbol是核心概念,是一个程序的桥梁,程序员使用符号来命名各种内容,链接器使用符号进行链接,调试器使用符号进行定位调试。符号常用字母、数字、_、.、$进行表示。全局符号使用.global,本地符号使用.L
伪指令,用于给汇编器发送命令,让汇编器按照既定命令进行汇编,也就是说,在汇编完成后,伪指令的使命就结束了。常见伪指令如下:
.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 |
.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 |
.section,这个比较容易和ld文件搞混。
这里就将汇编,.section表示在该section里的汇编会被链接到某个段里,常用格式如下
.section name,”flags”
.section 伪指令定义的段会一个段的名称开始,以下一个段或者文件的结尾结束;
.pushsection和.popsection
二者配对使用,将代码链接到指定的段,其他代码还保留在原来的段中;
.macro name args ...
宏名称、宏参数。
当宏里使用参数时,需加前缀”\”
例如
.macro add a1,a2
Add r0,\a1,\a2
.endm
这里讨论A32指令编码格式
A32指令包含4-bit的condition code,状态如下:
根据不同的op0/1可以解码成不同的指令集,如下:
注意这是给机器识别的指令。那我们实际写汇编该怎么弄呢?我们下一篇挨个分析: