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指令從文字池讀出常量。