簡體   English   中英

PC寄存器上的ARM LDR指令

[英]ARM LDR instruction on PC register

我在這里理解這個故事:

  • PC寄存器保存指向下一條指令的指針
  • LDR指令將第二個操作數的值加載到第一個操作數中(例如)
      LDR r0,[pc,0x5678] 
    相當於這個“C代碼”
    \n r0 = *(pc + 0x5678)\n
    它是使用基本偏移量解引用的指針。

我的問題是:

我找到了這段代碼

LDR PC, [PC,-4]

它被評論為猴子修補等。

我如何理解這段代碼

pc = *(pc - 4)

在這種情況下,“pc”寄存器將取消引用前一條指令的地址,並將包含指令的“機器代碼”(不是指令的地址),程序將跳轉到該無效地址繼續執行,可能我們將“分段故障”。 那么我缺少或不理解?



讓我思考的是LDR指令中第二個操作數的括號。 據我所知,x86架構上的括號已經取消引用指針,但我無法理解ARM架構中的含義。

mov r1, 0x5678
add r1, pc
mov r0, [r1]

這段代碼相當於?

LDR r0, [pc, 0x5678]

引自ARM指令集文檔(ARM DDI 0029E)的4.9.4節:

使用R15作為基址寄存器時,必須記住它包含當前指令地址8字節的地址。

因此該指令將加載位於當前指令之后 4個字節的字,該字有望包含有效地址。

由於ARM體系結構的一個怪癖LDR PC, [PC,-4] 以下指令的分支(假設我們在談論ARM,而不是Thumb),因此在正常情況下它沒有效果(性能除外) )。 關鍵是,通過將該指令放在函數的開頭,然后代碼在運行時通過重寫 LDR指令的底部12位來改變偏移,從而非常簡單,從而將該函數重定向到其他地方。 分支到緊跟在指令之后的字中存儲在存儲器中的地址。 Herp derp,我讓ADRLDR混淆了 - 如果它是ADR ,上面的情況就是如此,但這種情況更為直白。

現在我已經失去了自己,這只是一個簡單的函數調用蹦床。 函數地址將緊跟在LDR指令之后存儲為數據字(可能由鏈接器設置為某個初始值),並且可以在運行時簡單地重寫為數據以重定向分支,而無需求助於自修改代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM