?
11.5??單寄存器數(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.42??LDR(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)
If??address[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.43??LDR(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
If??address[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.44??LDR(3)指令的編碼格式
寄存器裝載指令LDR(3)允許將一個32位內(nèi)存數(shù)據(jù)裝載到通用寄存器。此種形式的LDR指令常被用于訪問PC相關(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.45??LDR(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)
If??address[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.46??LDRB(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.47??LDRB(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.48??LDRH(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)
if??address[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.49??LDRH(2)指令的編碼格式
(2)指令的語法格式
LDRB??<Rd>,[<Rn>,<Rm>]
①?<Rd>
目的寄存器。
②?<Rn>
此寄存器存放內(nèi)存訪問基地址。
③?<Rm>
此寄存器存放內(nèi)存訪問偏移地址。
(3)指令操作的偽代碼
address?=?Rn?+?Rm
if??address[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.50??LDRSB指令的編碼格式
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.51??LDRSH指令的編碼格式
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
if??address[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.52??STR(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)
if??address[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.53??STR(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
if??address[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.54??STR(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)
if??address[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.55??STRB(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.56??STRB(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.57??STRH(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)
if??address[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.58??STRH(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
if??address[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ù)傳送指令有更深入的了解。
LDR??r4,[r2,#4] ;將[r2+4]地址單元字數(shù)據(jù)加載到寄存器r4
LDR??r4,[r2,r1] ;將[r2+r4]地址單元字數(shù)據(jù)加載到寄存器r4
STR??r0,[r7,#0x7c] ;將r0中的字數(shù)據(jù)存儲到[r7+124]的內(nèi)存地址單元中
STRB??r1,[r5,#31] ;將r1的低8位數(shù)據(jù)存儲到[r5+31]的內(nèi)存地址單元中
STRH??r4,[r2,r3] ;將r4的低16位數(shù)據(jù)存儲到[r2+r3]的內(nèi)存地址單元中
LDRH??r3,[r6,r5] ;將[r6+r5]地址單元低16位數(shù)據(jù)加載到寄存器r3中
LDRB??r2,[r1,#5] ;將[r1+5]地址單元低8位數(shù)據(jù)加載到寄存器r2中
LDR??r6,[PC,#0xFC] ;將[PC+0x3FC]地址單元數(shù)據(jù)加載到寄存器r6中
LDR??r5,[SP,#64] ;將[SP+64]地址單元數(shù)據(jù)加載到寄存器r5中
STR??r4,[SP,#0x260] ;將寄存器r4中的數(shù)據(jù)存儲到[SP+0x260]內(nèi)存地址單元中