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