数据传送指令之:单寄存器的Load/Store指令
5.3单寄存器的Load/Store指令Load/Store内存访问指令在ARM寄存器和存储器之间传送数据。ARM指令中有3种基本的数据传送指令。
① 单寄存器Load/Store指令(Single Register)
这些指令在ARM寄存器和存储器之间提供更灵活的单数据项传送方式。数据项可以是字节、16位半字或32位字。
② 多寄存器Load/Store内存访问指令
这些指令的灵活性比单寄存器传送指令差,但可以使大量的数据更有效地传送。它们用于进程的进入和退出、保存和恢复工作寄存器以及拷贝存储器中的一块数据。
③ 单寄存器交换指令(Single Register Swap)
这些指令允许寄存器和存储器中的数值进行交换,在一条指令中有效地完成Load/Store操作。它们在用户级编程中很少用到。它的主要用途是在多处理器系统中实现信号量(Semaphores)的操作,以保证不会同时访问公用的数据结构。
5.3.1字数据传送指令
这种指令用于把单一的数据传入或者传出一个寄存器。支持的数据类型有字节(8位)、半字(16位)和字(32位)。
表5.1总结了所有单寄存器的Load/Store指令。
表5.1 单寄存器Load/Store指令
指 令
作 用
操 作
LDR
把一个字装入一个寄存器
Rd←mem32
STR
将存储器中的字保存到寄存器
Rd→mem32
LDRB
把一个字节装入一个寄存器
Rd←mem8
STRB
将寄存器中的低8位字节保存到存储器
Rd→mem8
LDRH
把一个半字装入一个寄存器
Rd←mem16
STRH
将寄存器中的低16位半字保存到存储器
Rd→mem16
LDRBT
用户模式下将一个字节装入寄存器
Rd←mem8 under user mode
STRBT
用户模式下将寄存器中的低8位字节保存到存储器
Rd→mem8 under user mode
LDRT
用户模式下把一个字装入一个寄存器
Rd←mem32under user mode
STRT
用户模式下将存储器中的字保存到寄存器
Rd→mem32 ]under user mode
LDRSB
把一个有符号字节装入一个寄存器
Rd←sign{mem8}
LDRSH
把一个有符号半字装入一个寄存器
Rd←sign{mem16}
1.LDR指令
(1)指令编码格式
LDR指令用于从内存中将一个32位的字读取到目标寄存器。
指令的编码格式如图5.3所示。
图5.3LDR指令编码格式
LDR指令根据<addr_mode>所确定的地址模式将一个32位字读取到指令中的目标寄存器<Rd>。如果指令中的寻址方式确定的地址不是字对齐的,则读出的数值要进行循环右移。所移位数为寻址方式确定的地址bits8的倍,也就是说处理器将取到的数值作为字的最低位处理。
如果设置了L位,则进行装载,否则进行存储。
如果设置了P位,则使用预先变址寻址,否则使用过后变址寻址。
如果设置了U位,则给出的偏移量被加到基址寄存器上,否则从中减去偏移量。
如果设置了B位,传送内存的一个字节,否则传送一个字。这在助记符末尾添加后缀“B”,如MOV r7,r5变为MOVB r7,r5。
W位的解释依赖于使用的地址模式。
·对于预先变址寻址,设置W位强制把它用做地址转换的最终地址写回基址寄存器中(例如,传送的副作用是Rn:= Rn +/-offset。这在汇编器中表示为给指令加上后缀“!”。)。
·对于过后变址寻址,地址总是写回,设置 W 位指示在进行传送之前强制地址转换。这在汇编器中表示为给指令加上后缀“T”。
当PC作为LDR的目的寄存器<Rd>时,从存储器取得的数据将被当作目标地址值,程序将跳转到目标地址开始执行。
(2)指令的语法格式
LDR{<cond>}<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示LDR指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
指令操作的伪代码如下面程序段所示。
IfConditionPassed{cond}then
Ifaddress == 0b00then
Value = Memory
Elseifaddress == 0b01then
Value = MemoryRotate_Right 8
Elseifaddress == 0b10then
Value = MemoryRotate_Right 16
Eles/* address == 0b11*/
Value = MemoryRotate_Right 24
If(Rd is R15)then
If (architecture version 5 or above)then
PC = value AND 0xfffffffe
T Bit = value
Else
PC = value AND 0xfffffffc
Else
Rd = value
(4)指令举例
LDRr1, ;将r0+12地址处的数据读出,保存到r1中(r0的值不变)
LDRr1, ;将r0地址处的数据读出,保存到r1中(零偏移)
LDRr1, ;将r0+r2地址的数据读出,保存到r1中(r0的值不变)
LDRr1, ;将r0+r2×4地址处的数据读出,保存到r1中(r0,r2的值不变)
LDRRd,label ;label为程序标号,label必须是当前指令的±4KB范围内
LDRRd,,#0x04 ;Rn的值用作传输数据的存储地址。在数据传送后,将偏移量0x04与
Rn相加,结果写回到Rn中。Rn不允许是r15
注意
地址对齐问题:大多数情况下,必须保证用于32位传送的地址是32位对齐的。
2.STR指令
(1)指令编码格式
STR指令用于将一个32位的字数据写入到指令中指定的内存单元。
指令的编码格式如图5.4所示。
图5.4STR指令编码格式
(2)指令的语法格式
STR{<cond>}<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示STR指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
指令操作的伪代码如下面程序段所示。
IfConditionPassed{cond}then
Memory=Rd
(4)指令举例
LDR/STR指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等等,若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转。
① 变量访问
NumCountEQU0x40003000 ;定义变量NumCount
LDRR0,=NumCount ;使用LDR伪指令装载NumCount的地址到R0
LDRR1, ;取出变量值
ADDR1,R1,#1 ;NumCount=NumCount+1
STR R1, ;保存变量
② GPIO设置
GPIO—BASEEQU 0xe0028000 ;定义GPIO寄存器的基地址
……
LDR R0,=GPIO—BASE
LDR R1,=0x00ffff00 ;将设置值放入寄存器
STR R1, ;IODIR=0x00ffff00,IOSET的地址为0xE0028004
③ 程序散转
…
MOVr2,r2,LSL #2 ;功能号乘以4,以便查表
LDRPC, ;查表取得对应功能子程序地址,并跳转
NOP
FUN—TABDCD FUN—SUB0
DCD FUN—SUB1
DCD FUN—SUB2
…
5.3.2字节数据传送指令(LDRB/STRB)
1.LDRB指令
(1)指令编码格式
LDRB指令根据<addr_mode>所确定的地址模式将一个8位字节读取到指令中的目标寄存器<Rd>。
指令的编码格式如图5.5所示。
图5.5LDRB指令编码格式
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c45219951e-thumb.png
注意
LDRB指令加载一个内存地址的8位字节到一个通用寄存器中。寄存器的高位数据补0。
(2)指令的语法格式
LDR{<cond>}B<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示LDRB指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
ifConditionPassed{cond}then
Rd = Memory
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c45248c840-thumb.png
注意
当PC作为位基地址出现在指令中时,指令中将会使用PC相关地址,使用这种方法可以编写自己的位置无关(position-independ)指令。
2.STRB指令
(1)指令编码格式
STRB指令从寄存器中取出指定的8位字节放入寄存器的低8位,并将寄存器的高位补0。
指令的编码格式如图5.6所示。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c4521e00f5-thumb.png
图5.6STRB指令编码格式
(2)指令的语法格式
STR{<cond>}B<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示STRB指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c4521e00f5-thumb.png
注意
当PC作为目标寄存器<Rd>出现在指令中时,指令的执行结果不可预知。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
ifConditionPassed{cond}then
Memory = Rd
5.3.3半字数据传送指令(LDRH/STRH)
1.LDRH指令
(1)指令编码格式
LDRH指令用于从内存中将一个16位的半字读取到目标寄存器。
如果指令的内存地址不是半字节对齐的,指令的执行结果不可预知。
指令的编码格式如图5.7所示。
图5.7LDRH指令的编码格式
(2)指令的语法格式
LDR{<cond>}H<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示LDRH指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c45240a54c-thumb.png
注意
如果PC作为目标寄存器,指令的执行结果不可预知。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
ifConditionPassed{cond}then
if address==0
data=Memory
else/*address==1*/
data=unpredictable
Rd=data
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c4523dd258-thumb.png
注意
在包含系统控制协处理器的芯片应用中,如果定义了地址对齐检测,当bit!=0时,将发生地址对齐异常。
2.STRH指令
(1)指令编码格式
STRH指令从寄存器中取出指定的16位半字放入寄存器的低16位,并将寄存器的高位补0。
指令的编码格式如图5.8所示。
图5.8STRH指令的编码格式
(2)指令的语法格式
STR{<cond>}H<Rd>,<addr_mode>
① <cond>
指令编码中的条件域。它指示STRH指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c452221d22-thumb.png
注意
如果PC作为目标寄存器,指令的执行结果不可预知。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
ifConditionPassed{cond}then
if address==0
data=Rd
else/*address==1*/
data=unpredictable
Memory=data
5.3.4用户模式字数据传送指令(LDRT/STRT)
1.LDRT指令
(1)指令编码格式
LDRT指令用于从内存中将一个32位的字读取到目标寄存器。
指令的编码格式如图5.9所示。
LDRT指令根据<addr_mode>所确定的地址模式将一个32位字读取到指令中的目标寄存器<Rd>。如果指令中的寻址方式确定的地址不是字对齐的,则读出的数值要进行循环右移。所移位数为寻址方式确定的地址bits的8倍。也就是说处理器将取到的数值作为字的最低位处理。
图5.9LDRT指令编码格式
当处理器在特权模式下使用此指令时,内存系统将该操作当作一般用户模式下得内存访问指令。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c4522ea3d8-thumb.png
注意
指令的编码格式中,P位指定位“0”,也就是说LDRT指令的寻址方式为固定寻址方式,即后索引编码寻址(post_indexed_addressing_mode)。
(2)指令的语法格式
LDR{<cond>}T<Rd>,<post_indexed_addressing_mode>
① <cond>
为指令编码中的条件域。它指示LDRT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <post_indexex_address_mode>
使用后索引地址模式寻址。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c452250e02-thumb.png
注意
后索引地址模式中P=0并且W=0(即bit=0、bit=0)。但此指令P=0并且W=1(即bit=1、bit=0)。但实际的寻址操作是一样的。
(3)指令操作的伪代码
指令操作的伪代码如下面程序段所示。
IfConditionPassed{cond}then
Ifaddress==0b00
Rd=Memory
Elseifaddress==0b01
Rd=MemoryRotate_Right8
Elseifaddress==0b10
Rd=MemoryRotate_Right16
Elseaddress==0b11
Rd=MemoryRotate_Right24
2.STRT指令
(1)指令编码格式
STRT指令用于将一个32位的字数据写入到指令中指定的内存单元。
当处理器在特权模式下执行此指令时,内存系统将该操作当作一般用户模式下的内存访问操作。
指令的编码格式如图5.10所示。
图5.10STR指令编码格式
(2)指令的语法格式
STR{<cond>}T<Rd>,<post_indexed_addressing_mode>
① <cond>
为指令编码中的条件域。它指示STRT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <post_indexed_address_mode>
使用后索引地址模式寻址,参见LDRT指令。
(3)指令操作的伪代码
指令操作的伪代码如下面程序段所示。
IfConditionPassed{cond}then
Memory=Rd
5.3.5用户模式字节数据传送指令(LDRBT/STRBT)
1.LDRBT指令
(1)指令编码格式
LDRBT指令根据<post_indexed_addressing_mode>地址模式将一个8位字节读取到指令中的目标寄存器<Rd>。
当处理器在特权模式下执行此指令时,内存系统将该操作当作一般用户模式下的内存访问操作。
指令的编码格式如图5.11所示。
图5.11LDRBT指令编码格式
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c4522a41fa-thumb.png
注意
LDRBT指令加载一个内存地址的8位字节到一个通用寄存器中。寄存器的高位数据补0。
(2)指令的语法格式
LDR{<cond>}BT<Rd>,<post_indexed_addressing_mode>
① <cond>
为指令编码中的条件域。它指示LDRBT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))
。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <post_indexed_addressing_mode>
使用后索引地址模式寻址,参见LDRT指令。
(3)指令操作的伪代码
指令操作的伪代码如下面程序段所示。
IfConditionPassed{cond}then
Rd=Memory
2.STRBT指令
(1)指令编码格式
STRBT指令用于将一个8位的字节数据写入到指令中指定的内存单元。
当处理器在特权模式下执行此指令时,内存系统将该操作当作一般用户模式下的内存访问操作。
指令的编码格式如图5.12所示。
图5.12STRBT指令编码格式
(2)指令的语法格式
STR{<cond>}BT<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示LDRBT指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <post_indexed_addressing_mode>
使用后索引地址模式寻址,参见LDRT指令。
(3)指令操作的伪代码
指令操作的伪代码如下面程序段所示。
IfConditionPassed{cond}then
Memory=Rd
5.3.6有符号的字节/半字数据传送指令(LDRBT/STRBT)
1.LDRSB指令
(1)指令编码格式
LDRSB指令根据<addr_mode>所确定的地址模式将一个8位字节读取到指令中的目标寄存器<Rd>。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c452301003-thumb.png
注意
LDRSB与LDRB指令的不同之处在于它将寄存器的高24位设置成该字节数据的符号位的值(即将该8位字节数据进行符号位扩展,生成32位字数据)。
指令的编码格式如图5.13所示。
图5.13LDRSB指令编码格式
(2)指令的语法格式
LDR{<cond>}SB<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示LDRSB指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
IfConditionPassed{cond}then
data=Memory
Rd=SignExtend{data}
2.LDRSH指令
(1)指令编码格式
LDRSH指令根据<addr_mode>所确定的地址模式将一个16位半字读取到指令中的目标寄存器<Rd>。
http://upload.semidata.info/new.eefocus.com/article/image/2013/09/08/522c45232e5d2-thumb.png
注意
LDRSH与LDRH指令的不同之处在于它将寄存器的高16位设置成该字节数据的符号位的值(即将该16位字节数据进行符号位扩展,生成32位字数据)。
指令的编码格式如图5.14所示。
图5.14LDRSH指令编码格式
(2)指令的语法格式
LDR{<cond>}SH<Rd>,<addr_mode>
① <cond>
为指令编码中的条件域。它指示LDRSH指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
② <Rd>
确定使用哪个通用寄存器作为目标寄存器。
③ <addr_mode>
它确定了指令编码中的I、P、U、W、Rn和<addr_mode>位。所有的寻址模式中,都会确定一个基址寄存器Rn。
(3)指令操作的伪代码
IfConditionPassed{cond}then
ifaddress==0
data=Memory
else/*address ==1*/
data=UNPREDICTABLE
Rd=SignExtend{data}
页:
[1]