日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

匯編語言LDR指令和LDR偽指令詳解_匯編語言

作者:正在起飛的蝸牛 ? 更新時間: 2023-03-19 編程語言

LDR指令和LDR偽指令詳解

ARM32位指令的構成

ARM是RISC結構,數據從內存到CPU之間的移動只能通過LDR/STR指令來完成。 32bit = 指令碼 + 數據。所以32bit的一條指令不可能表示再帶一個32bit的數據,實際只有其中的12bit來表示立即數,其中4bit表示移位的位數(循環右移,且數值x2),8bit用來表示要移位的一個基數。這就產生了非法立即數和合法立即數的問題,經過移位操作,不為零的部分不能用8bit表示的數就是非法立即數。ldr偽指令就是用來解決非法立即數問題的。

ldr指令和ldr偽指令的使用區別:

ldr r0, =0xFFF0 @偽指令
ldr r0, 0xFFFF @指令
直觀的區別就是ldr偽指令使用時,后面的數據前會有"=",實際使用時,大部分都使用偽指令,這樣就不用考慮合法和非法立即數的問題。在編譯的時候,編譯器會將ldr偽指令進行替換,用文字池的方式來解決非法立即數的問題。文字池就是劃分出一段地址空間用來存放常量或者地址,需要時用基址+變址的方式去取數據,這樣就不用受到合法立即數的限制,可以表示32bit的數據。例如:
匯編源代碼:
_start:
ldr r0, =0x11111111
經過反匯編:
00000000 <_start>:
0: e59f009c ldr r0, [pc, #156] ; a4 <delay_loop+0x10>
·
·
·
98: e1520003 cmp r2, r3
9c: 1afffffc bne 94 <delay_loop>
a0: e1a0f00e mov pc, lr
a4: 11111111 tstne r1, r1, lsl r1
分析:
通過反匯編可以看到,ldr偽指令被一條寄存器基址變址指令給替代了。其中以pc為基址,偏移156個字節(16進制是0x9c)。這條指令的作用是將內存地址"pc + 156"開頭的4個字節讀取到r0中,此時pc的值等于當前執行指令的地址+8(因為流水線的原因),因此pc + 156 = 0xa4,而0xa4地址處存的值剛好是0x11111111。這樣就完成了將0x11111111加載到r0。

補充1:

RAM處理器存在流水線,目前已經有十幾級流水線,但是ARM為了兼容,無論Soc有多少級流水線,PC的值都是等于當前指令地址 + 8。PC = 當前指令地址 + 8, 記住就行。

補充2:

匯編語言ldr偽指令

偽指令是用來自動拆分代碼值的,會把一條語句拆分成多條語句。

示例:

/* 匯編點亮一個 LED 燈 */

.text
.global _start

_start:
    ldr r1, =0x56000050
    ldr r0, =0x100  /* 相當于 mov r0, #0x100 */
    str r0, [r1]

    ldr r1, =0x56000054
    ldr r0, =0 /* mov r0, #0 */
    str r0, [r1]

halt:
    b halt

ldr r1, =0x56000054就是一條偽指令,假設我們想把56000054值給r1寄存器,可以用 mov r1, #56000050 ,
但是長度超出了mov 能接收的長度,就要分為高低字節去發送,但是在某些時候我們還要去看開放文檔,才能知道
或者沒有開發文檔,那就讓偽指令自己去判斷。

原文鏈接:https://blog.csdn.net/weixin_42031299/article/details/114749604

欄目分類
最近更新