ARM主要汇编指令总结

本文大部分学习内容来自朱老师的课堂。
ARM汇编特点:8种寻址方式
寄存器寻址 mov r1,r2
立即寻址 mov r0,#FF00
寄存器移位寻址 mov r0,r1,lsl#3
寄存器间接寻址 ldr r1,[r2]
基址变址寻址 ldr r1,[r2,#4]
多寄存器寻址 ldmia r1!,{r2-r7,r12},
堆栈寻址 stmfd sp!,{r2-r7,lr}

Stmdb和ldmia指令区别
stmdb和ldmia指令一般配对使用,stmdb用于将寄存器压栈,ldmia用于将寄存器弹出栈,作用是保存使用到的寄存器。
stmdb和ldmia指令一般配对使用,stmdb用于将寄存器存到某个地址上(一般是栈地址),ldmia用于将地址上的值加载到寄存器上,作用是保存使用到的寄存器。
https://blog.csdn.net/minsophia/article/details/53080183
这里比较容易混,混就混在了逗号上,ldr和ldmia用法其实不是一样的,ldmia和str的用法差不多,是把逗号前面的放到逗号后面的里头

ARM汇编特点3:指令后缀
同一指令经常附带不同后缀,变成不同的指令。经常使用的后缀有:
B(byte)功能不变,操作长度变为8位
H(half word)功能不变,长度变为16位
S(signed)功能不变,操作数变为有符号
如 ldr ldrb ldrh ldrsb ldrsh
S(S标志)功能不变,影响CPSR标志位
如 mov和movs movs r0, #0
问题:什么是cpsr?
CPSR是程序状态寄存器
ARM主要汇编指令总结
ARM主要汇编指令总结
看这张图就知道cpsr是什么了。
ARM主要汇编指令总结
后缀什么时候执行?
是在本句语句执行之前判断,前面判断若没有被允许,后面的指令就不能执行。
怎么判断呢?
就看CPSR的条件位。看N、Z、C、V的值。
ARM主要汇编指令总结
mov和mvn的区别是什么?
mvn是先位取反后再传递的。

数据传输指令 mov mvn
算术指令 add sub rsb adc sbc rsc
逻辑指令 and orr eor bic
比较指令 cmp cmn tst teq
乘法指令 mvl mla umull umlal smull smlal
前导零计数 clz
这里普及下指令作用:
逻辑指令bic用的比较多,
用法 bic r0,r0,#0x1f
解释:把r的第0位到第4位先清0,然后在赋值给r0

比较指令有4个
CMP
    CMP{条件}{P}    <op1>, <op2>
                    status = op1 - (op2)                             相减操作
CMN -- 比较取负的值
    CMN{条件}{P}    <op1>, <op2>
                    status = op1 - (-op2)                          相加操作
    CMN R0, #1  @把R0与-1进行比较
TEQ -- 测试等价
   TEQ{条件} {P}  <op1>, <op2>
                     status = op1 EOR op2                        相异或操作
    注意:TEQ是对2个数,进行EOR
TST --- 测试位
   TST{条件} {P}  <op1>, <op2>
                     status = op1 AND op2                        相与操作
    TST R0,#0x01 @测试Bit0是否为0
注意:CMP 和 CMN 是算术指令,TEQ 和 TST 是逻辑指令
TEQ和TST通常是一个寄存器和一个立即数按位运算后做比较
mrs & msr

mrs用来读psr,msr用来写psr
CPSR寄存器比较特殊,需要专门的指令访问,这就是mrs和msr。

Psr是Cpsr和spsr
用法
ARM主要汇编指令总结
cpsr_c的意思是cpsr的C位控制位
那么怎么知道cpsr到第有多少字段呢?
C:控制域屏蔽字段(PSR中的第0位到第7位);
X:扩展域屏蔽字段(PSR中的第8位到第15位);
S:状态域屏蔽字段(PSR中的第16位到第32位);
F:标志域屏蔽字段(PSR中的第24位到第31位)。

b & bl & bx

b 直接跳转(就没打开算返回)
bl branch and link,跳转前把返回地址放入lr中{r14中},以便返回,以便用于函数调用
//bx跳转同时切换到ARM模式,一般用于异常处理的跳转。。。基本上不用

ldr/str & ldm/stm & swp

单个字/半字/字节访问 ldr/str
多字批量访问 ldm/stm
swp r1, r2, [r0]
Swp的主要作用是交换的作用,先把[r0]放到r1里,然后把r2放回到[r0]

swp r1, r1, [r0]
上面这个例子就是交换了,这个用的比较多,这就完成了寄存器和内存的交换

mcr & mrc

mrc用于读取CP15中的寄存器
mcr用于写入CP15中的寄存器
ARM主要汇编指令总结
https://blog.csdn.net/gameit/article/details/13169405
mcr{<cond>} p15, <opcode_1>, <Rd>, <Crn>, <Crm>, {<opcode_2>}
opcode_1:对于cp15永远为0
Rd:ARM的普通寄存器
Crn:cp15的寄存器,合法值是c0~c15
Crm:cp15的寄存器,一般均设为c0
opcode_2:一般省略或为0
其实就是r0和c1的数据的ldr和str

补充一个概念为什么要有伪指令?
答:伪指令的出现时因为有合法立即数和非法立即数的概念,由于非法立即数的出现,导致编写很麻烦,所以通过伪指令可以通用这些指令。
那什么是非法立即数?
非法立即数是指连续出现ff(8个1)以上就是非法的,不能超过8个1

上面那条指令就是报错指令
那么伪指令为什么就可以呢?
答:因为编译器可以帮你搞定,帮你转换。

猜你喜欢

转载自blog.51cto.com/11372477/2341297