ARM指令集中,LDR通常都是作載入指令的,但是它也可以作偽指令。LDR偽指令的形式是“LDRRn,=expr”。下面舉一個例子來說明它的用法。COUNTEQU0x40003100……LDRR1,=COUNTMOVR0,#0STRR0,[R1]COUNT是我們定義的一個變數,地址為0x40003100。這中定義方法在組合語言中是很常見的,如果使用過微控制器的話,應該都熟悉這種用法。LDRR1,=COUNT是將COUNT這個變數的地址,也就是0x40003100放到R1中。MOVR0,#0是將立即數0放到R0中。最後一句STRR0,[R1]是一個典型的儲存指令,將R0中的值放到以R1中的值為地址的儲存單元去。實際就是將0放到地址為0x40003100的儲存單元中去。可見這三條指令是為了完成對變數COUNT賦值。用三條指令來完成對一個變數的賦值,看起來有點不太舒服。這可能跟ARM的採用RISC有關。下面還有一個例子:將COUNT的值賦給R0LDRR1,=COUNT;這條偽指令,是將COUNT的地址賦給R1LDRR0,[R1];將COUNT的值賦給R0ARM是RISC結構,資料從記憶體到CPU之間的移動只能透過LDR/STR指令來完成。比如想把資料從記憶體中某處讀取到暫存器中,只能使用LDR,比如:ldrr0,0x12345678;就是把0x12345678這個地址中的值存放到r0中。而mov不能幹這個活,mov只能在暫存器之間移動資料,或者把立即數移動到暫存器中,這個和x86這種CISC架構的晶片區別最大的地方。x86中沒有ldr這種指令,因為x86的mov指令可以將資料從記憶體中移動到暫存器中。MOV是從一個暫存器或者移位的暫存器或者立即數的值傳遞到另外一個暫存器。從本質上是暫存器到暫存器的傳遞,為什麼會有立即數,其實也是有限制的立即數,不是所有立即數都可以傳遞的這個立即數要符合一個8位數迴圈右移偶數位的取值。原因是,MOV本身就是一條32bit指令,除了指令碼本身,它不可能再帶一個可以表示32bit的數字,所以用了其中的12bit來表示立即數,其中4bit表示移位的位數(迴圈右移,且數值x2),8bit用來表示要移位的一個基數。另外還有一個就是ldr偽指令,雖然ldr偽指令和ARM的ldr指令很像,但是作用不太一樣。ldr偽指令可以在立即數前加上=,以表示把一個地址寫到某暫存器中,比如:ldrr0,=0x12345678這樣,就把0x12345678這個地址寫到r0中了。所以,ldr偽指令和mov是比較相似的。只不過mov指令限制了立即數的長度為8位,也就是不能超過512。而ldr偽指令沒有這個限制。如果使用ldr偽指令時,後面跟的立即數沒有超過8位,那麼在實際彙編的時候該ldr偽指令是被轉換為mov指令的。總結:偽指令LDR{cond}register,={expr|label-expr}expr為32為常量。編譯器根據expr的取值情況來處理這條偽指令:1、當expr表示的地址沒有超過mov或mvn指令中地址的取值範圍時,編譯器用合適的mov指令或mvn指令代替該LDR偽指令。2、當expr表示的地址超過了mov或mvn指令中地址的取值範圍時,編譯器將該常數放在緩衝區中,同時用一條基於PC的LDR指令讀取該常數。
ARM指令集中,LDR通常都是作載入指令的,但是它也可以作偽指令。LDR偽指令的形式是“LDRRn,=expr”。下面舉一個例子來說明它的用法。COUNTEQU0x40003100……LDRR1,=COUNTMOVR0,#0STRR0,[R1]COUNT是我們定義的一個變數,地址為0x40003100。這中定義方法在組合語言中是很常見的,如果使用過微控制器的話,應該都熟悉這種用法。LDRR1,=COUNT是將COUNT這個變數的地址,也就是0x40003100放到R1中。MOVR0,#0是將立即數0放到R0中。最後一句STRR0,[R1]是一個典型的儲存指令,將R0中的值放到以R1中的值為地址的儲存單元去。實際就是將0放到地址為0x40003100的儲存單元中去。可見這三條指令是為了完成對變數COUNT賦值。用三條指令來完成對一個變數的賦值,看起來有點不太舒服。這可能跟ARM的採用RISC有關。下面還有一個例子:將COUNT的值賦給R0LDRR1,=COUNT;這條偽指令,是將COUNT的地址賦給R1LDRR0,[R1];將COUNT的值賦給R0ARM是RISC結構,資料從記憶體到CPU之間的移動只能透過LDR/STR指令來完成。比如想把資料從記憶體中某處讀取到暫存器中,只能使用LDR,比如:ldrr0,0x12345678;就是把0x12345678這個地址中的值存放到r0中。而mov不能幹這個活,mov只能在暫存器之間移動資料,或者把立即數移動到暫存器中,這個和x86這種CISC架構的晶片區別最大的地方。x86中沒有ldr這種指令,因為x86的mov指令可以將資料從記憶體中移動到暫存器中。MOV是從一個暫存器或者移位的暫存器或者立即數的值傳遞到另外一個暫存器。從本質上是暫存器到暫存器的傳遞,為什麼會有立即數,其實也是有限制的立即數,不是所有立即數都可以傳遞的這個立即數要符合一個8位數迴圈右移偶數位的取值。原因是,MOV本身就是一條32bit指令,除了指令碼本身,它不可能再帶一個可以表示32bit的數字,所以用了其中的12bit來表示立即數,其中4bit表示移位的位數(迴圈右移,且數值x2),8bit用來表示要移位的一個基數。另外還有一個就是ldr偽指令,雖然ldr偽指令和ARM的ldr指令很像,但是作用不太一樣。ldr偽指令可以在立即數前加上=,以表示把一個地址寫到某暫存器中,比如:ldrr0,=0x12345678這樣,就把0x12345678這個地址寫到r0中了。所以,ldr偽指令和mov是比較相似的。只不過mov指令限制了立即數的長度為8位,也就是不能超過512。而ldr偽指令沒有這個限制。如果使用ldr偽指令時,後面跟的立即數沒有超過8位,那麼在實際彙編的時候該ldr偽指令是被轉換為mov指令的。總結:偽指令LDR{cond}register,={expr|label-expr}expr為32為常量。編譯器根據expr的取值情況來處理這條偽指令:1、當expr表示的地址沒有超過mov或mvn指令中地址的取值範圍時,編譯器用合適的mov指令或mvn指令代替該LDR偽指令。2、當expr表示的地址超過了mov或mvn指令中地址的取值範圍時,編譯器將該常數放在緩衝區中,同時用一條基於PC的LDR指令讀取該常數。