MOV 赋值操作
寄存器 <= 寄存器/存储器/立即数
MOV{条件}{S} 目的寄存器,源操作数
没有S时指令不更新 CPSR 中条件标志位的值
立即数:由0-255之间的数据循环右移偶数位生成。(移动规则不用掌握)
#0xfff不是立即数,而0x80000001是立即数
对于ARM指令 => 机器码 存在一定的规则:(也不用记,只需要有这个概念)
移位操作
- LSL(或ASL)逻辑(算术)左移
MOV R0,R1, LSL #2 将R1中的内容左移两位后传送到R0,低位用0填充
- LSR逻辑右移,高位补0
MOV R0, R1, LSR #2
- ASR算术右移,高位用原第31位的值(符号位)填充
MOV R0,R1,ASR #2
- ROR循环右移,高位用低位移出的位来填充
MOV R0, R1, ROR #2
- RRX带扩展的循环右移,高位用进位标志位C来填充
MOV R0, R1, RRX #2
# CMP指令
CMP{ 条件 } 操作数 1 ,操作数 2
CMP 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新 CPSR 中条件标志位的值。
CMP R1 R0 ;将寄存器 R1 的值与寄存器 R0 的值相减,并根据结果设置 CPSR 的标志位
TST条件指令
TST{ 条件 } 操作数 1 ,操作数 2
TST 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的与运算,并根据运算结果更新 CPSR 中条件标志位的值。
操作数 1 是要测试的数据,而操作数 2 是一个位掩码,根据测试结果设置相应位。
TST R1 #%1 ;用于测试在寄存器 R1 中是否设置了最低位(%表示二进制数)。
数据处理指令 add sub等
-
ADD
ADD{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2:操作数1+操作数2结果存放于目的寄存器
-
ADC
ADC{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2:除了操作数1+操作数2,还要加上CPSR中的C条件标志位
-
SUB
SUB{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2:SUB 指令用于把操作数 1 减去操作数 2 ,并将结果存放到目的寄存器中。
-
SBC
SBC{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2:除了正常的减法,还要再减去CPSR中C条件标志位的反码
-
AND
AND{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2:两个操作数按位与
-
ORR
ORR{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2:逻辑或
-
BIC
BIC{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2:清除操作数1的某些位(看操作数的32位哪些位为1)
跳转指令
在ARM程序中两种方法实现跳转:
1、专门的跳转指令
-
B 跳转指令:B{ 条件 } 目标地址
-
BL 带返回的跳转指令:BL{ 条件 } 目标地址,在跳转之前会自动将PC值保存于R14,后续可以通过将R14的值赋给PC来实现返回
-
BLX 带返回和状态切换的跳转指令 thumb 指令
-
BX 带状态切换的跳转指令 thumb 指令
目标地址用label表示
B指令最大寻址空间只有±32MB,对于全部32Bit地址空间,需要直接修改PC来实现
2、直接向PC写入跳转地址值,注意在跳转前把当前PC存下来 MOV LR,PC
程序状态寄存器访问指令MRS、MSR
CPSR访问指令:用于CPSR和通用寄存器之间传送数据
MRS {条件} 通用寄存器,程序状态寄存器( CPSR 或 SPSR):将CPSR的内容传送到通用寄存器
MRS R0,CPSR ;传送 CPSR 的内容到 R0
MSR {条件} 程序状态寄存器( CPSR 或 SPSR )_ <域>,操作数:用于将操作数的内容传送到程序状态寄存器的特定域中。操作数可以为通用寄存器/立即数,<域> 用于设置状态寄存器中需要操作的位,用字符表示不同的位。
MSR CPSR_c ,R0 ;传送 R0 的内容到 CPSR ,但仅仅修改 CPSR 中的控制位域([7:0]位)
MSR SPSR , R0 ; 传送R0的内容到SPSR
LDR STR指令
LDR = load register
LDR {条件} 目的寄存器, <存储器地址>:LDR 指令用于从存储器中将一个 32 位的字数据传送到目的寄存器中。
- LDR R0 ,[R1] ;将存储器地址为 R1 的字数据读入寄存器 R0
- LDR R0 ,[R1 R2] ;将存储器地址为 R1+R2 的字数据读入寄存器 R0
STR = store register
STR{条件} 源寄存器, <存储器地址>:STR指令用于从源寄存器中将一个32位的字数据传送到寄存器中。
-
STR r0,[r1,#12]:将r0寄存器的值发送到(r1寄存器中存放数据 偏移#12后)的内存
-
STR r0,[r1],#12:将r0寄存器的值发送到(r1寄存器中的值对应的内存),然后再将r1寄存器的值加上#12
也就是一个是先赋值后偏移,另一个是先偏移后赋值。
Push Pop指令
push本质上是写内存指令,pop本质上是读指令,读写的位置是sp所指向的位置
push {r3,lr} ; 进栈顺序是高标号的寄存器写到高地址,低标号的寄存器写到低地址,与大括号内寄存器的顺序无关。指令含义是:将lr寄存器的值写入sp,然后sp-4,将r3寄存器的值写入sp,sp-4
pop {r3,pc} ; 将sp指向的值读给r3,sp+4,将sp指向的值读给pc,sp+4
这样的栈是向下增长,即高地址向低地址增长。
ARM寻址方式
- 立即寻址:立即数寻址
- 寄存器寻址:利用寄存器中的数值作为操作数
- 寄存器间接寻址:以寄存器中的值作为操作数的地址,操作数存放在存储器中,如LDR R0,[R1]
- 基址变址寻址:将寄存器的内容和给定偏移量相加,作为操作数的有效地址,如LDR R0,[R1, #4]
- 相对寻址:与基址变址寻址方式相类似,相对寻址以程序计数器 PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。(如 BL)
- 多寄存器寻址:一条指令可以完成多个寄存器值的传送,如LDMIA
- 堆栈寻址、批量加载/存储指令:LDM批量数据加载、STM批量数据存储