[英]ARM LDR instruction on PC register
我在這里理解這個故事:
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),因此在正常情況下它沒有效果(性能除外) )。
關鍵是,通過將該指令放在函數的開頭,然后代碼在運行時通過重寫
分支到緊跟在指令之后的字中存儲在存儲器中的地址。 Herp derp,我讓LDR
指令的底部12位來改變偏移,從而非常簡單,從而將該函數重定向到其他地方。
ADR
和LDR
混淆了 - 如果它是ADR
,上面的情況就是如此,但這種情況更為直白。
現在我已經失去了自己,這只是一個簡單的函數調用蹦床。 函數地址將緊跟在LDR
指令之后存儲為數據字(可能由鏈接器設置為某個初始值),並且可以在運行時簡單地重寫為數據以重定向分支,而無需求助於自修改代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.