<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > ARM微處理器寄存器裝載和存儲

ARM微處理器寄存器裝載和存儲

作者: 時(shí)間:2016-11-09 來(lái)源:網(wǎng)絡(luò ) 收藏

傳送單一數據

使用單一數據傳送指令(STR 和 LDR)來(lái)裝載和存儲單一字節或字的數據從/到內存。尋址是非常靈活的。

本文引用地址:http://dyxdggzs.com/article/201611/317639.htm

首先讓我們查看指令格式:

LDR{條件}    Rd, <地址>STR{條件}    Rd, <地址>LDR{條件}B   Rd, <地址>STR{條件}B   Rd, <地址>
指令格式

這些指令裝載和存儲 Rd 的值從/到指定的地址。如果象后面兩個(gè)指令那樣還指定了‘B’,則只裝載或存儲一個(gè)單一的字節;對于裝載,寄存器中高端的三個(gè)字節被置零(zeroed)。

地址可以是一個(gè)簡(jiǎn)單的值、或一個(gè)偏移量、或者是一個(gè)被移位的偏移量??梢赃€可以把合成的有效地址寫(xiě)回到基址寄存器(去除了對加/減操作的需要)。

各種尋址方式的示例: 

譯注:下文中的 Rbase 是表示基址寄存器,Rindex 表示變址寄存器,index 表示偏移量,偏移量為 12 位的無(wú)符號數。用移位選項表示比例因子。標準尋址方式 - 用 AT&T 語(yǔ)法表示為 disp(base, index, scale),用 Intel 語(yǔ)法表示為 [base + index*scale + disp],中的變址(連帶比例因子)與偏移量不可兼得。

