?
4.2? 內(nèi)存訪問指令尋址
根據(jù)內(nèi)存訪問指令的分類,內(nèi)存訪問指令的尋址方式可以分為以下幾種。
① 字及無符號字節(jié)的Load/Store指令的尋址方式。
② 雜類Load/Store指令的尋址方式。
③ 批量Load/Store指令的尋址方式。
④ 協(xié)處理器Load/Store指令的尋址方式。
4.2.1? 字及無符號字節(jié)的Load/Store指令的尋址方式
字及無符號字節(jié)的Load/Store指令語法格式如下:
LDR|STR{<cond>}{B}{T}? <Rd>,<addressing_mode>
其中<addressing_mode>共有9種尋址方式,如表4.2所示。
表4.2?? 字及無符合字節(jié)的Load/Store指令的尋址方式
格??? 式 |
模??? 式 |
|
1 |
[Rn,#±<offset_12>] |
立即數(shù)偏移尋址 (Immediate offset) |
2 |
[Rn,±Rm] |
寄存器偏移尋址 (Register offset) |
3 |
[Rn,Rm,<shift>#< offset_12>] |
帶移位的寄存器偏移尋址 (Scaled register offset) |
4 |
[Rn,#±< offset_12>]! |
立即數(shù)前索引尋址 (Immediate pre-indexed) |
5 |
[Rn,±Rm]! |
寄存器前索引尋址 (Register post-indexed) |
6 |
[Rn,Rm,<shift>#< offset_12>]! |
帶移位的寄存器前索引尋址 (Scaled register pre-indexed) |
7 |
[Rn],#±< offset_12> |
立即數(shù)后索引尋址 (Immediate post-indeded) |
8 |
[Rn],±<Rm> |
寄存器后索引尋址 (Register post-indexed) |
9 |
[Rn],±<Rm>,<shift>#< offset_12> |
帶移位的寄存器后索引尋址 (Scaled register post-indexed) |
字及無符號字節(jié)的Load/Store指令的解碼格式如圖4.13所示。
圖4.13? 字及無符號字節(jié)的Load/Store指令的解碼格式
?
編碼格式中各位的含義如表4.3所示。
表4.3?????????? 字和無符號半字Load/Store指令編碼格式各位含義
位? 標? 識 |
取??? 值 |
含??? 義 |
P |
P=0 |
使用后索引尋址 |
P=1 |
使用偏移地址或前索引尋址(由W位決定) |
|
U |
U=0 |
訪問的地址=基址寄存器的值-偏移量(offset) |
U=1 |
訪問的地址=基址寄存器的值+偏移量(offset) |
|
B |
B=0 |
字訪問Load/Store |
B=1 |
無符號字節(jié)訪問Load/Store |
|
W |
W=0 |
如果P=0,該指令為LDR、LDRB、STR或STRB指令,且內(nèi)存訪問指令為正常訪問指令;如果P=1,指令執(zhí)行不更新基地址 |
W=1 |
如果P=0,該指令為LDRBT、LDRT、STRBT或STRT,且指令為非特權(quán)(用戶模式)訪問指令;如果P=1,計算內(nèi)存地址并更新基地址 |
|
L |
L=0 |
Store指令 |
L=1 |
Load指令 |
?
1.[Rn,#±<offset_12>]
(1)編碼格式
指令的編碼格式如圖4.14所示。
圖4.14? 內(nèi)存訪問指令——立即數(shù)偏移尋址編碼格式
內(nèi)存訪問地址為基址寄存器Rn的值加(或減)立即數(shù)offset_12。
編程中,在訪問結(jié)構(gòu)體或記錄(record)類型的變量時,這些內(nèi)存的操作指令是十分有效的。另外,在子程序中也常用這些指令訪問本地變量和堆棧。
(2)語法格式
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,#±<offset_12>]
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <offset_12>為12位立即數(shù),內(nèi)存訪問地址偏移量。
(3)操作偽代碼
If? U = = 1? then
???? Address = Rn + offset_12
Else
???? Address = Rn – offset_12
(4)說明
① 如果指令中沒有指定立即數(shù),使用[<Rn>],編譯器按[<Rn>,#0]形式編碼。
② 如果Rn被指定為程序計數(shù)器r15,其值為當前指令地址加8。
2.[Rn,±Rm]
(1)編碼格式
指令的編碼格式如圖4.15所示。
圖4.15? 內(nèi)存訪問指令——寄存器偏移尋址編碼格式
內(nèi)存訪問地址為基址寄存器Rn的值加(或減)偏移寄存器Rm的值。
該尋址方式適合使用指針訪問字節(jié)數(shù)組中的數(shù)據(jù)成員。
(2)語法格式
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>]
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量。
(3)操作偽代碼
If? U = = 1? then
???? Address = Rn + Rm
Else
???? Address = Rn – Rm
(4)說明
如果Rn被指定為程序計數(shù)器r15,其值為當前指令地址加8;如果r15被用作偏移地址寄存器Rm的值,指令的執(zhí)行結(jié)果不可預(yù)知。
3.[Rn,Rm,<shift>#< offset_12>]
(1)編碼格式
指令的編碼格式如圖4.16所示。
圖4.16? 內(nèi)存訪問指令——帶移位的寄存器偏移尋址編碼格式
內(nèi)存地址為Rn的值加/減通過移位操作后的Rm的值。
當數(shù)組中的成員長度大于1個字節(jié)時,使用該尋址方式可高效率地訪問數(shù)組成員。
?
(2)語法格式
語法格式有以下5種。
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,LSL #< offset_12>]
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,LSR #< offset_12>]
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,ASR #< offset_12>]
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,ROR #< offset_12>]
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,RRX]
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量;
·? LSL表示邏輯左移操作;
·? LSR表示邏輯右移操作;
·? ASR表示算術(shù)右移操作;
·? ROR表示循環(huán)右移操作;
·? RRX表示擴展的循環(huán)右移。
·? <shift_imm>為移位立即數(shù)。
(3)操作偽代碼
Case? shift? of
???? 0b00? /*LSL*/
???? ??????Index = Rm logic_shift_left? shift_imm
???? 0b01? /*LSR*/
?????????? If? shift_imm = = 0? then /*LSR? #32*/
??????????????? Index = 0
?????????? Else
??????????????? Index = Rm logical_shift_right? shift_imm
???? 0b10? /*ASR*/
?????????? If? shift_imm = = 0 then /*ASR? #32*/
??????????????? If? Rm[31] = = 1 then
???????????????????? Index = 0xffffffff
??????????????? Else
???????????????????? Index = 0
?????????? Else
??????????????? Index = Rm? Arithmetic_shift_Right? shift_imm
???? 0b11? /* ROR or RRX*/
?????????? If? shift_imm = = 0 then /*RRX*/
??????????????? Index = (C flag Logical_shift_left 31) OR
????????????????????????? (Rm logical_shift_Right 1)
?????????? Else /*ROR*/
??????????????? Index = Rm Rotate_Right shift_imm
Endcase
If? U = = 1 then
???? Address = Rn + index
Else /*U = = 0*/
???? Address = Rn – index
(4)說明
如果Rn被指定為程序計數(shù)器r15,其值為當前指令地址加8;如果r15被用作偏移地址寄存器Rm的值,指令的執(zhí)行結(jié)果不可預(yù)知。
4.[Rn,#±< offset_12>]!
(1)編碼格式
指令的編碼格式如圖4.17所示。
圖4.17? 內(nèi)存訪問指令——前索引立即數(shù)偏移尋址編碼格式
內(nèi)存地址為基址寄存器Rn加/減立即數(shù)offset_8的值。當指令執(zhí)行的條件<cc>滿足時,生成的地址寫回基址寄存器Rn中。
該尋址方式適合訪問數(shù)組自動進行數(shù)組下標的更新。
(2)語法格式
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<offset_12>] !
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <offset_12>為12位立即數(shù),內(nèi)存訪問地址偏移量;
·? !設(shè)置指令編碼中的W位,更新指令基址寄存器。
(3)操作偽代碼
If? U == 1? then
???? Address = Rn + offset_12
Else
???? Address = Rn – offset_12
If? ConditionPassed{cond}? then
???? Rn = address
(4)說明
① 如果指令中沒有指定立即數(shù),使用[<Rn>],編譯器按[<Rn>,#0] ! 形式編碼。
② 如果Rn被指定為程序計數(shù)器r15,指令的執(zhí)行結(jié)果不可預(yù)知。
5.[Rn,±Rm]!
(1)編碼格式
指令的編碼格式如圖4.18所示。
圖4.18? 內(nèi)存訪問指令——前索引寄存器偏移尋址編碼格式
內(nèi)存訪問地址為基址寄存器Rn的值加(或減)偏移寄存器Rm的值。當指令的執(zhí)行條件<cc>滿足時,生成地地址將寫回基址寄存器。
(2)語法格式
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>]
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量;
·? !設(shè)置指令編碼中的W位,更新指令基址寄存器。
(3)操作偽代碼
If? U = = 1? then
???? Address = Rn + Rm
Else
???? Address = Rn – Rm
If? ConditionPassed{cond}? then
???? Rn = address
(4)說明
如果Rn和Rm指定為同一寄存器,指令的執(zhí)行結(jié)果不可預(yù)知。
?
6.[Rn,±Rm,<shift>#< offset_12>]!
(1)編碼格式
指令的編碼格式如圖4.19所示。
圖4.19? 內(nèi)存訪問指令——帶移位的前索引寄存器偏移尋址編碼格式
內(nèi)存地址為Rn的值加/減通過移位操作后的Rm的值。當指令的執(zhí)行條件<cc>滿足時,生成地地址將寫回基址寄存器。
(2)語法格式
語法格式有以下5種。
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,LSL #< offset_12>] !
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,LSR #< offset_12>] !
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,ASR #< offset_12>] !
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,ROR #< offset_12>] !
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>,±<Rm>,RRX] !
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量;
·? LSL表示邏輯左移操作;
·? LSR表示邏輯右移操作;
·? ASR表示算術(shù)右移操作;
·? ROR表示循環(huán)右移操作;
·? RRX表示擴展的循環(huán)右移。
·? <shift_imm>為移位立即數(shù)。
·? !設(shè)置指令編碼中的W位,更新指令基址寄存器。
(3)操作偽代碼
Case? shift? of
???? 0b00? /*LSL*/
?????????? Index = Rm logic_shift_left? shift_imm
???? 0b01? /*LSR*/
?????????? If? shift_imm = = 0? then /*LSR? #32*/
??????????????? Index = 0
?????????? Else
??????????????? Index = Rm logical_shift_right? shift_imm
???? 0b10? /*ASR*/
?????????? If? shift_imm = = 0 then /*ASR? #32*/
??????????????? If? Rm[31] = = 1 then
???????????????????? Index = 0xffffffff
??????????????? Else
???????????????????? Index = 0
?????????? Else
??????????????? Index = Rm? Arithmetic_shift_Right? shift_imm
???? 0b11? /* ROR or RRX*/
?????????? If? shift_imm = = 0 then /*RRX*/
??????????????? Index = (C flag Logical_shift_left 31) OR
????????????????????????? (Rm logical_shift_Right 1)
?????????? Else /*ROR*/
??????????????? Index = Rm Rotate_Right shift_imm
Endcase
If? U = = 1 then
???? Address = Rn + index
Else /*U = = 0*/
???? Address = Rn – index
If? ConditionPassed{cond}? then
???? Rn = address
(4)說明
① 當PC用作基址寄存器Rn或Rm時,指令執(zhí)行結(jié)果不可預(yù)知。
② 當Rn和Rm是同一個寄存器時,指令的執(zhí)行結(jié)果不可預(yù)知。
7.[Rn],#±< offset_12>
(1)編碼格式
指令的編碼格式如圖4.20所示。
圖4.20? 內(nèi)存訪問指令——后索引立即數(shù)偏移尋址編碼格式
指令使用基址寄存器Rn的值作為實際內(nèi)存訪問地址。當指令的執(zhí)行條件滿足時,將基址寄存器的值加/減偏移量產(chǎn)生新的地址值回寫到Rn寄存器中。
(2)語法格式
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>],±<offset_12>
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <offset_12>為12位立即數(shù),內(nèi)存訪問地址偏移量。
(3)操作偽代碼
Address = Rn
If? conditionPassed{cond}? then
???? If? U = = 1 then
????????? Rn = Rn + offset_12
???? Else
????????? Rn = Rn – offset_12
(4)說明
① LDRBT、LDRT、STRBT和STRT指令只支持后索引尋址。
② 如果Rn被指定為程序計數(shù)器r15,指令的執(zhí)行結(jié)果不可預(yù)知。
8.[Rn],±<Rm>
(1)編碼格式
指令的編碼格式如圖4.21所示。
圖4.21? 內(nèi)存訪問指令——后索引寄存器偏移尋址編碼格式
指令訪問地址為實際的基址寄存器的值。當指令的執(zhí)行條件滿足時,將基址寄存器的值加/減索引寄存器Rm的值回寫到Rn基址寄存器。
(2)語法格式
LDR|STR{<cond>}{B}{T}? <Rd>,[Rn],±<Rm>
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量。
(3)操作偽代碼
Address = Rn
If ?conditionPassed{cond}? then
???? If? U = = 1? then
????????? Rn = Rn + Rm
???? Else
????????? Rn = Rn – Rm
(4)說明
① LDRBT、LDRT、STRBT和STRT指令只支持后索引尋址。
② 如果Rm和Rn指定為同一寄存器,指令的執(zhí)行結(jié)果不可預(yù)知。
?
9.[Rn],±Rm,<shift>#< offset_12>]
(1)編碼格式
指令的編碼格式如圖4.22所示。
圖4.22? 內(nèi)存訪問指令——帶移位的后索引寄存器偏移尋址編碼格式
實際的內(nèi)存訪問地址為寄存器Rn的值。當指令的執(zhí)行條件滿足時,將基址寄存器值加/減一個地址偏移量產(chǎn)生新的地址值。
(2)語法格式
語法格式有以下5種。
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>],±<Rm>,LSL #< offset_12>
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>],±<Rm>,LSR #< offset_12>
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>],±<Rm>,ASR #< offset_12>
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>],±<Rm>,ROR #< offset_12>
LDR|STR{<cond>}{B}{T}? <Rd>,[<Rn>],±<Rm>,RRX
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量;
·? LSL表示邏輯左移操作;
·? LSR表示邏輯右移操作;
·? ASR表示算術(shù)右移操作;
·? ROR表示循環(huán)右移操作;
·? RRX表示擴展的循環(huán)右移。
·? <shift_imm>為移位立即數(shù)。
(3)操作偽代碼
Address = Rn
Case? shift? of
???? 0b00? /*LSL*/
?????????? Index = Rm logic_shift_left? shift_imm
???? 0b01? /*LSR*/
?????????? If? shift_imm = = 0? then /*LSR? #32*/
??????????????? Index = 0
?????????? Else
??????????????? Index = Rm logical_shift_right? shift_imm
???? 0b10? /*ASR*/
?????????? If? shift_imm = = 0 then /*ASR? #32*/
??????????????? If? Rm[31] = = 1 then
???????????????????? Index = 0xffffffff
??????????????? Else
???????????????????? Index = 0
?????????? Else
??????????????? Index = Rm? Arithmetic_shift_Right? shift_imm
???? 0b11? /* ROR or RRX*/
?????????? If? shift_imm = = 0 then /*RRX*/
??????????????? Index = (C flag Logical_shift_left 31) OR
????????????????????????? (Rm logical_shift_Right 1)
?????????? Else /*ROR*/
??????????????? Index = Rm Rotate_Right shift_imm
Endcase
If? ConditionPassed{cond}? then
??? If? U = = 1 then
???????? Rn = Rn + index
??? Else /*U = = 0*/
???????? Rn = Rn – index
(4)說明
① LDRBT、LDRT、STRBT和STRT指令只支持后索引尋址。
② 當PC用作基址寄存器Rn或Rm時,指令執(zhí)行結(jié)果不可預(yù)知。
③ 當Rn和Rm是同一個寄存器時,指令的執(zhí)行結(jié)果不可預(yù)知。
4.2.2? 雜類Load/Store指令的尋址方式
使用該類尋址方式的指令的語法格式如下。
LDR|STR{<cond>}H|SH|SB|D? <Rd>,<addressing_mode>
使用該類尋址方式的指令包括:(有符號/無符號)半字Load/Store指令、有符號字節(jié)Load/Store指令和雙字Load/Store指令。
該類尋址方式分為6種類型,如表4.4所示。
表4.4?? 雜類Load/Store指令的尋址方式
格??? 式 |
模??? 式 |
|
1 |
[Rn,#±<offset_8>] |
立即數(shù)偏移尋址 (Immediate offset) |
2 |
[Rn,±Rm] |
寄存器偏移尋址 (Register offset) |
3 |
[Rn,#±< offset_8>]! |
立即數(shù)前索引尋址 (Immediate pre-indexed) |
4 |
[Rn,±Rm]! |
寄存器前索引尋址 (Register post-indexed) |
5 |
[Rn],#±< offset_8> |
立即數(shù)后索引尋址 (Immediate post-indeded) |
6 |
[Rn],±<Rm> |
寄存器后索引尋址 (Register post-indexed) |
?
雜類Load/Store指令的解碼格式如圖4.23所示。
圖4.23? 雜類Load/Store指令解碼格式
編碼格式中各標志位的含義如表4.5所示。
表4.5??????? 雜類Load/Store指令編碼格式各標志位含義
位? 標? 識 |
取??? 值 |
含??? 義 |
P |
P=0 |
使用后索引尋址 |
P=1 |
使用偏移地址或前索引尋址(由W位決定) |
續(xù)表
位? 標? 識 |
取??? 值 |
含??? 義 |
U |
U=0 |
訪問的地址=基址寄存器的值-偏移量(offset) |
U=1 |
訪問的地址=基址寄存器的值+偏移量(offset) |
|
W |
W=0 |
如果P=0,使用后索引尋址;P=1,指令不改變基址寄存器的值 |
W=1 |
如果P=0,未定義指令;如果P=1,將計算的內(nèi)存訪問地址回寫到基址寄存器 |
|
L |
L=0 |
Store指令 |
L=1 |
Load指令 |
|
S |
S=0 |
無符號半字內(nèi)存訪問 |
S=1 |
有符號半字內(nèi)存訪問 |
|
H |
H=0 |
字節(jié)訪問 |
H=1 |
半字訪問 |
注意 |
當S=0并且H=0時,并非無符號的字節(jié)內(nèi)存訪問指令。無符號的內(nèi)存訪問指令不使用該種尋址方式,詳見本章上一節(jié)。 當S=1并且L=0時,并非是有符號的存儲指令,而是未定義指令。ARM指令并未區(qū)分有符號和無符號的字節(jié)和半字存儲。 |
1.[Rn,#±<offset_8>]
(1)編碼格式
指令的編碼格式如圖4.24所示。
圖4.24? 雜項內(nèi)存訪問指令——立即數(shù)偏移尋址編碼格式
內(nèi)存訪問地址為基址寄存器Rn的值加(或減)立即數(shù)offset_8。
編程中,在訪問結(jié)構(gòu)體或記錄(record)類型的變量時,這些內(nèi)存的操作指令是十分有效的。另外,在子程序中,也常用這些指令訪問本地變量和堆棧。當offset_8=0時,內(nèi)存訪問地址即基址寄存器Rn的值。
(2)語法格式
LDR|STR{<cond>}H|SH|SB|D? <Rd>,[<Rn>,#±<offset_12>]
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址。
·? <offset_8>為8位立即數(shù),內(nèi)存訪問地址偏移量。
(3)操作偽代碼
offset_8 = (immedH << 4) OR immedL
If? U = = 1? then
???? Address = Rn + offset_8
Else
???? Address = Rn – offset_8
(4)說明
① 如果指令中沒有指定立即數(shù),使用[<Rn>],編譯器按[<Rn>,#0]形式編碼。
② 如果Rn被指定為程序計數(shù)器r15,其值為當前指令地址加8。
?
2.[Rn,±Rm]
(1)編碼格式
指令的編碼格式如圖4.25所示。
圖4.25? 雜項內(nèi)存訪問指令——寄存器偏移尋址編碼格式
內(nèi)存訪問地址為基址寄存器Rn的值加(或減)偏移寄存器Rm的值。
該尋址方式適合使用指針訪問數(shù)組中的單個數(shù)據(jù)成員。
(2)語法格式
LDR|STR{<cond>}H|SH|SB|D? <Rd>,[<Rn>,±<Rm>]
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量。
(3)操作偽代碼
If? U = = 1? then
???? Address = Rn + Rm
Else
???? Address = Rn – Rm
(4)說明
如果Rn被指定為程序計數(shù)器r15,其值為當前指令地址加8;如果r15被用作偏移地址寄存器Rm的值,指令的執(zhí)行結(jié)果不可預(yù)知。
3.[Rn,#±< offset_8>]!
(1)編碼格式
指令的編碼格式如圖4.26所示。
圖4.26? 雜類內(nèi)存訪問指令——前索引立即數(shù)偏移尋址編碼格式
內(nèi)存地址為基址寄存器Rn加/減立即數(shù)offset_8的值。當指令執(zhí)行的條件<cc>滿足時,生成的地址寫回基址寄存器Rn中。
該尋址方式適合訪問數(shù)組自動進行數(shù)組下標的更新。
(2)語法格式
LDR|STR{<cond>}H|SH|SB|D? <Rd>,[<Rn>,±<offset_8>] !
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <offset_8>為8位立即數(shù),內(nèi)存訪問地址偏移量,在指令編碼格式中被拆為immedH和immedL兩部分;
·? !設(shè)置指令編碼中的W位,更新指令基址寄存器。
(3)操作偽代碼
offset_8 = (immedH) << 4 OR immedL
If? U == 1? then
???? Address = Rn + offset_8
Else
???? Address = Rn – offset_8
If? ConditionPassed{cond}? then
???? Rn = address
(4)說明
① 如果指令中沒有指定立即數(shù),使用[<Rn>],編譯器按[<Rn>,#0] ! 形式編碼。
② 如果Rn被指定為程序計數(shù)器r15,指令的執(zhí)行結(jié)果不可預(yù)知。
?
4.[Rn,±Rm] !
(1)編碼格式
指令的編碼格式如圖4.27所示。
圖4.27? 雜項內(nèi)存訪問指令——前索引寄存器偏移尋址編碼格式
內(nèi)存訪問地址為基址寄存器Rn的值加(或減)偏移寄存器Rm的值。當指令的執(zhí)行條件<cc>滿足時,生成地地址將寫回基址寄存器。
(2)語法格式
LDR|STR{<cond>}H|SH|SB|D? <Rd>,[<Rn>,±<Rm>]
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量;
·? !設(shè)置指令編碼中的W位,更新指令基址寄存器。
(3)操作偽代碼
If? U = = 1? then
???? Address = Rn + Rm
Else
???? Address = Rn – Rm
If? ConditionPassed{cond}? then
???? Rn = address
(4)說明
① 如果Rn和Rm指定為同一寄存器,指令的執(zhí)行結(jié)果不可預(yù)知。
② 如果程序計數(shù)器r15被用作Rm或Rn,則指令的執(zhí)行結(jié)果不可預(yù)知。
5.[Rn],#±< offset_8>
(1)編碼格式
指令的編碼格式如圖4.28所示。
圖4.28? 雜項內(nèi)存訪問指令——后索引立即數(shù)偏移尋址編碼格式
指令使用基址寄存器Rn的值作為實際內(nèi)存訪問地址。當指令的執(zhí)行條件滿足時,將基址寄存器的值加/減偏移量生產(chǎn)新的地址值回寫到Rn寄存器中。
(2)語法格式
LDR|STR{<cond>}H|SH|SB|D? <Rd>,[<Rn>],±<offset_8>
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <offset_8>為8位立即數(shù),內(nèi)存訪問地址偏移量。
(3)操作偽代碼
Address = Rn
Offset_8 = (immedH << 4) OR immedL
If? conditionPassed{cond}? then
???? If? U = = 1 then
????????? Rn = Rn + offset_8
???? Else
????????? Rn = Rn – offset_8
(4)說明
① 當指令中沒有指定立即數(shù)時,匯編器按“[<Rn>],#0”編碼。
② 如果Rn被指定為程序計數(shù)器r15,指令的執(zhí)行結(jié)果不可預(yù)知。
?
6.[Rn],±<Rm>
(1)編碼格式
指令的編碼格式如圖4.29所示。
圖4.29? 雜項內(nèi)存訪問指令——后索引寄存器偏移尋址編碼格式
指令訪問地址為實際的基址寄存器的值。當指令的執(zhí)行條件滿足時,將基址寄存器的值加/減索引寄存器Rm的值回寫到Rn基址寄存器。
(2)語法格式
LDR|STR{<cond>}H|SH|SB|D? <Rd>,[Rn],±<Rm>
其中:
·? Rn為基址寄存器,該寄存器包含內(nèi)存訪問的基地址;
·? <Rm>為偏移地址寄存器,包含內(nèi)存訪問地址偏移量。
(3)操作偽代碼
Address = Rn
If ?conditionPassed{cond}? then
???? If? U = = 1? then
????????? Rn = Rn + Rm
???? Else
????????? Rn = Rn – Rm
(4)說明
① 程序寄存器r15被指定為Rm或Rn,指令的執(zhí)行結(jié)果不可預(yù)知。
② 如果Rm和Rn指定為同一寄存器,指令的執(zhí)行結(jié)果不可預(yù)知。
4.2.3? 批量Load/Store指令尋址方式
批量Load/Store指令將一片連續(xù)內(nèi)存單元的數(shù)據(jù)加載到通用寄存器組中或?qū)⒁唤M通用寄存器的數(shù)據(jù)存儲到內(nèi)存單元中。
批量Load/Store指令的尋址模式產(chǎn)生一個內(nèi)存單元的地址范圍,指令寄存器和內(nèi)存單元的對應(yīng)關(guān)系滿足這樣的規(guī)則,即編號低的寄存器對應(yīng)于內(nèi)存中低地址單元,編號高的寄存器對應(yīng)于內(nèi)存中的高地址單元。
指令的語法格式如下。
LDM|STM{<cond>}<addressing_mode>? <Rn>{!},<registers><^>
指令的尋址方式如表4.6所示。
表4.6????? 批量Load/Store指令的尋址方式
格??? 式 |
模??? 式 |
|
1 |
IA(Increment After) |
后遞增方式 |
2 |
IB(Increment Before) |
先遞增方式 |
3 |
DA(Decrement After) |
后遞減方式 |
4 |
DB(Decrement Before) |
先遞減方式 |
指令的編碼格式如圖4.30所示。
圖4.30? 批量Load/Store指令編碼格式
編碼格式中各標志位的含義如表4.7所示。
表4.7??????? 批量Load/Store指令編碼格式各標志位含義
位標識 |
取??? 值 |
含??? 義 |
P |
P=0 |
Rn包含的地址,是所要訪問的內(nèi)存塊的高地址(U=0)還是低地址(U=1) |
P=1 |
標識Rn所指向的內(nèi)存單元是否被訪問 |
|
U |
U=0 |
Rn所指內(nèi)存單元為所要訪問的內(nèi)存單元塊的高地址 |
U=1 |
Rn所指內(nèi)存單元為所要訪問的內(nèi)存單元塊的低地址 |
|
S |
S=0 |
當程序計數(shù)器PC作為要加載的寄存器之一時,S標識是否將spsr內(nèi)容拷貝到cpsr;對于不加載PC的load指令和所有store指令,S標識特權(quán)模式下,使用用戶模式寄存器組代替當前模式下寄存器組 |
S=1 |
||
W |
W=0 |
數(shù)據(jù)傳送完畢,更新地址寄存器內(nèi)容 |
W=1 |
||
L |
L=0 |
Store指令 |
L=1 |
Load指令 |
?
1.IA尋址
(1)編碼格式
指令的編碼格式如圖4.31所示。
該尋址方式指定一片連續(xù)的內(nèi)存地址空間,地址空間的大小<address_length>等于寄存器列表中寄存器數(shù)目的4倍。內(nèi)存地址范圍起始地址<start_address>等于基址寄存器Rn的值。結(jié)束地址<end_address>等于起始地址<start_address>加上地址空間大小<address_length>。
圖4.31? 批量Load/Store指令——后增加尋址
地址空間中的每個內(nèi)存單元對應(yīng)寄存器列表中的一個寄存器。編號低的寄存器對應(yīng)于內(nèi)存中低地址單元,編號高的寄存器對應(yīng)于內(nèi)存中的高地址單元。
當指令執(zhí)行條件滿足并且指令編碼格式中W位置位,基址寄存器Rn的值等于內(nèi)存地址范圍結(jié)束地址<end_address>加4。
(2)語法格式
LDM|STM{<cond>}IA? <Rn>{!},<registers><^>
其中:
·? IA標識指令使用“后增加”尋址方式;
·? Rn為基址寄存器,包含內(nèi)存訪問的基地址;
·? <registers>為指令操作的寄存器列表;
·? <^>表示如果寄存器列表中包含程序計數(shù)器PC,是否將spsr拷貝到cpsr。
(3)操作偽代碼
Start_address = Rn
End_address = Rn + (Number_of_Set_Bits_In(register_list)*4) – 4
If? conditionPassed(cond) and W = = 1 then
???? Rn = Rn + (Number_of_Set_Bits_In(register_list)*4)
2.DA尋址
(1)編碼格式
指令的編碼格式如圖4.32所示。
圖4.32? 批量Load/Store指令——后遞減尋址
該尋址方式指定一片連續(xù)的內(nèi)存地址空間,地址空間的大小<address_length>等于寄存器列表中寄存器數(shù)目的4倍。內(nèi)存地址范圍起始地址<start_address>等于基址寄存器Rn的值減去地址空間大小<address_length>并加4。結(jié)束地址<end_address>等于基址寄存器的值。
地址空間中的每個內(nèi)存單元對應(yīng)寄存器列表中的一個寄存器。編號低的寄存器對應(yīng)于內(nèi)存中低地址單元,編號高的寄存器對應(yīng)于內(nèi)存中的高地址單元。
當指令執(zhí)行條件滿足并且指令編碼格式中W位置位時,基址寄存器Rn的值等于內(nèi)存地址范圍起始地址<start_address>減4。
(2)語法格式
LDM|STM{<cond>}IA? <Rn>{!},<registers><^>
其中:
·? DA標識指令使用“后遞減”尋址方式;
·? Rn為基址寄存器,包含內(nèi)存訪問的基地址;
·? <registers>為指令操作的寄存器列表;
·? <^>表示如果寄存器列表中包含程序計數(shù)器PC,是否將spsr拷貝到cpsr。
(3)操作偽代碼
Start_address = Rn – (Number_of_Set_Bits_In(register_list)*4) + 4
End_address = Rn
If? conditionPassed(cond) and W = = 1 then
Rn = Rn - (Number_of_Set_Bits_In(register_list)*4)
3.IB尋址
(1)編碼格式
指令的編碼格式如圖4.33所示。
圖4.33? 批量Load/Store指令——前增加尋址
該尋址方式指定一片連續(xù)的內(nèi)存地址空間,地址空間的大小<address_length>等于寄存器列表中寄存器數(shù)目的4倍。內(nèi)存地址范圍起始地址<start_address>等于基址寄存器Rn的值加4。結(jié)束地址<end_address>等于起始地址<start_address>加上地址空間大小<address_length>。
地址空間中的每個內(nèi)存單元對應(yīng)寄存器列表中的一個寄存器。編號低的寄存器對應(yīng)于內(nèi)存中低地址單元,編號高的寄存器對應(yīng)于內(nèi)存中的高地址單元。
當指令執(zhí)行條件滿足并且指令編碼格式中W位置位,基址寄存器Rn的值等于內(nèi)存地址范圍結(jié)束地址<end_address>。
?
(2)語法格式
LDM|STM{<cond>}IB? <Rn>{!},<registers><^>
其中:
·? IB標識指令使用“前增加”尋址方式;
·? Rn為基址寄存器,包含內(nèi)存訪問的基地址;
·? <registers>為指令操作的寄存器列表;
·? <^>表示如果寄存器列表中包含程序計數(shù)器PC,是否將spsr拷貝到cpsr。
(3)操作偽代碼
Start_address = Rn + 4
End_address = Rn + (Number_of_Set_Bits_In(register_list)*4)
If? ConditionPassed(cond) and W= = 1? then
???? Rn = Rn + (Number_Of_Set_Bits_In(register_list)*4)
4.DB尋址
(1)編碼格式
指令的編碼格式如圖4.34所示。
圖4.34? 批量Load/Store指令——前遞減尋址
該尋址方式指定一片連續(xù)的內(nèi)存地址空間,地址空間的大小<address_length>等于寄存器列表中寄存器數(shù)目的4倍。內(nèi)存地址范圍起始地址<start_address>等于基址寄存器Rn的值減地址空間的大小<address_length>。結(jié)束地址<end_address>等于基址寄存器的值減4。
地址空間中的每個內(nèi)存單元對應(yīng)寄存器列表中的一個寄存器。編號低的寄存器對應(yīng)于內(nèi)存中低地址單元,編號高的寄存器對應(yīng)于內(nèi)存中的高地址單元。
當指令執(zhí)行條件滿足并且指令編碼格式中W位置位,基址寄存器Rn的值等于內(nèi)存地址范圍起始地址<address_address>。
(2)語法格式
LDM|STM{<cond>}DB? <Rn>{!},<registers><^>
其中:
·? DB標識指令使用“前遞減”尋址方式;
·? Rn為基址寄存器,包含內(nèi)存訪問的基地址;
·? <registers>為指令操作的寄存器列表;
·? <^>表示如果寄存器列表中包含程序計數(shù)器PC,是否將spsr拷貝到cpsr。
(3)操作偽代碼
Start_address = Rn - (Number_Of_Set_Bits_In(register_list)*4)
End_address = Rn - 4
If? ConditionPassed(cond) and W = = 1? then
???? Rn = Rn – (Number_Of_Set_Bits_In(register_list)*4)
4.2.4? 堆棧操作尋址方式
堆棧操作尋址方式和批量Load/Store指令尋址方式十分類似。但對于堆棧的操作,數(shù)據(jù)寫入內(nèi)存和從內(nèi)存中讀出要使用不同的尋址模式,因為進棧操作(pop)和出棧操作(push)要在不同的方向上調(diào)整堆棧。
下面詳細討論如何使用合適的尋址方式實現(xiàn)數(shù)據(jù)的堆棧操作。
根據(jù)不同的尋址方式,將堆棧分為以下4種。
① Full棧:堆棧指針指向棧頂元素(last used location)。
② Empty棧:堆棧指針指向第一個可用元素(the first unused location)。
③ 遞減棧:堆棧向內(nèi)存地址減小的方向生長。
④ 遞增棧:堆棧向內(nèi)存地址增加的方向生長。
根據(jù)堆棧的不同種類,將其尋址方式分為以下4種。
① 滿遞減FD(Full Descending)。
② 空遞減ED(Empty Descending)。
③ 滿遞增FA(Full Ascending)。
④ 空遞增EA(Empty Ascending)。
注意 |
如果程序中有對協(xié)處理器數(shù)據(jù)的進棧/出棧操作,最好使用FD或EA類型堆棧。這樣可以使用一條STC或LDC指令將數(shù)據(jù)進?;虺鰲?。 |
?
表4.8顯示了堆棧的尋址方式和批量Load/Store指令尋址方式的對應(yīng)關(guān)系。
表4.8???? 堆棧尋址方式和批量Load/Store指令尋址方式對應(yīng)關(guān)系
批量數(shù)據(jù)尋址方式 |
堆棧尋址方式 |
L位 |
P位 |
U位 |
LDMDA |
LDMFA |
1 |
0 |
0 |
LDMIA |
LDMFD |
1 |
0 |
1 |
LDMDB |
LDMEA |
1 |
1 |
0 |
LDMIB |
LDMED |
1 |
1 |
1 |
STMDA |
STMED |
0 |
0 |
0 |
STMIA |
STMEA |
0 |
0 |
1 |
STMDB |
STMFD |
0 |
1 |
0 |
STMIB |
STMFA |
0 |
1 |
1 |
4.2.5? 協(xié)處理器Load/Store尋址方式
協(xié)處理器Load/Store指令的語法格式如下。
<opcode>{<cond>}{L}? <coproc>,<CRd>,<addressing_mode>
表4.9顯示了該類指令的尋址方式。
表4.9?? 協(xié)處理器Load/Store指令尋址方式
格??? 式 |
說??? 明 |
|
1 |
[<Rn>,#±<offset_8>*4] |
立即數(shù)偏移尋址 |
2 |
[<Rn>,#±<offset_8>*4]! |
前索引立即數(shù)偏移尋址 |
3 |
[<Rn>],#±<offset_8>*4 |
后索引立即數(shù)偏移尋址 |
4 |
[<Rn>], <option> |
直接尋址 |
協(xié)處理器Load/Store指令的編碼方式如圖4.35所示。
編碼格式中各標志位的含義如表4.10所示。
圖4.35? 協(xié)處理器Load/Store指令編碼格式
表4.10???? 協(xié)處理器Load/Store指令編碼格式各標志位含義
位? 標? 識 |
取??? 值 |
含??? 義 |
P |
P=0 |
標識使用偏移尋址還是前索引尋址(由W位決定) |
P=1 |
標識使用后索引尋址還是直接尋址(由W位決定) |
|
U |
U=0 |
從基地址中減去偏移量offset |
U=1 |
從基地址中加上偏移量offset |
|
N |
N=0 |
和具體使用的協(xié)處理器相關(guān) |
N=1 |
||
W |
W=0 |
指令執(zhí)行結(jié)束,不改變基址寄存器的值 |
W=1 |
訪問的內(nèi)存地址回寫到基址寄存器 |
|
L |
L=0 |
Store指令 |
L=1 |
Load指令 |
1.[<Rn>,#±<offset_8>*4]
(1)編碼格式
指令的編碼格式如圖4.36所示。
圖4.36? 協(xié)處理器Load/Store指令——立即數(shù)尋址
該尋址方式指定一片連續(xù)的內(nèi)存地址空間。訪問內(nèi)存單元的第一個地址<first_addressing>等于基址寄存器<Rn>的值加上/減去指令中寄存器值的4倍。接下來的內(nèi)存訪問地址是前一個訪問地址加4。當協(xié)處理器發(fā)出傳輸中止信號時,數(shù)據(jù)傳送結(jié)束。
這種尋址方式的數(shù)據(jù)傳輸數(shù)目由協(xié)處理器決定。
注意 |
這種尋址方式最多允許傳輸16的字。 |
?
(2)語法格式
<opcode>{<cond>}{L}? <coproc>,<CRd>,[<Rn>,#±<offset_8>*4]
其中:
·? <Rn>為基址寄存器,包含尋址操作的基地址;
·? <offset_8>為8位立即數(shù),該值的4倍為地址偏移量。
(3)操作偽代碼
If? ConditionPassed(cond)? then
???? If? U = = 1 then
????????? Address = Rn + offset_8 * 4
???? Else? /*U = = 0*/
????????? Address = Rn – offset_8 * 4
???? Start_address = address
???? While (NotFinished(coprocessor[cp_num]))
????????? Address = address +4
???? End_address = address
(4)說明
如果基址寄存器指定為程序計數(shù)器r15,則基地址為當前執(zhí)行指令地址加8。
2.[<Rn>,#±<offset_8>*4]!
(1)編碼格式
指令的編碼格式如圖4.37所示。
圖4.37? 協(xié)處理器Load/Store指令——前索引立即數(shù)尋址
該尋址方式指定一片連續(xù)的內(nèi)存地址空間。訪問內(nèi)存單元的第一個地址<first_addressing>等于基址寄存器<Rn>的值加上/減去指令中寄存器值的4倍。如果指令的條件域滿足,產(chǎn)生的<first_addressing>回寫到基址寄存器Rn中。接下來的內(nèi)存訪問地址是前一個訪問地址加4。當協(xié)處理器發(fā)出傳輸中止信號時,數(shù)據(jù)傳送結(jié)束。
這種尋址方式的數(shù)據(jù)傳輸數(shù)目由協(xié)處理器決定。
注意 |
這種尋址方式最多允許傳輸16的字。 |
(2)語法格式
<opcode>{<cond>}{L}? <coproc>,<CRd>,[<Rn>,#±<offset_8>*4]!
其中:
·? <Rn>為基址寄存器,包含尋址操作的基地址;
·? <offset_8>為8位立即數(shù),該值的4倍為地址偏移量;
·? !設(shè)置指令編碼中的W位,更新指令基地址。
(3)操作偽代碼
If? ConditionPassed(cond)? then
???? If? U = = 1 then
????????? Rn = Rn + offset_8 * 4
???? Else? /*U = = 0*/
????????? Rn = Rn – offset_8 * 4
???? Start_address = Rn
???? Address = start_address
???? While (NotFinished(coprocessor[cp_num]))
????????? Address = address +4
???? End_address = address
(4)說明
如果基址寄存器指定為程序計數(shù)器r15,則指令的執(zhí)行結(jié)果不可預(yù)知。
3.[<Rn>],#±<Offset_8>*4
(1)編碼格式
指令的編碼格式如圖4.38所示。
圖4.38? 協(xié)處理器Load/Store指令——后索引立即數(shù)尋址
該尋址方式指定一片連續(xù)的內(nèi)存地址空間。訪問內(nèi)存單元的第一個地址<first_addressing>等于基址寄存器<Rn>的值。接下來的內(nèi)存訪問地址是前一個訪問地址加4。當協(xié)處理器發(fā)出傳輸中止信號時,數(shù)據(jù)傳送結(jié)束。如果指令的條件域滿足,Rn基址寄存器的值更新為Rn的值加上/減去8位立即數(shù)的4倍。
這種尋址方式的數(shù)據(jù)傳輸數(shù)目由協(xié)處理器決定。
注意 |
這種尋址方式最多允許傳輸16的字。 |
?
(2)語法格式
<opcode>{<cond>}{L}? <coproc>,<CRd>,[<Rn>],#±<offset_8>*4
其中:
·? <Rn>為基址寄存器,包含尋址操作的基地址;
·? <offset_8>為8位立即數(shù),該值的4倍為地址偏移量。
(3)操作偽代碼
If? ConditionPassed(cond)? then
???? Start_address = Rn
???? If? U = = 1 then
????????? Rn = Rn + offset_8 * 4
???? Else? /*U = = 0*/
????????? Rn = Rn – offset_8 * 4
???? Address = start_address
???? While (NotFinished(coprocessor[cp_num]))
????????? Address = address +4
???? End_address = address
(4)說明
如果基址寄存器指定為程序計數(shù)器r15,則指令的執(zhí)行結(jié)果不可預(yù)知。
4.[<Rn>], <Option>
(1)編碼格式
指令的編碼格式如圖4.39所示。
圖4.39? 協(xié)處理器Load/Store指令——直接尋址
該尋址方式指定一片連續(xù)的內(nèi)存地址空間。訪問內(nèi)存單元的第一個地址<first_addressing>等于基址寄存器<Rn>的值。接下來的內(nèi)存訪問地址是前一個訪問地址加4。當協(xié)處理器發(fā)出傳輸中止信號時,數(shù)據(jù)傳送結(jié)束。
指令不更新基址寄存器的值。指令編碼格式中bits[7:0]保留,所以可以將空閑位用作協(xié)處理器指令擴展。
這種尋址方式的數(shù)據(jù)傳輸數(shù)目由協(xié)處理器決定,最多可以傳輸16字。
(2)語法格式
<opcode>{<cond>}{L}? <coproc>,<CRd>,[<Rn>],<Option>
其中:
·? <Rn>為基址寄存器,包含尋址操作的基地址;
·? <option>用作協(xié)處理器指令擴展。
(3)操作偽代碼
If? ConditionPassed(cond)? then
???? Start_address = Rn
???? Address = start_address
???? While (NotFinished(coprocessor[cp_num]))
????????? Address = address +4
???? End_address = address
(4)說明
如果基址寄存器指定為程序計數(shù)器r15,則尋址基地址為當前指令地址加8。