预备知识
1. 寻找地址表现形式
- 立即数地址(Immediate Addressing)
LDR R0, =0x2000 // 将立即数 0x2000 作为地址加载到寄存器 R0 中
- 寄存器间接寻址(Register Indirect Addressing)
使用寄存器的值作为内存地址进行数据存取。
LDR R0, [R1] // 从寄存器 R1 指向的内存地址加载数据到寄存器 R0
STR R2, [R3] // 将寄存器 R2 中的数据存储到寄存器 R3 指向的内存地址
- 寄存器间接加偏移量(Register Indirect with Offset)
功能:在寄存器指定的基地址上加上一个立即数偏移量来计算实际的内存地址。
LDR R0, [R1, #4] // 从寄存器 R1 加上偏移量 4 指向的地址加载数据到寄存器 R0
STR R2, [R3, #8] // 将寄存器 R2 中的数据存储到寄存器 R3 加上偏移量 8 指向的内存地址
- 寄存器间接加寄存器偏移(Register Indirect with Register Offset)
功能:使用一个寄存器的值作为基地址,并将另一个寄存器的值作为偏移量来计算实际的内存地址。偏移量是数而不是地址。
LDR R0, [R1, R2] // 从寄存器 R1 加上寄存器 R2 指向的地址加载数据到寄存器 R0
STR R3, [R4, R5] // 将寄存器 R3 中的数据存储到寄存器 R4 加上寄存器 R5 指向的内存地址
- 寄存器间接加偏移量与基地址寄存器的递增(Pre-indexed Addressing)
功能:在访问内存之前,先将一个立即数偏移量加到基地址寄存器的值上。这种方式会修改基地址寄存器的值。
LDR R0, [R1, #4]! // 从寄存器 R1 加上偏移量 4 指向的地址加载数据到寄存器 R0,并递增寄存器 R1
STR R2, [R3, #8]! // 将寄存器 R2 中的数据存储到寄存器 R3 加上偏移量 8 指向的内存地址,并递增寄存器 R3
2. #和=的区别
- #4是一个立即数
- =address,用途:表示一个常量地址或数据值,用于将较大的数值加载到寄存器中。是伪指令
3.
一、数据传输指令
1.MOV指令 Move Register
功能:将一个值从一个寄存器或立即数传输到另一个寄存器。
MOV R0, #5 // 将立即数5加载到寄存器R0
MOV R1, R0 // 将寄存器R0的值传输到寄存器R1
二、访存指令
唯二
1.LDR指令 Load Register
功能:从内存中加载数据到寄存器。左<-右
LDR R0, [R1] // 从寄存器R1指向的内存地址加载数据到寄存器R0
LDR R2, =0x1000 // 将地址0x1000加载到寄存器R2
LDR R3, [R2] // 从寄存器R2指向的内存地址加载数据到寄存器R3
2. STR指令 Store Register
功能:将寄存器中的数据存储到内存中。左->右
STR R0, [R1] // 将寄存器 R0 中的数据存储到寄存器 R1 指向的内存地址
STR R2, [R3] // 将寄存器 R2 中的数据存储到寄存器 R3 指向的内存地址
三、多寄存器访存指令
1. LDM指令 Load Multiple (LDM)
功能:从内存中加载多个寄存器的值。
- 递增模式(IA):在每次数据加载后,基地址寄存器的值递增。
LDMIA R0!, {R1, R2, R3}//从内存地址 R0 指向的地址开始,依次加载内存中的值到寄存器 R1、R2 和 R3。
R0 在每次加载后递增,直到所有寄存器加载完毕。
- 递减模式(DA)
LDMDA R0!, {R1, R2, R3}//从内存地址 R0 指向的地址开始(地址递减),依次加载内存中的值到寄存器 R1、R2 和 R3。R0 在每次加载前递减,直到所有寄存器加载完毕。
- 不更新基地址寄存器
LDMIA R0, {R1, R2, R3}//从内存地址 R0 指向的地址开始,依次加载内存中的值到寄存器 R1、R2 和 R3。基地址寄存器 R0 的值不更新(即没有 !)。
2. STM指令 Store Multiple (STM)
功能:将多个寄存器的值存储到内存中。类似于LDM指令
STMIA R0!, {R1, R2, R3} // 将寄存器 R1、R2、R3 的值存储到寄存器 R0 指向的内存地址,并在存储后递增 R0
四、栈操作指令
1.PUSH和POP指令
后进先出
功能:PUSH:将寄存器的值压入栈中。
POP:从栈中弹出数据到寄存器。
PUSH {R0, R1} // 将寄存器 R0 和 R1 的值压入栈中。值得注意是R1先压入栈中
POP {R2, R3} // 从栈中弹出数据到寄存器 R2 和 R3
POP {R2, R3}//从栈中弹出数据到寄存器 R2 和 R3 中。R3存放最先出栈的元素
五、立即数处理指令
1.MOVT Move Top (移动顶部)和MOVW Move Wide (移动宽度)指令
功能:
MOVW:将一个16位立即数加载到寄存器的低16位。
MOVT:将一个16位立即数加载到寄存器的高16位。
MOVW R0, #0x1234 // 将立即数 0x1234 加载到寄存器 R0 的低 16 位
MOVT R0, #0x5678 // 将立即数 0x5678 加载到寄存器 R0 的高 16 位
六、系统控制寄存器操作指令
1. MRS和MSR指令
- MRS 和 MSR 是用于处理系统控制寄存器(如程序状态寄存器(CPSR)、控制寄存器等)的指令。它们用于读写这些寄存器的值,从而影响系统的状态和控制。
- MRS 指令,全称:Move Register to Status Register
- 功能:将系统控制寄存器的值读取到通用寄存器中。主要用于从程序状态寄存器(CPSR)或其他控制寄存器读取数据。
- MSR 指令,全称:Move Status Register to Register
- 功能:将通用寄存器的值写入到系统控制寄存器中。主要用于设置程序状态寄存器(CPSR)或其他控制寄存器的值。
MRS R0, CPSR // 将当前程序状态寄存器 (CPSR) 的值加载到寄存器 R0 中
MSR CPSR, R0 // 将寄存器 R0 的值写入当前程序状态寄存器 (CPSR)
七、汇总
ARM汇编指令汇总
类别 | 指令 | 功能描述 | 示例代码 |
---|---|---|---|
数据传输指令 | MOV | 将数据从一个寄存器或立即数传输到另一个寄存器 | MOV R0, #5 MOV R1, R0 |
访存指令 | LDR | 从内存中加载数据到寄存器 | LDR R0, [R1] LDR R2, =0x1000 LDR R3, [R2] |
STR | 将寄存器中的数据存储到内存中 | STR R0, [R1] STR R2, [R3] | |
多寄存器访存指令 | LDM | 从内存中加载多个寄存器的值 | LDMIA R0!, {R1, R2, R3} LDMDA R0!, {R1, R2, R3} LDMIA R0, {R1, R2, R3} |
STM | 将多个寄存器的值存储到内存中 | STMIA R0!, {R1, R2, R3} | |
栈操作指令 | PUSH | 将寄存器的值压入栈中 | PUSH {R0, R1} |
POP | 从栈中弹出数据到寄存器 | POP {R2, R3} | |
立即数处理指令 | MOVW | 将一个 16 位立即数加载到寄存器的低 16 位 | MOVW R0, #0x1234 |
MOVT | 将一个 16 位立即数加载到寄存器的高 16 位 | MOVT R0, #0x5678 | |
系统控制寄存器操作指令 | MRS | 将系统状态寄存器(如 CPSR)的值读取到通用寄存器中 | MRS R0, CPSR |
MSR | 将通用寄存器中的值写入到系统状态寄存器(如 CPSR)中 | MSR CPSR, R0 |