僞指令LDR和ADR的分析

在ARM彙編程序中,就經常使用到LDR和ADR這兩條僞指令,現在對這兩條僞指令進行分析,歡迎大家指正。

 在資料中,ADR的定義爲:小範圍的地址讀取僞指令,ADR指令將基於PC相對偏移的地址值讀取到寄存器中,在編譯源程序時ADR僞指令被編譯器 替換成一條合適的指令。通常,編譯器用一條ADD指令或SUB指令來實現該ADR僞指令的功能,若不能用一條指令實現,剛產生錯誤。

在如上的定義中,有兩個關鍵信息:⑴將基於PC相對偏移的地址值讀取到寄存器中;⑵被編譯器替換成一條合適的指令。ADR指令只能將地址值讀取到寄存器中,而不能是其它的立即數,並用只能用一條指令。

如果在彙編程序中使用ADR R1,ResetHandel語句,其中ResetHandel是彙編程序中的一個標籤,此條僞指令的作用是把ResetHandel標籤所在的指令地址 讀取到寄存器R0中。當彙編器對此條僞指令進行編譯的時候,將會編譯成機器碼:0xE28F100C,轉換成二進制就是1110 0010 1000 1111 0001 0000 0000 1100,下面對這個機器碼進行分析:

 

 

 

根據上面的分析,可以看到,編譯器在編譯的時候把ADR僞指令編譯成一個ADD R1,PC,Immediate指令,其中Immediate是一個立即數,數值是ResetHandel語句和此條僞指令之間的差值,由編譯器自動算 出。由於立即數尋址的約束,這個Immediate存在一定的約束,所以會出現定義中所說的不能用一條指令實現。

LDR說的定義爲:大範圍地址讀取僞指令,LDR僞指令用於加載32們的立即數或一個地址值到指定寄存器。在彙編編譯源程序時,LDR僞指令被編譯 器替換成一條合適的指令。若加載的常數未超出MOV或者MVN的範圍,剛使用MOV或MVN指令代替該LDR僞指令,否則彙編器將常量放入字池,並使用一 條程序相對偏移的LDR指令從文字池讀出常量。

與ARM指令的LDR相比,僞指令的LDR的參數有"="號。

在如上的定義中,有三個關鍵信息:⑴用於加載32們的立即數或一個地址值到指定寄存器;⑵被編譯器替換成一條合適的指令;⑶優先使用MOV或MVN指令代替該指令。

如果使用MOV指令,那就使用立即數尋址的方式,但是立即數尋址存在一個範圍白約束,所以不是所以的常數都可以使用立即數尋址白方式。當不能使用立 即數尋址方式時,就把常量放入文字池,使用一條程序相對於PC尋址的LDR指令把文字池的內容讀取到寄存器中。立即數和地址值的操作方式是一樣的。

如果有僞指令:LDR R0,=0x123456。那編譯器在編譯該僞指令的時候將會編譯成機器碼:1110 0101 1001 1111 0000 0000 0001 0100,下面對這個機器碼進行分析:

 

 

由上面分析可知,僞指令LDR R0,=0x123456其實就是被編譯成LDR R0,[PC,Immediate]。其中立即數0x123456被儲存在一個文字池中,他的地址和指令LDR R0,[PC,Immediate]的地址之前差了Immediate。因此指令LDR R0,[PC,Immediate]就可以把立即數0x123456讀取到R0中了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章