多寄存器寻址指令ldmia/ldmib和ARM存储器访问指令——多寄存器存取
Posted 天才2012
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多寄存器寻址指令ldmia/ldmib和ARM存储器访问指令——多寄存器存取相关的知识,希望对你有一定的参考价值。
多寄存器和堆栈寻址的用法:多寄存器寻址:LDMIA,LDMIB,STMIA,STMIB,LDMDA,LDMDB,STMDA,STMDB;
堆栈寻址:LDMFA,LDMFD,STMFA,STMFD,LDMEA,LDMED,STMEA,STMED;
弄清堆栈寻址的SP的变化:LDMFA,LDMFD,STMFA,STMFD,LDMEA,LDMED,STMEA,STMED;
IB: 每次传送前地址加4;
DA: 每次传送后地址减4;
DB: 每次传送前地址减4;
FD: 满递减堆栈;
ED: 空递减堆栈;
FA: 满递增堆栈;
EA: 空递增堆栈。
1、多寄存器寻址:
LDMIA R0!,R1-R4
;R1<----[R0]
;R2<----[R0+4]
;R3<----[R0+8]
;R4<----[R0+12]
例如:
所有的示例指令执行前:
mem32[0x1000C] = 0x04
mem32[0x10008] = 0x03
mem32[0x10004] = 0x02
mem32[0x10000] = 0x01
r0 = 0x00010010
r1 = 0x00000000
r3 = 0x00000000
r4 = 0x00000000
1) ldmia r0!, r1-r3 2) ldmib r0!, r1-r3
执行后: 执行后:
r0 = 0x00100000 r0 = 0x00100000
r1 = 0x01 r1 = 0x02
r2 = 0x02 r2 = 0x03
r3 = 0x03 r3 = 0x04
2、堆栈寻址:
STMFD入栈指令,相当于STMDB
STMFD SP!,R2-R4 ;[SP-4]<---R4
;[SP-8]<---R3
;[SP-12]<---R2
LDMFD出栈指令,相当于LDMIA
LDMFD SP!,R6-R8 ;R6<----[SP]
;R7<----[SP+4]
;R8<----[SP+8]
LDRcondT Rd,<地址> ;将指定地址上的字数据读入Rd STRcondT Rd,<地址> ;将Rd中的字数据存入指定地址 LDRcondBT Rd,<地址> ;将指定地址上的字节数据读入Rd STRcondBT Rd,<地址> ;将Rd中的字节数据存入指定地址 •LDR和STR——字和无符号字节加载/存储指令 LDR/STR指令寻址非常灵活,它由两部分组成,其中一部分为一个基址寄存器,可以为任一个通用寄存器;另一部分为一个地址偏移量。地址偏移量有以下3种格式: 立即数。立即数可以是一个无符号的数值。这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如:LDR R1,[R0,#0x12] ;R1<-[R0+0x12] 寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如:LDR R1,[R0,R2] ; R1<-[R0+R2] LDR R1,[R0,-R2] ; R1<-[R0-R2] 寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如:LDR R1,[R0,R2,LSL #2]
多寄存器加载/存储指令格式如下: LDMcond<模式> Rn!,reglist^ ; STMcond<模式> Rn!,reglist^ ; 多寄存器加载/存储指令格式如下: LDMcond<模式> Rn!,reglist^ ; STMcond<模式> Rn!,reglist^ ; cond:指令执行的条件; 模式:控制地址的增长方式,一共有8种模式; !:表示在操作结束后,将最后的地址写回Rn中; reglist :表示寄存器列表,可以包含多个寄存器,它们使用“,”隔开,如R1,R2,R6-R9,寄存器由小到大排列; ^:可选后缀。允许在用户模式或系统模式下使用。它有以下两个功能: 1)若op是LDM且寄存器列表包含R15时,那么除了正常的多寄存器传送外,还将SPSR也复制到CPSR中。这用于异常处理返回,仅在异常模式下使用。 2)数据传入或传出的是用户模式下的寄存器,而不是当前模式的寄存器。
多寄存器加载/存储指令的8种模式如下表所示,右边四种为堆栈操作、左边四种为数据传送操作。
模式 | 说明 | 模式 | 说明 |
IA | 每次传送后地址加4 | FD | 满递减堆栈 |
IB | 每次传送前地址加4 | ED | 空递减堆栈 |
DA | 每次传送后地址减4 | FA | 满递增堆栈 |
DB | 每次传送前地址减4 | EA | 空递增堆栈 |
数据块传送操作 | 堆栈操作 |
数据块传送 存储 | 堆栈操作 压栈 | 说明 | 数据块传送 加载 | 堆栈操作 出栈 | 说明 | |
STMDA | STMED | 空递减 | LDMDA | LDMFA | 满递减 | |
STMIA | STMEA | 空递增 | LDMIA | LDMFD | 满递增 | |
STMDB | STMFD | 满递减 | LDMDB | LDMEA | 空递减 | |
STMIB | STMFA | 满递增 | LDMIB | LDMED | 空递增 |
两段代码的执行结果是一样的,但是使用堆栈指令的压栈和出栈操作编程很简单(只要前后一致即可),而使用数据块指令进行压栈和出栈操作则需要考虑空与满、加与减对应的问题。(相当于堆栈指令做了封装)
以上是关于多寄存器寻址指令ldmia/ldmib和ARM存储器访问指令——多寄存器存取的主要内容,如果未能解决你的问题,请参考以下文章