一.指令的比较
ldr指令是存储器到寄存器的加载指令,ldm指令加载到多个寄存器的指令
str指令是寄存器到存储器的存储指令,stm指令是存储到多个存储器的指令
如果是对于特殊的内存空间比如栈,它的地址特点就是从高到低(一般情况下)
也就是我们选择的是FD,这样每来一个新的数据,我们将它存放进pc-4的地点
而出栈的时候,同样从最低的地址开始出,然后一步步地址增大,这是栈的特殊结构,我们必须这样使用
而对于其他不是这种特殊结构的内存空间,我们可以选择当这个数据送到存储器之后,下一个数据是
存放到它的上面还是下面
IA:stmia r4,{r0,r1,r2}
将r0中的数据存放到以r4中的数据为地址的内存中去,然后地址加4(这里跟每次栈的地址也要加4一样)
然后r1放到上面这个地址,然后地址再加4
IB:stmib r4,{r0,r1,r2}
先将r4中的数据加4(全都是十六进制下,因为地址的表示就是十六进制)然后r0进去,然后地址加4,r1进去
上面两种是往上生长的,不同于栈,是往下生长的,并且栈是先存放进去数据然后加4
DA:向下生长,这种类似于栈的生长方式,都是每次传送后地址-4
DB:向下生长
而更不更新地址值要看有没有!跟上面的生长方式无关
二.特殊的寄存器
stmfd r13!,{r0,r1,r2}
如果换成其他的寄存器 r8,表示将r8中的数据作为地址,但这个地址不是栈中的地址。
将r0中的数据放入到以r8中的数据为地址的内存中去,且ARM必须高地址存放高编号寄存器
如果是栈的话,必须从高地址开始入,所以入的必须是高编号寄存器
出栈的时候,ldmfd r13!,{r4,r5,r6}
以r13存放的数据作为地址,将低地址中的数据加载进r4中,然后r13+4,将此地址中的数据放入到r5中,然后在放入到r6寄存器中
首先可以理解为r13中存放的是内存中的栈的可用的地址,r13寄存器指向的这块栈与寄存器r0,r1,r2中的数据进行交换
并且因为ARM是以4个字节为单位处理数据,所以r13中存放的地址要以4个字节为单位往下移动,虽然这4个字节的地址
范围,只存放寄存器中的数据,如果是立即数,只占一个字节,剩余的地址空间内全部补0即可
- mov r1, #0x11
- mov r2, #0x22
- mov r3, #0x33
- ldr r13, =0xFF30
- stmfd r13!, {r1-r3}
- stmfd r13, {r1-r3}
- stmfd r13!, {r1-r3}
在执行完第5步之后,栈中的地址从0xff30-0xff2c,这是4个字节的地址空间中应该存放的是高编号的寄存器中的数值
所以,应该存放进入33,剩余地址空间内用00补齐,同样,从0xff2c-0xff28存放的是22,00。从0xff28-0xff24存放11
数据完成交换之后,r13是不是指向当前更新过的地址看后面有没有!。一般情况需要更新,如果不更新,那么后面
stmfd r13!,{r3,r4,r5}会将r3,r4,r5中的值存放进入地址为0xff30的栈中,就会造成之前存放的r0中的数据被覆盖掉。
三
大端小端的方式仅仅是对同一个数据来说,而上述从r0到r2是操作多个数据,对于操作的多个数据要按照具体的指令
进行存放,只有一个数据在一个字节存放不下去
比如ldr r0,#0x11223344才有大小端的区分,这时低地址处存放44高地址处存放11