天天看點

ARM指令LDR和ARM僞指令LDR

LDR僞指令的形式是“LDR Rn,=expr”,例: COUNT EQU 0x40003100 ……

LDR R1,=COUNT

MOV R0,#0

STR R0,[R1] COUNT是我們定義的一個變量,位址為0x40003100。這種定義方法在彙編語言中是很常見的。

LDR R1,=COUNT是将COUNT這個變量的位址,也就是0x40003100放到R1中。

MOV R0,#0是将立即數0放到R0中。

最後一句STR R0,[R1]是一個典型的存儲指令,将R0中的值放到以R1中的值為位址的存儲單元去。

實際就是将0放到位址為0x40003100的存儲單元中去。可見這三條指令是為了完成對變量COUNT指派。

用三條指令來完成對一個變量的指派,看起來有點不太舒服。這可能跟ARM的采用RISC有關。

下面還有一個例子 ;将COUNT的值賦給R0

LDR R1,=COUNT

LDR R0,[R1] 這條指令實際上會編譯成一條LDR指令和一條 DCD僞指令。     ARM指令LDR和ARM僞指令LDR有什麼差別 僞指令LDR{cond} register, ={expr|label-expr}

expr為32為常量。編譯器根據expr的取值情況來處理這條僞指令:

1、當expr表示的位址沒有超過mov或mvn指令中位址的取值範圍時,編譯器用合适的mov指令或mvn指令代替該LDR僞指令。

2、當expr表示的位址超過了mov或mvn指令中位址的取值範圍時,編譯器将該常數放在緩沖區中,同時用一條基于PC的LDR指令讀取該常數。 由于arm是risc精簡指令集,指令都是32位的,在編碼中操作碼,目标和源寄存器是要占掉32位一部分,

是以一條指令裡面不可能存一個32位的立即數,是以arm提供了一條僞指令來完成一條指令load一個32位的立即數。

方法是在這條指令附近放要load的值,再利用目前的pc+偏移load這個數,注意ldr的原來的意義是将記憶體的某個值load到寄存器裡面。

比如:

ldr r0, =0x5000010

經過arm的assembler的翻譯實際上就是:

ldr r0, [pc+#0x4] ;;指令是4byte 32位,就是将記憶體中下一個word放到r0中

0x500010 ;;這個地方放的是數值。這裡,0x4是在它立即數的範圍内的   arm指令中mov和ldr的差別

ARM是RISC結構,資料從記憶體到CPU之間的移動隻能通過L/S指令來完成,也就是ldr/str指令。

比如想把資料從記憶體中某處讀取到寄存器中,隻能使用ldr

比如:

ldr r0, 0x12345678

就是把0x12345678這個位址中的值存放到r0中。

而mov不能幹這個活,mov隻能在寄存器之間移動資料,或者把立即數移動到寄存器中,

這個和x86這種CISC架構的晶片差別最大的地方。

x86中沒有ldr這種指令,因為x86的mov指令可以将資料從記憶體中移動到寄存器中。

另外還有一個就是ldr僞指令,雖然ldr僞指令和ARM的ldr指令很像,但是作用不太一樣。

ldr僞指令可以在立即數前加上=,以表示把一個位址寫到某寄存器中,比如:

ldr r0, =0x12345678

這樣,就把0x12345678這個位址寫到r0中了。是以,ldr僞指令和mov是比較相似的。隻不過mov指令限制了立即數的長度為8位,

也就是不能超過512。而ldr僞指令沒有這個限制。如果使用ldr僞指令時,後面跟的立即數沒有超過8位,那麼在實際彙編的時候

該ldr僞指令是被轉換為mov指令的。

ldr僞指令和ldr指令不是一個同東西。  

ARM僞指令之位址讀取:ADR ADRL LDR 1、ADR僞指令--- 小範圍的位址讀取      ADR僞指令将基于PC相對偏移的位址值或基于寄存器相對偏移的位址值讀取到寄存器中。在彙編編譯器編譯源程式時,ADR僞指令被編譯器替換成一條合适的指令。通常,編譯器用一條ADD指令或SUB指令來實作該ADR僞指令的功能,若不能用一條指令實作,則産生錯誤,編譯失敗。 ADR僞指令格式 :ADR{cond}   register, expr 位址表達式expr的取值範圍:     當位址值是位元組對齊時,其取指範圍為: +255 ~ 255B;     當位址值是字對齊時,其取指範圍為:   -1020 ~ 1020B; 2、ADRL僞指令----中等範圍的位址讀取 ADRL僞指令将基于PC相對偏移的位址值或基于寄存器相對偏移的位址值讀取到寄存器中,比ADR僞指令可以讀取更大範圍的位址。在彙編編譯器編譯源程式時,ADRL僞指令被編譯器替換成兩條合适的指令。若不能用兩條指令實作,則産生錯誤,編譯失敗。 ADRL僞指令格式:ADRL{cond}   register, expr 位址表達式expr的取值範圍:     當位址值是位元組對齊時,其取指範圍為: -64K~64K;    當位址值是字對齊時,其取指範圍為:   -256K~256K; 3、LDR僞指令-----大範圍的位址讀取 LDR 僞指令用于加載32位的立即數或一個位址值到指定寄存器。在彙編編譯源程式時,LDR僞指令被編譯器替換成一條合适的指令。若加載的常數未超出MOV或 MVN的範圍,則使用MOV或MVN指令代替該LDR僞指令,否則彙編器将常量放入文字池,并使用一條程式相對偏移的LDR指令從文字池讀出常量。

繼續閱讀