ldr
首先要判斷我們用的是ldr arm指令還是偽指令。 當我們用的是arm指令時,它的作用不是向寄存器里加載立即數,而是將某個地址里的內容加載到寄存器。而偽指令ldr的作用就是向寄存器里加載立即數。
(1) ldr偽指令
ldr偽指令的格式是 ldr Rn, =expr
其中,expr是要加載到Rn中的內容,一般可以是立即數或者label。
如果expr可以用8bit數據向右移偶數位得到,那么這條偽指令就被編譯器翻譯成mov指令。具體的移位情況可以去查閱資料。反之如果立即數很大,超過了12bit的表示范疇,那么就不能用一條mov指令了,畢竟arm指令最大只有32bit的空間可用(RISC的arm所有的指令長度是一致的,效率較高,當然我們并不關心16bit的thumb指令)。如果不能用一條32bit的指令乘下來,那么就只能另辟蹊徑了,新開一段緩沖,將立即數expr放到里面,然后將其地址(暫時標記為addr)拿來使用:
ldr Rn, addr
xxx (xxx就是expr)
xxx
由于編譯器一般來說新安排的存儲這個立即數expr的緩沖的位置是在相應代碼的附近(這個應該可以控制,好像是使用.ltorg偽指令)。我們從addr地址加載數據到Rn不就可以了。
(2)ldr arm 指令 就是將一個地址的內容加載到寄存器。不能用mov,因為arm里的mov只是在寄存器之間傳輸數據,不支持在寄出器和memory之間傳遞數據。因此就出現了ldr/str指令。如ldr Rn, addr,注意這里的addr的值也是有限制的。這個label應該距離當前指令的距離不超過4k。因為我們知道label在具體使用的時候應該是被翻譯成了相對偏移,如果這個label長度不超過12bit,那么就不應超過4k,我們可以這樣做: ldr pc, _start_armboot _start_armboot: .word arm_startboot 這樣label _start_armboot就在指令下方,因此肯定是合法的。
由于編譯器一般來說新安排的存儲這個立即數expr的緩沖的位置是在相應代碼的附近(這個應該可以控制,好像是使用.ltorg偽指令)。我們從addr地址加載數據到Rn不就可以了。
(2)ldr arm 指令 就是將一個地址的內容加載到寄存器。不能用mov,因為arm里的mov只是在寄存器之間傳輸數據,不支持在寄出器和memory之間傳遞數據。因此就出現了ldr/str指令。如ldr Rn, addr,注意這里的addr的值也是有限制的。這個label應該距離當前指令的距離不超過4k。因為我們知道label在具體使用的時候應該是被翻譯成了相對偏移,如果這個label長度不超過12bit,那么就不應超過4k,我們可以這樣做: ldr pc, _start_armboot _start_armboot: .word arm_startboot 這樣label _start_armboot就在指令下方,因此肯定是合法的。
總結
- 上一篇: 今晚发布!iOS 16 Beta描述文件
- 下一篇: x210 debug口当普通串口使用