Thumb指令集之: 單寄存器數(shù)據(jù)傳送指令
Thumb指令集支持寄存器的裝載和存儲,即LDR和STR指令。8和類型的Load/Store指令在Thumb指令集中可用。這些指令使用兩種尋址模式:寄存器偏移和立即數(shù)偏移。指令所能存取的數(shù)據(jù)包括字、半字和字節(jié),同時半字和字節(jié)可以為有符號數(shù)或無符號數(shù)。
表11.4總結(jié)了Thumb狀態(tài)下可用的數(shù)據(jù)傳送指令。
表11.4 Thumb狀態(tài)數(shù)據(jù)傳送指令
助記符
說明
操作
LDR
傳送32位字到寄存器
Rd<-mem32[address]
STR
存儲32位寄存器的值
Rd->mem32[address]
LDRB
傳送8位字節(jié)到寄存器
Rd<-mem8[address]
STRB
保存寄存器中的字節(jié)
Rd->mem8[address]
LDRH
傳送16位半字到寄存器
Rd<-mem16[address]
STRH
保存寄存器中的半字
Rd->mem16[address]
LDRSB
裝載有符號字節(jié)到寄存器
Rd<-sighExtend(mem8[address])
STRSB
裝載有符號半字到寄存器
Rd<-sighExtend(mem16[address])
Thumb數(shù)據(jù)傳送指令的基本語法格式分為以下4種。
①<opcode1><Rd>,[<Rn>,#<5_bit_offset>]
其中,<opcode1>:=LDR|LDRH|LDRB|STR|STRH|STRB
②<opcode2><Rd>,[<Rn>,<Rm>]
其中,<opcode2>:=LDR|LDRH|LDRB|LSRSH|STR|STRH|STRB
③LDR<Rd>,[PC,<8_bit_offset>]
④<opcode3><Rd>,[SP,#<8_bit_offset>]
其中,<opcode3>:=LDR|STR
下面詳細介紹各數(shù)據(jù)傳送指令的語法和使用。
11.5.1寄存器裝載指令LDR(1)(1)編碼格式
寄存器裝載指令LDR(1)的編碼格式如圖11.42所示。
圖11.42LDR(1)指令的編碼格式
這種形式的LDR指令將32位內(nèi)存數(shù)據(jù)裝載到通用寄存器。常用于結(jié)構(gòu)體的數(shù)據(jù)訪問。域的基地址放在Rn寄存器中。
(2)指令的語法格式
LDR<Rd>,[<Rn>,#<immed_5>*4]
①<Rd>
目的寄存器。用于存放從內(nèi)存中取出的數(shù)據(jù)。
②<Rn>
基址寄存器,用于存放所取數(shù)據(jù)的基地址。
③<immed_5>
5位立即數(shù)。該立即數(shù)的4倍加上基址寄存器的值形成目標地址。
(3)指令操作的偽代碼
Address=Rn+(immed_5*4)
Ifaddress[1:0]==0b00
Data=Memory[address,4]
Else
Data=UNPREDICTABLE
Rd=data
(4)對應的ARM指令
LDR<Rd>,[<Rn>,#<immed_5>*4]
注意
如果指令訪問地址非字對齊,則指令的執(zhí)行結(jié)果不可預知。
11.5.2寄存器裝載指令LDR(2)(1)編碼格式
寄存器裝載指令LDR(2)的編碼格式如圖11.43所示。
圖11.43LDR(2)指令的編碼格式
寄存器裝載指令LDR(2)允許將一個32位內(nèi)存數(shù)據(jù)裝載到通用寄存器。此種形式的LDR指令常被用于訪問數(shù)組中的元素。
(2)指令的語法格式
LDR<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
寄存器存放內(nèi)存訪問基地址。
③<Rm>
寄存器存放內(nèi)存訪問偏移地址。
(3)指令操作的偽代碼
Address=Rn+Rm
Ifaddress[1:0]==0b00
Data=Memory[address,4]
Else
Data=UNPREDICTABLE
Rd=data
(4)對應的ARM指令
LDR<Rd>,[<Rn>,<Rm>]
11.5.3寄存器裝載指令LDR(3)(1)編碼格式
寄存器裝載指令LDR(3)的編碼格式如圖11.44所示。
圖11.44LDR(3)指令的編碼格式
寄存器裝載指令LDR(3)允許將一個32位內(nèi)存數(shù)據(jù)裝載到通用寄存器。此種形式的LDR指令常被用于訪問PC相關(guān)(PC-relative)數(shù)據(jù)。
(2)指令的語法格式
LDR<Rd>,[PC,#<immed_8>*4]
①<Rd>
目的寄存器。
②PC
程序指針寄存器,用于計算內(nèi)存訪問的地址。計算地址時,PC值的bit[1]被系統(tǒng)默認為0進行計算,所以產(chǎn)生的內(nèi)存訪問地址必為字對齊。
③<immed_8>
8位立即數(shù)。該立即數(shù)的4倍將和PC值相加,形成內(nèi)存訪問地址。
(3)指令操作的偽代碼
Address=(PC[31:2]<<2)+(immed_8*4)
Rd=Memory[address,4]
(4)對應的ARM指令
LDR<Rd>,[PC,#<immed_8>*4]
11.5.4寄存器裝載指令LDR(4)(1)編碼格式
寄存器裝載指令LDR(4)的編碼格式如圖11.45所示。
圖11.45LDR(4)指令的編碼格式
寄存器裝載指令LDR(4)允許將一個32位內(nèi)存數(shù)據(jù)裝載到通用寄存器。此種形式的LDR指令常被用于訪問堆棧數(shù)據(jù)。
(2)指令的語法格式
LDR<Rd>,SP,#<immed_8>*4]
①<Rd>
目的寄存器。
②SP
堆棧指針寄存器,用于計算內(nèi)存訪問地址。
③<immed_8>
8位立即數(shù)。該立即數(shù)的4倍將和SP值相加,形成內(nèi)存訪問地址。
(3)指令操作的偽代碼
Address=SP+(immed_8*4)
Ifaddress[1:0]==0b00
Data=memory[address,4]
Else
Data=UNPREDICTABLE
Rd=data
(4)對應的ARM指令
LDR<Rd>,[SP,#<immed_8>*4]
11.5.5字節(jié)加載指令LDRB(1)(1)編碼格式
字節(jié)加載指令LDRB(1)的編碼格式如圖11.46所示。
圖11.46LDRB(1)指令的編碼格式
LDRB(1)字節(jié)數(shù)據(jù)加載指令用于從內(nèi)存中將一個8位的字節(jié)數(shù)據(jù)讀取到指令中的目標寄存器中,并將寄存器的高24位清零。常用于結(jié)構(gòu)體的數(shù)據(jù)訪問。域的基地址放在Rn寄存器中。
(2)指令的語法格式
LDRB<Rd>,[<Rn>,#<immed_5>]
①<Rd>
目的寄存器。
②<Rn>
指令的基址寄存器。
③<immed_5>
5位立即數(shù)。用于與<Rn>寄存器中的數(shù)值相加,形成內(nèi)存訪問地址。
(3)指令操作的偽代碼
address=Rn+immed_5
Rd=memory[address,1]
(4)對應的ARM指令
LDRB<Rd>,[<Rn>,#<immed_5>]
11.5.6字節(jié)加載指令LDRB(2)(1)編碼格式
字節(jié)加載指令LDRB(2)的編碼格式如圖11.47所示。
圖11.47LDRB(2)指令的編碼格式
LDRB(2)字節(jié)數(shù)據(jù)加載指令用于從內(nèi)存中將一個8位的字節(jié)數(shù)據(jù)讀取到指令中的目標寄存器中,并將寄存器的高24位清零。此種形式的LDRB(2)指令常用于數(shù)組元素的訪問。
(2)指令的語法格式
LDRB<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
存放形成內(nèi)存訪問地址的第一個寄存器。
③<Rm>
存放形成內(nèi)存訪問地址的第二個寄存器。
(3)指令操作的偽代碼
address=Rn+Rm
Rd=Memory[address,1]
(4)對應的ARM指令
LDRB<Rd>,[<Rn>,<Rm>]
11.5.7半字加載指令LDRH(1)(1)編碼格式
半字數(shù)據(jù)加載指令LDRH(1)的編碼格式如圖11.48所示。
圖11.48LDRH(1)指令的編碼格式
LDRH(1)半字數(shù)據(jù)加載指令用于從內(nèi)存中將一個16位的半字數(shù)據(jù)讀取到指令中的目標寄存器中,并將寄存器的高16位清零。常用于結(jié)構(gòu)體的數(shù)據(jù)訪問。域的基地址放在Rn寄存器中。
(2)指令的語法格式
LDRH<Rd>,[<Rn>,#<immed_5>*2]
①<Rd>
目的寄存器。
②<Rn>
指令的基址寄存器。
③<immed_5>
5位立即數(shù)。該寄存器數(shù)值的2倍將與<Rn>寄存器中的數(shù)值相加,形成內(nèi)存訪問地址。
(3)指令操作的偽代碼
address=Rn+(immed_5*2)
ifaddress[0]==0
data=Memory[address,2]
else
data=UNPREDICTABLE
Rd=data
(4)對應的ARM指令
LDRH<Rd>,[<Rn>,#<immed_5>*2]
11.5.8半字數(shù)據(jù)加載指令LDRH(2)(1)編碼格式
半字數(shù)據(jù)加載指令LDRH(2)的編碼格式如圖11.49所示。
LDRH(2)字節(jié)數(shù)據(jù)加載指令用于從內(nèi)存中將一個16位的半字數(shù)據(jù)讀取到指令中的目標寄存器中,并將寄存器的高16位清零。此種形式的LDRH(2)指令常用于數(shù)組元素的訪問。
圖11.49LDRH(2)指令的編碼格式
(2)指令的語法格式
LDRB<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
此寄存器存放內(nèi)存訪問基地址。
③<Rm>
此寄存器存放內(nèi)存訪問偏移地址。
(3)指令操作的偽代碼
address=Rn+Rm
ifaddress[0]==0
data=memory[address,2]
else
data=UNPREDICTABLE
Rd=data
(4)對應的ARM指令
LDRH<Rd>,[<Rn>,<Rm>]
11.5.9有符號字節(jié)數(shù)據(jù)加載指令LDRSB(1)編碼格式
有符號字節(jié)數(shù)據(jù)加載指令LDRSB的編碼格式如圖11.50所示。
圖11.50LDRSB指令的編碼格式
LDRSB指令用于從內(nèi)存中將一個8位的字節(jié)數(shù)據(jù)讀取到指令中的目標寄存器中,并將寄存器的高24位設置成該字節(jié)數(shù)據(jù)的符號位的值(即將該8位字節(jié)數(shù)據(jù)進行符號位擴展,生成32位字數(shù)據(jù))。
(2)指令的語法格式
LDRSB<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
此寄存器存放內(nèi)存訪問基地址。
③<Rm>
此寄存器存放內(nèi)存訪問偏移地址。
(3)指令操作的偽代碼
address=Rn+Rm
Rd=SignExtend(Memory[address,1])
(4)對應的ARM指令
LDRSB<Rd>,[<Rn>,<Rm>]
11.5.10有符號半字數(shù)據(jù)加載指令LDRSH(1)編碼格式
有符號字節(jié)數(shù)據(jù)加載指令LDRSH的編碼格式如圖11.51所示。
圖11.51LDRSH指令的編碼格式
LDRSH指令用于從內(nèi)存中將一個16位的半字數(shù)據(jù)讀取到指令中的目標寄存器中,并將寄存器的高16位設置成該半字數(shù)據(jù)的符號位的值(即將該16位半字數(shù)據(jù)進行符號位擴展,生成32位字數(shù)據(jù))。
(2)指令的語法格式
LDRBH<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
此寄存器存放內(nèi)存訪問基地址。
③<Rm>
此寄存器存放內(nèi)存訪問偏移地址。
(3)指令操作的偽代碼
address=Rn+Rm
ifaddress[0]==0
data=memory[address,2]
else
data=UNPREDICTABLE
Rd=SignExtend[data]
(4)對應的ARM指令
LDRSH<Rd>,[<Rn>,<Rm>]
11.5.11寄存器存儲指令STR(1)(1)編碼格式
寄存器存儲指令STR(1)的編碼格式如圖11.52所示。
圖11.52STR(1)指令的編碼格式
這種形式的STR指令將32位通用寄存器的數(shù)值存儲到內(nèi)存中。該指令常用于結(jié)構(gòu)體的數(shù)據(jù)訪問。域的基地址放在Rn寄存器中。
(2)指令的語法格式
STR<Rd>,[<Rn>,#<immed_5>*4]
①<Rd>
目的寄存器。用于存放從內(nèi)存中取出的數(shù)據(jù)。
②<Rn>
基址寄存器,用于存放所取數(shù)據(jù)的基地址。
③<immed_5>
5位立即數(shù)。該立即數(shù)的4倍加上基址寄存器的值為目標地址。
(3)指令操作的偽代碼
address=Rn+(immed_5*4)
ifaddress[1:0]==0b00
Memory[address,4]=Rd
Else
Memory[address,4]=UNPREDICTABLE
(4)對應的ARM指令
STR<Rd>,[<Rn>,#<immed_5>*4]
11.5.12寄存器存儲指令STR(2)(1)編碼格式
寄存器存儲指令STR(2)的編碼格式如圖11.53所示。
圖11.53STR(2)指令的編碼格式
寄存器裝載指令STR(2)將一個32位通用寄存器數(shù)據(jù)存儲到內(nèi)存單元中。此種形式的STR指令常被用于訪問數(shù)組中的元素。
(2)指令的語法格式
LDR<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
存放形成內(nèi)存訪問地址的第一個寄存器。
③<Rm>
存放形成內(nèi)存訪問地址的第二個寄存器。
(3)指令操作的偽代碼
address=Rn+Rm
ifaddress[1:0]==0b00
Memory[address,4]==Rd
Else
Memory[address,4]==UNPREDICTABLE
(4)對應的ARM指令
STR<Rd>,[<Rn>,<Rm>]
11.5.13寄存器存儲指令STR(3)(1)編碼格式
寄存器存儲指令STR(3)的編碼格式如圖11.54所示。
圖11.54STR(3)指令的編碼格式
寄存器存儲指令STR(3)允許將一個32位通用寄存器的值存儲到內(nèi)存。此種形式的STR指令常被用于訪問堆棧數(shù)據(jù)。
(2)指令的語法格式
STR<Rd>,[SP,#<immed_8>*4]
①<Rd>
目的寄存器。
②SP
堆棧指針寄存器,用于計算內(nèi)存訪問的地址。
③<immed_8>
8位立即數(shù)。該立即數(shù)的4倍將和堆棧指針寄存器SP的值相加,形成內(nèi)存訪問地址。
(3)指令操作的偽代碼
address=SP+(immed_8*4)
ifaddress[1:0]==0b00
Memory[address,4]=Rd
Else
Memory[address,4]=UNPREDICTABLE
(4)對應的ARM指令
STR<Rd>,[SP,#<immed_8>*4]
11.5.14字節(jié)存儲指令STRB(1)(1)編碼格式
字節(jié)存儲加載指令STRB(1)的編碼格式如圖11.55所示。
圖11.55STRB(1)指令的編碼格式
STRB(1)字節(jié)數(shù)據(jù)存儲指令用于將一個8位的字節(jié)數(shù)據(jù)寫入到指令中指定的內(nèi)存單元,該字節(jié)數(shù)據(jù)為指令中存放源操作數(shù)寄存器的低8位。常用于結(jié)構(gòu)體的數(shù)據(jù)訪問。域的基地址放在Rn寄存器中。
(2)指令的語法格式
STRB<Rd>,[<Rn>,#<immed_5>]
①<Rd>
目的寄存器。
②<Rn>
指令的基址寄存器。
③<immed_5>
5位立即數(shù)。用于與<Rn>寄存器中的數(shù)值相加,形成內(nèi)存訪問地址。
(3)指令操作的偽代碼
address=Rn+immed_5
Memory[address,1]=Rd[7:0]
(4)對應的ARM指令
STRB<Rd>,[<Rn>,#<immed_5>]
11.5.15寄存器存儲指令STRB(2)(1)編碼格式
寄存器存儲指令STRB(2)的編碼格式如圖11.56所示。
圖11.56STRB(2)指令的編碼格式
寄存器存儲指令STRB(2)用于將一個8位的字節(jié)數(shù)據(jù)寫入到指令中指定的內(nèi)存單元。此種形式的LDRB指令常被用于訪問數(shù)組中的元素。
(2)指令的語法格式
STRB<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
此寄存器存放內(nèi)存訪問基地址。
③<Rm>
此寄存器存放內(nèi)存訪問偏移地址。
(3)指令操作的偽代碼
address=Rn+Rm
Memory[address,1]=Rd[7:0]
(4)對應的ARM指令
STRB<Rd>,[<Rn>,<Rm>]
11.5.16半字存儲指令STRH(1)(1)編碼格式
半字存儲加載指令STRH(1)的編碼格式如圖11.57所示。
圖11.57STRH(1)指令的編碼格式
STRH(1)半字數(shù)據(jù)存儲指令用于將一個16位的半字數(shù)據(jù)寫入到指令中指定的內(nèi)存單元,該半字數(shù)據(jù)為指令中存放源操作數(shù)寄存器的低16位。常用于結(jié)構(gòu)體的數(shù)據(jù)訪問。域的基地址放在Rn寄存器中。
(2)指令的語法格式
STRH<Rd>,[<Rn>,#<immed_5>*2]
①<Rd>
目的寄存器。
②<Rn>
指令的基址寄存器。
③<immed_5>
5位立即數(shù)。該立即數(shù)的2倍與<Rn>寄存器中的數(shù)值相加,形成內(nèi)存訪問地址。
(3)指令操作的偽代碼
address=Rn+(immed_5*2)
ifaddress[1:0]==0
Memory[address,2]=Rd[15:0]
Else
Memory[address,2]=UNPREDICTABLE
(4)對應的ARM指令
STRH<Rd>,[<Rn>,#<immed_5>*2]
11.5.17寄存器存儲指令STRH(2)(1)編碼格式
寄存器存儲指令STRH(2)的編碼格式如圖11.58所示。
圖11.58STRH(2)指令的編碼格式
寄存器存儲指令STRH(2)用于將一個8位的半字數(shù)據(jù)寫入到指令中指定的內(nèi)存單元。此種形式的STRH指令常被用于訪問數(shù)組中的元素。
(2)指令的語法格式
STRH<Rd>,[<Rn>,<Rm>]
①<Rd>
目的寄存器。
②<Rn>
存放形成內(nèi)存訪問地址的第一個寄存器。
③<Rm>
存放形成內(nèi)存訪問地址的第二個寄存器。
(3)指令操作的偽代碼
address=Rn+Rm
ifaddress[1:0]==0
Memory[address,2]=Rd[15:0]
Else
Memory[address,2]=UNPREDICTABLE
(4)對應的ARM指令
STRH<Rd>,[<Rn>,<Rm>]
11.5.18數(shù)據(jù)傳送指令舉例下面的例子程序綜合使用了各種數(shù)據(jù)傳送指令,通過該例可以對Thumb狀態(tài)下數(shù)據(jù)傳送指令有更深入的了解。
LDRr4,[r2,#4] ;將[r2+4]地址單元字數(shù)據(jù)加載到寄存器r4
LDRr4,[r2,r1] ;將[r2+r4]地址單元字數(shù)據(jù)加載到寄存器r4
STRr0,[r7,#0x7c] ;將r0中的字數(shù)據(jù)存儲到[r7+124]的內(nèi)存地址單元中
STRBr1,[r5,#31] ;將r1的低8位數(shù)據(jù)存儲到[r5+31]的內(nèi)存地址單元中
STRHr4,[r2,r3] ;將r4的低16位數(shù)據(jù)存儲到[r2+r3]的內(nèi)存地址單元中
LDRHr3,[r6,r5] ;將[r6+r5]地址單元低16位數(shù)據(jù)加載到寄存器r3中
LDRBr2,[r1,#5] ;將[r1+5]地址單元低8位數(shù)據(jù)加載到寄存器r2中
LDRr6,[PC,#0xFC] ;將[PC+0x3FC]地址單元數(shù)據(jù)加載到寄存器r6中
LDRr5,[SP,#64] ;將[SP+64]地址單元數(shù)據(jù)加載到寄存器r5中
STRr4,[SP,#0x260] ;將寄存器r4中的數(shù)據(jù)存儲到[SP+0x260]內(nèi)存地址單元中