汇编
This is my study note of compilation.
GNU汇编语法
编译器不同会导致汇编的语法存在一些区别,这次主要是记录GNU语法的汇编
语句组成
plaintext
1 | lable表示标签,command则是要执行的操作,@表示注释 |
- 任何以”:”结尾的标识符都会被识别为一个标号
- ARM中指令、伪指令、伪操作、寄存器名等都可以全部使用大写或全部使用小写,但是不可以大小写混用
定义段
plaintext
1 | .section .testsection @定义一个testsection段 |
- 每个段以段名开始,以下一个段名或文件末尾结束
段名 | 含义 |
---|---|
.text | 表示代码段 |
.data | 初始化数据段 |
.bss | 未初始化的数据段 |
.rodata | 只读数据段 |
默认入口标号:_start
plaintext
1 | .global _start |
- 汇编程序默认入口为_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。 |
定义函数
plaintext
1 | 函数名: |
- undefined_Handler:为函数名
- ldr r0, =undefined_Handler为函数题
- bx r0 为返回语句,返回语句不是必须的
内部数据传输
- MOV指令 将寄存器拷贝到另一个寄存器plaintext
1
2MOV R0, R1 @将寄存器R1中的数据传递给R0,R0=R1
MOV R0, #0x12 @将立即数0x12传递给R0寄存器,R0=0x12 - MRS指令
MRS指令用于特殊寄存器数据复制给通用寄存器plaintext1
MRS R0, CPSR @将特殊寄存器CPSR里面的数据传递给R0,即R0=CPSR
- MSR指令
MSR指令用于普通寄存器传递给特殊寄存器plaintext1
MSR CPSR, R0 @将R0的数据复制到特殊寄存器CPSR中
存储器访问指令
- LDR指令
主要用于将存储数据加载到寄存器Rx中,也可以传入立即数。plaintext1
2LDR R0, =0X0209C004 @将寄存器地址0X0209C005加载到R0中
LDR R1, [R0] @读取地址0X0209C005中的数据到R1中 - STR指令LDR和STR都是按照字进行读取和写入的(32位),如果想要进行半字节的操作,指令为LDRH、STRHplaintext
1
STR R1, [R0] @将R1中的值写到R0中所保存的地址中
压栈和出栈指令
- PUSH压栈plaintext
1
PUSH {R0~R3, R12} @将R0~R3和R12压栈
- POP出栈POP和PUSH的另一种写法是STMFD和LDMFDplaintext
1
POP {R0~R3, R12} @恢复LRR0~R3和R12
跳转指令
- B指令plaintext
1
B指令会将PC寄存器的值设置为跳转目标地址,一旦执行则会跳转到目标地址,但是不会返回原处。
- BL指令plaintext
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 按位易或
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 风声向寂!
评论
ValineDisqus