这儿比较下简单混杂的四条指令,现已在这4条指令的混杂上花费了许多精力,现在做个小结,LDR,STR,LDM,STM这四条指令,关于LDM和STM的阐明,见别的一个阐明文件(我的一篇新的文章),阐明晰这两个文件用于栈操作时的留意事项。
(1)LDR:L一共LOAD,LOAD的意义应该了解为:Load from memory into register。下面这条查办就阐明的很清楚:
LDRR1,[R2]
R1<——[R2]
便是把R2中的内容对应的地址的值(一个memory地址),读取到R1中(一个register)
(2)STR:S一共STORE,STORE的意义应该了解为:Store from a register into memory。下面这条查办一共的很清楚:
STRR1,[R2]
R1——>[R2]
便是把寄存器R1中的内容“保存”到R2的值对应的地址中(一个memory地址)。
明显,这两条查办都有个特色,便是寄存器写在前面(左面)而内存地址写在后边(右边),数据传送的方向则是恰好相反的。
(3)LDM:L的意义仍然是LOAD,便是Load from memory into register。不同之处在于,该指令是将内存中仓库内的数据,批量的赋值给寄存器,便是出栈操作;其间仓库指针一般对应于SP,留意SP是寄存器R13,实践用到的却是R13中的内存地址,仅仅该指令没有写为[R13],一起,LDM指令中寄存器和内存地址的方位相关于前面两条指令改变了,下面的比如:
LDMFDSP! ,{R0, R1, R2}
实践上能够了解为:LDMFD[SP]!,{R0, R1, R2}
明显,这儿SP是个地址,可是写在了左面,而把寄存器组—R0, R1, R2写在了右边,这个是要留意的。
(4)STM:S的意义仍然是STORE,与LDM是配对运用的,其指令格局上也类似,即差异于STR,是将仓库指针写在左面,而把寄存器组写在右边。
STMFDSP! ,{R0}
相同的,该指令也可了解为:STMFD[SP]!,{R0}
这儿,是把R0保存到仓库中。
明显,这两个仓库操作指令也有个特色,便是寄存器组写在后边(右边)而仓库指针写在前面(左面),并且实践上运用的是仓库指针中的内存地址,这一点与前面两条指令是有差异的。
这四条指令中,前面两条和后边两条其实联络不多,反而是不同很大,因而,能够直接把这两组指令委任开来,以为它们之间没有联络,这样防止误解。
ARM指令中STM和LDM的了解误区
STM和LDM的主要用途是现场维护、数据、参数传递等,其形式有8种,如下:
注:前面4种用于数据块的传输,后边4种用于仓库操作
(1)IA 每次传送后地址加4
(2)IB 每次传送前地址加4
(3)DA 每次传送后地址减4
(4)DB 每次传送前地址减4
(5)FD 满递减仓库
(6)FA 满递加仓库
(7)ED 空递减仓库
(8)EA 空递加仓库
下面的推荐关于空递减仓库和空递加仓库相同适用.
在仓库操作时,常常过错以为运用STMFD满递减将寄存器压入仓库后,在弹出数据的时分应该运用LDMFA。
可是FD和FA仅用于仅仅现在操作的仓库是何种形式(仓库共有四种形式),FD指明现在的仓库是满递减仓库,
则数据入栈时的指令为STMFD,那么数据出栈时的指令对应的为LDMFD,而不是LDMFA。
咱们能够这样以为STMFD等价于STMDB,LDMFD等价于STMIA
那么,数据传输的次序和数据入栈的次序又是怎么呢
先来看STMFD SP!,{R1-R3} 碑文的成果图(操作之后SP指向SP)
SP——->
|R3|
|R2|
SP——>|R1|
那么STMFD SP!,{R3,R2,R1}碑文后的仓库次序是不是刚好和上面的仓库次序相反,实践情况时这两个指令碑文后的仓库数据次序相同,由于ARM编译器会主动将STMFD SP!,{R3,R2,R1}转换为STMFD SP!,{R0-R3}指令,也便是说,ARM编译器默许高寄存器优先存入仓库。即使你在指令STMFD SP!,{R3,R2,R1}中故意“组织”了寄存器入栈次序,而在编译时编译器又从头做了处理,打乱了你希望的数据入栈次序。
同理STMDB R0!,{R1-R3}和STMDB R0!,{R3,R2,R1}指令碑文后数据在仓库中的次序完全一致。
STMFD SP!,{R1-R3}指令对应的出栈指令是LDMFD SP!,{R1-R3}(R1,R2,R3的次序恣意)