我们走得太快,灵魂都跟不上了。 微小的幸福就在身边,容易满足就是天堂。

这个view里面有 PUSH/LDR/SUB/MOVS/BLX/SUBS/BEQ/CMP ,这些差不多都是常见的,不过也不需要看得懂,理解这个指令即可,接下来我们就来分析下这些指令分别有什么作用吧。
先引入 概念性 东西,免得大家后面被搞混,那就是为什么会有S和!。
S:指令执行后程序状态寄存器的条件标志位将被刷新 , 如ADDS R1,R0,#2
! :指令中的地址表达式中含有!后缀时,指令执行后,基址寄存器中的地址值将发生变化,变化的结果是:基址寄存器中的值(指令执行后)=指令执行前的值 + 地址偏移量,如 LDR R3,[R0,#2]! 指令执行后,R0 = R0 + 2
接下来分别讲解这个View里面的指令分别有什么作用。
PUSH,顾名思义,直接PUSH进栈了。相反的,POP则为出栈了。
指令示例:
PUSH{cond} reglist PUSH将寄存器推入满递减堆栈
PUSH {r0,r4-r7} 将R0,R4-R7寄存器内容压入堆栈
POP{cond} reglist POP从满递减堆栈中弹出数据到寄存器
POP {r0,r4-r7} 将R0,R4-R7寄存器从堆栈中弹出
LDR,指令语法:LDR{条件} 目的寄存器,<存储器地址>,LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理,当程序计数器PC作为 目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。该指令在程序设计 中比较常用,且寻址方式灵活多样。
LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0。
LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0。
MOVS 、LDR 这些是跳转指令,直接向程序计数器PC写入跳转地址值,通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,那有人会问,如果说从当前指令向前或向后的32MB的地址空间的跳转是怎么个实现原理?其实在 上篇文章中提及到了,它们是B\BL\BLX\BX 四大指令,这个我们最后才来讲解,其实它们有点像我们常说的分支结构,我们从图片里面选第四条指令作为查看数据。
则可以看到,R5是原地址,其实为0xFF8->0x104A,复制返回地址到PC,实现子的返回,做安卓的同学可能会有个疑问,为什么有个S,因为语法就是 MOV{条件}{S} 目的寄存器+源操作数。
看到这里大家可能会头晕,怎么感觉都是看不懂的数字,那其它那些,如ADD、等就给大家整理了一份表格。
助记符
指令功能描述
ADD
加法指令
MRS
传送CPSR或SPSR的内容到通用寄存器指令
ADC
带进位加法指令
MRC
从协处理器寄存器到ARM寄存器的数据传输指令
AND
逻辑与指令
MSR
传送通用寄存器到CPSR或SPSR的指令
B
分支指令
MUL
32位乘法指令
BL
带返回的分支指令
BIC
位清零指令
BLX
带返回和状态切换的分支指令
MLA
32位乘加指令
BX
带状态切换的分支指令
MVN
数据取反传送指令
TST
位测试指令
ORR
逻辑或指令
CDP
协处理器数据操作指令
RSC
带错位的逆向减法指令
RSB
逆向减法指令
SBC
带错位减法指令
CMN
比较反值指令
CMP
比较指令
STC
协处理器寄存器写入存储器指令
EOR
异或指令
STM
批量内存字写入指令
LDC
存储器到协处理器的数据传输指令
STR
寄存器到存储器的数据存储指令
LDM
加载多个寄存器指令
SUB
减法指令
LDR
存储器到寄存器的数据加载指令
SWI
软件中断指令
MCR
从ARM寄存器到协处理器寄存器的数据传输指令
TEQ
相等测试指令
MOV
数据传送指令
SUBS 从表中可以看到,SUB是减法指令,如SUB R0,R1,R2则对应了R0 = R1 - R2,SUB R0,R1,#1 则是R0 = R1 -1,要注意的是 SUBS 是低32位相减。
那 BEQ 呢?!不要着急,来看下图
BEQ 指令是跳转指令,但是跳转要满足一定的条件,满足则跳转执行,看下图红框部分。
那就只剩下 CMP 了,CMP是比较指令,指令格式:CMP{条件} 操作数1,操作数2。
如 CMP R1,#10,则等于比较R1和10,并设置CPSR的标志位。
CMP R1,R0 ;将寄存器R1的值与寄存器R0的值相减,并根据 结果设置CPSR的标志位
CMP R1,#100 ;将寄存器R1的值与立即数100相减,并根 据结果设置CPSR的标志位
如果和BEQ一起使用话则是:CMP R1,#0 换行 BEQ Label ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行
OK , 从第一张图中我们看到后面跟的是两位,那如果是复杂一点的两位以上怎么看?
先来看MOV的,如MOV R0,R1 , LSL R3 ,这个又是何解?其实它是将R1的值左移R3位,然后将结果存放到R0中 。
再来看LDR的,LDR R0,[R1],R2 ,这个何解? 它是将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2写入R1 , 要记住,R1是最终落地的地址 。