This is my study note of compilation.
GNU汇编语法
编译器不同会导致汇编的语法存在一些区别,这次主要是记录GNU语法的汇编
语句组成
1 2 3 4 5 6
| lable表示标签,command则是要执行的操作,@表示注释 lable: command @ 注释内容 例: add: MOVS R0, #0x12 @ 设置R0=0x12
|
- 任何以”:”结尾的标识符都会被识别为一个标号
- ARM中指令、伪指令、伪操作、寄存器名等都可以全部使用大写或全部使用小写,但是不可以大小写混用
定义段
1
| .section .testsection @定义一个testsection段
|
段名 |
含义 |
.text |
表示代码段 |
.data |
初始化数据段 |
.bss |
未初始化的数据段 |
.rodata |
只读数据段 |
默认入口标号:_start
1 2 3
| .global _start _start: ldr r0, =0x12 @r0=0x12
|
- 汇编程序默认入口为_start
- 可以在链接脚本中使用ENTRY来指明其他的入口点
伪操作
伪操作 |
含义 |
.byte |
定义单字节数据,比如.byte 0x12。 |
.short |
定义双字节数据,比如.short 0x1234。 |
.long |
定义一个 4 字节数据,比如.long 0x12345678。 |
.equ |
赋值语句,格式为:.equ 变量名,表达式,比如.equ num, 0x12,表示 num=0x12。 |
.align |
数据字节对齐,比如:.align 4 表示 4 字节对齐。 |
.end |
表示源文件结束。 |
.global |
定义一个全局符号,格式为:.global symbol,比如:.global _start。 |
定义函数
1 2 3 4 5 6 7 8
| 函数名: 函数体 返回语句
例子: undefined_Handler: ldr r0, =undefined_Handler bx r0
|
- undefined_Handler:为函数名
- ldr r0, =undefined_Handler为函数题
- bx r0 为返回语句,返回语句不是必须的
内部数据传输
- MOV指令 将寄存器拷贝到另一个寄存器
1 2
| MOV R0, R1 @将寄存器R1中的数据传递给R0,R0=R1 MOV R0, #0x12 @将立即数0x12传递给R0寄存器,R0=0x12
|
- MRS指令
MRS指令用于特殊寄存器数据复制给通用寄存器1
| MRS R0, CPSR @将特殊寄存器CPSR里面的数据传递给R0,即R0=CPSR
|
- MSR指令
MSR指令用于普通寄存器传递给特殊寄存器1
| MSR CPSR, R0 @将R0的数据复制到特殊寄存器CPSR中
|
存储器访问指令
- LDR指令
主要用于将存储数据加载到寄存器Rx中,也可以传入立即数。1 2
| LDR R0, =0X0209C004 @将寄存器地址0X0209C005加载到R0中 LDR R1, [R0] @读取地址0X0209C005中的数据到R1中
|
- STR指令
1
| STR R1, [R0] @将R1中的值写到R0中所保存的地址中
|
LDR和STR都是按照字进行读取和写入的(32位),如果想要进行半字节的操作,指令为LDRH、STRH
压栈和出栈指令
- PUSH压栈
1
| PUSH {R0~R3, R12} @将R0~R3和R12压栈
|
- POP出栈
1
| POP {R0~R3, R12} @恢复LRR0~R3和R12
|
POP和PUSH的另一种写法是STMFD和LDMFD
跳转指令
- B指令
1
| B指令会将PC寄存器的值设置为跳转目标地址,一旦执行则会跳转到目标地址,但是不会返回原处。
|
- BL指令
1
| 在跳转之前会在寄存器 LR(R14)中保存当前 PC 寄存器值,所以可以通过将 LR 寄存器中的值重新加载到 PC 中来继续从跳转之前的代码处运行.
|
运算符指令
指令 |
计算公式 |
备注 |
ADD Rd, Rn, Rm |
Rd = Rn + Rm |
加法运算,指令为 ADD |
ADD Rd, Rn, #immed |
Rd = Rn + #immed |
加法运算,指令为 ADD |
ADC Rd, Rn, Rm |
Rd = Rn + Rm + 进位 |
带进位的加法运算,指令为 ADC |
ADC Rd, Rn, #immed |
Rd = Rn + #immed +进位 |
带进位的加法运算,指令为 ADC |
SUB Rd, Rn, Rm |
Rd = Rn – Rm |
减法 |
SUB Rd, #immed |
Rd = Rd - #immed |
减法 |
SUB Rd, Rn, #immed |
Rd = Rn - #immed |
减法 |
SBC Rd, Rn, #immed |
Rd = Rn - #immed – 借位 |
带借位的减法 |
SBC Rd, Rn ,Rm |
Rd = Rn – Rm – 借位 |
带借位的减法 |
MUL Rd, Rn, Rm |
Rd = Rn * Rm |
乘法(32 位) |
UDIV Rd, Rn, Rm |
Rd = Rn / Rm |
无符号除法 |
SDIV Rd, Rn, Rm |
Rd = Rn / Rm |
有符号除法 |
逻辑运算指令
- AND 与
- ORR 或
- BIC 位清除
- ORN 按位或非
- EOR 按位易或