汇编伪指令格式
标号symbol(label)
注释符号:@
整行注释:#
语句分离:;
立即数前缀:# 或 $
分段:.section伪操作,用于自定义新的段
- .text:代码段
- .data:初始化的数据段
- .bss:未初始化的数据段
- .rodata:字符串和#define定义的常量
- heap、stack、常量段
汇编程序的缺省入口是**_start标号**
数据定义
杂项伪操作符:
.global 定义全局符号
.align 指定数据对齐方式
.include 引入头文件,也可以#include
.incbin 伪操作:将一个二进制文件编译到当前文件,用于静态库
.rept:重复接下来的指令,以.rept开始,.end结束
.if伪操作:根据表达式的值来决定是否要编译下面的代码
.macro伪操作:将一段代码定义为一个整体,类似c里面的宏函数
举例:
伪指令
不是标注的ARM指令,在编译时会转化为对应的其他ARM指令(可能对应多条ARM指令)
LDR伪指令:
ldr r1,=val @ r1 = val 把val标号地址赋给r1
ldr r2, val @ r2 = *val 把val地址的内容给r2
可以实现长跳转:ldr pc, = 32位地址
可以解决非立即数的问题:ldr r0,=0x999 @0x999不是立即数
在编译后查看机器码:
通过基址变址寻址的方式实现,即将0x999放在了40008008地址的位置,牺牲一个4字节空间实现
内联汇编
内联汇编即在 C 中直接使用汇编语句进行编程,使程序可以在 C 程序中实现 C 语言不能完成的一些 工作
举例:
汇合汇编
使单独编译的C语言程序和汇编程序之间能够相互调用
ARM结构过程调用规范(APPCS):寄存器使用规则及相应名称、数据栈使用规则、参数传递的规则:
例子如下:
参数传递是按照r0-r3寄存器进行传递,当超过4个参数,多余参数就要进栈,
返回值可以通过r0返回,当结果为64位时可以通过组合r0-r1方式,位数更多时需要调用内存,函数的返回地址存放在lr寄存器中。