STR    Rd, [Rbase]          存儲 Rd 到 Rbase 所包含的有效地址。STR    Rd, [Rbase, Rindex]  存儲 Rd 到 Rbase + Rindex 所合成的有效地址。 STR    Rd, [Rbase, #index]  存儲 Rd 到 Rbase + index 所合成的有效地址。index 是一個(gè)立即值。例如,STR Rd, [R1, #16] 將把 Rd 存儲到 R1+16。STR    Rd, [Rbase, Rindex]! 存儲 Rd 到 Rbase + Rindex 所合成的有效地址,并且把這個(gè)新地址寫(xiě)回到 Rbase。STR    Rd, [Rbase, #index]! 存儲 Rd 到 Rbase + index 所合成的有效地址,并且并且把這個(gè)新地址寫(xiě)回到 Rbase。STR    Rd, [Rbase], Rindex  存儲 Rd 到 Rbase 所包含的有效地址。把 Rbase + Rindex 所合成的有效地址寫(xiě)回 Rbase。STR    Rd, [Rbase, Rindex, LSL #2] 存儲 Rd 到 Rbase + (Rindex * 4) 所合成的有效地址。STR    Rd, place            存儲 Rd 到 PC + place 所合成的有效地址。
你當然可以在這些指令上使用條件執行。但要注意條件標志要先于字節標志,所以如果你希望在結果是等于的時(shí)候裝載一個(gè)字節,要用的指令是LDREQB Rx, (不是LDRBEQ...)。

如果你指定預先變址尋址(這里的基址和變址都在方括號中),用是否存在‘!’來(lái)控制寫(xiě)回操作。上面的第4和第5個(gè)例子中使用了這個(gè)標志。你可以使用它來(lái)在內存中自動(dòng)正向或反向移動(dòng)。一個(gè)字符串打印例程將變成:

.loopLDRB   R0, [R1, #1]!SWI    "OS_WriteC"CMP    R0, #0BNE    loop
而不是:
.loopLDRB   R0, [R1]SWI    "OS_WriteC"ADD    R1, R1, #1CMP    R0, #0BNE    loop

對于過(guò)后變址尋址‘!’是無(wú)效的(這里的變址在方括號外面,比如上面的例子6),因為寫(xiě)回是暗含的。

如同你見(jiàn)到的那樣,變址可以被移位來(lái)實(shí)現比例縮放。除此之外,可以從基址上減去偏移量。在這種情況下,你可以使用如下代碼:

LDRB   R0, [R1, #-1]

盡管你可以存儲或裝載 PC,但你不可以用裝載或存儲指令來(lái)修改 PSR。要裝載一個(gè)被存儲的‘狀態(tài)’并正確的恢復它,請使用:

LDR    R0, [Rbase]MOVS   R15, R0
假如你在有特權的模式下,MOVS 將導致 PSR 的位被更改。
對 PC 使用MOVS不遵從 32-bit 體系,你需要使用 MRS 和 MSR 來(lái)處理 PSR。

依照 ARM 匯編手冊:

譯注:下文所敘述內容針對的是小端字節序配置,對大端字節序配置在手冊中另有專(zhuān)門(mén)敘述。

  • 如果提供的地址在一個(gè)字邊界上,則字節裝載(LDRB)使用在 0 至 7 位上的數據,如果在一個(gè)字地址加上一個(gè)字節上,則使用 8 至 15 位,以此類(lèi)推。選擇的字節被放入目標寄存器的低端 8 位中,并把寄存器中其余的位用零填充。
  • 字節存儲(STRB)在數據總線(xiàn)上重復源寄存器的的低端 8 位 4 次。由外部的內存系統來(lái)激活適當的字節子系統來(lái)存儲數據。
  • 字裝載(LDR)或字存儲(STR)將生成一個(gè)字對齊的地址。使用一個(gè)非字對齊的地址將有不明顯和未規定的結果。實(shí)際上提示的是你不能使用 LDR 從一個(gè)非對齊的地址裝載一個(gè)字。

 

傳送多個(gè)數據

使用多數據傳送指令(LDM 和 STM)來(lái)裝載和存儲多個(gè)字的數據從/到內存。

LDM/STM 的主要用途是把需要保存的寄存器到棧上。如我們以前見(jiàn)到過(guò)的STMFD R13!, {R0-R12, R14}。

指令格式是:

xxM{條件}{類(lèi)型}  Rn{!}, <寄存器列表>{^}

‘xx’是 LD 表示裝載,或 ST 表示存儲。

再加 4 種‘類(lèi)型’就變成了 8 個(gè)指令:

棧        其他LDMED     LDMIB     預先增加裝載LDMFD     LDMIA     過(guò)后增加裝載LDMEA     LDMDB     預先減少裝載LDMFA     LDMDA     過(guò)后減少裝載 STMFA     STMIB     預先增加存儲STMEA     STMIA     過(guò)后增加存儲STMFD     STMDB     預先減少存儲STMED     STMDA     過(guò)后減少存儲
指令格式

匯編器關(guān)照如何映射這些助記符。注意 ED 不同于 IB;只對于預先減少裝載是相同的。在存儲的時(shí)候,ED 是過(guò)后減少的。

FD、ED、FA、和 EA 指定是滿(mǎn)棧還是空棧,是升序棧還是降序棧。一個(gè)滿(mǎn)棧的棧指針指向上次寫(xiě)的最后一個(gè)數據單元,而空棧的棧指針指向第一個(gè)空閑單元。一個(gè)降序棧是在內存中反向增長(cháng)(就是說(shuō),從應用程序空間結束處開(kāi)始反向增長(cháng))而升序棧在內存中正向增長(cháng)。

其他形式簡(jiǎn)單的描述指令的行為,意思分別是過(guò)后增加(Increment After)、預先增加(Increment Before)、過(guò)后減少(Decrement After)、預先減少(Decrement Before)。

RISC OS 使用傳統的滿(mǎn)降序棧。在使用符合 APCS 規定的編譯器的時(shí)候,它通常把你的棧指針設置在應用程序空間的結束處并接著(zhù)使用一個(gè) FD (滿(mǎn)降序 - Full Descending)棧。如果你與一個(gè)高級語(yǔ)言(BASIC 或 C)一起工作,你將別無(wú)選擇。棧指針(傳統上是 R13)指向一個(gè)滿(mǎn)降序棧。你必須繼續這個(gè)格式,或則建立并管理你自己的棧(如果你是死硬派人士那么你可能喜歡這樣做!)。

‘基址’是包含開(kāi)始地址的寄存器。在傳統的 RISC OS 下,它是棧指針 R13,但你可以使用除了 R15 之外的任何可獲得的寄存器。

如果你想把操作后棧頂的當前的內存地址保存到棧指針中,可以簡(jiǎn)單的在棧指針寄存器后面設置一個(gè)寫(xiě)回標志‘!’。

寄存器列表放在{花括號}中。不管你用什么次序在其中指定寄存器,寄存器按從最低到最高的編號次序與到從低端到高端的內存之間傳送數據。并且因為用指令中的一個(gè)單一的位來(lái)表示是否保存一個(gè)寄存器,不可能指定某個(gè)寄存器兩次。它的副作用是不能用下面這樣的代碼:

STMFD  R13!, {R0, R1}LDMFD  R13!, {R1, R0}
來(lái)交換兩個(gè)寄存器的內容。

提供了一個(gè)有用的簡(jiǎn)寫(xiě)。要包含一個(gè)范圍的寄存器,可以簡(jiǎn)單的只寫(xiě)第一個(gè)和最后一個(gè),并在其間加一個(gè)橫杠。例如R0-R3等同與R0, R1, R2, R3,只是更加整齊和理智而已...

在把 R15 存儲到內存中的時(shí)候,還保存了 PSR 位。在重新裝載 R15 的時(shí)候,除非你要求否則不恢復 PSR 位。要求的方法是在寄存器列表后跟隨一個(gè)‘^’?!?/p>

STMFD  R13!, {R0-R12, R14}...LDMFD  R13!, {R0-R12, PC}
這保存所有的寄存器,做一些事情,接著(zhù)重新裝載所有的寄存器。從 R14 裝載 PC,它由一個(gè) BL 或此類(lèi)指令所設置。不觸及 PSR 標志?!?pre>STMFD R13!, {R0-R12, R14}...LDMFD R13!, {R0-R12, PC}^這保存所有的寄存器,做一些事情,接著(zhù)重新裝載所有的寄存器。從 R14 裝載 PC,它由一個(gè) BL 或此類(lèi)指令所設置。變更 PSR 標志。
警告: 這些代碼不遵從 32 bit 體系。你需要使用 MRS 和 MSR 來(lái)處理 PSR,你不能使用‘^’后綴。

注意在這兩個(gè)例子中,R14 被直接裝載到 PC 中。這節省了對 MOV(S) R14 到 R15 中的需要。
警告: 使用 MOVS PC,... 不遵從 32 bit 體系。你需要使用 MRS 和 MSR 來(lái)處理 PSR。

 

SWP : 單一數據交換

(Swap)

SWP{條件}{B}  , , []
指令格式

SWP將:

  • 從操作數 2 所指向的內存裝載一個(gè)字并把這個(gè)字放置到目的寄存器中。
  • 把寄存器操作數 1 的內容存儲到同一個(gè)地址中。
如果目的和操作數 1 是同一個(gè)寄存器,則把寄存器的內容和給定內存位置的內容進(jìn)行交換。
如果提供了B后綴,則將傳送一個(gè)字節,否則傳送一個(gè)字。


評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>