ldmfd与stmfd指令(ARM指令总结)

一.指令的比较

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即可

  1. mov r1, #0x11
  2. mov r2, #0x22
  3. mov r3, #0x33
  4. ldr r13, =0xFF30
  5. stmfd r13!, {r1-r3}
  6. stmfd r13, {r1-r3}
  7. 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



猜你喜欢

转载自blog.csdn.net/chengchaonan/article/details/80724576
今日推荐