2014-02-07 20 views
0

我正在使用內聯彙編執行跳遠的程序。據我的理解,我所需要做的就是將FP和PC更換爲保存的FP和PC。使用程序集,我可以更改幀指針(%ebp),但是我無法將它指向PC。將程序計數器(PC)修改爲保存的地址

int jump(int x) 
{ 
    int oldFP = getebp(); //the FP of the calling function 
    int oldPC = getebp()+4; //the PC of the calling function 

    ljump(); //uses assembly to change FP (works) but can't figure out PC 

    return x; 
} 

和我ljump()

ljump: # return stack frame pointer FP 
     movl savedFP, %ebp 
     ret 

我以前嘗試PC已經使用跳變,但是我通常會得到一個分割錯誤。

任何輸入,將不勝感激。

+0

不知道答案是什麼,但你可以看看如何爲你的平臺實現'setjmp'和'longjmp'並嘗試類似的東西。 –

+1

不是試圖重新實現'longjmp',而是使用'longjmp'。非局部轉移比看起來更難。最好讓運行時庫爲你做。它瞭解非本地轉移的各種ABI要求。 (在x86上,您還需要恢復非易失性寄存器。) –

+0

感謝您的建議。我查看了longjmp的源代碼,但是很難讀到它。改變幀指針是很容易的,而且工作正常,但改變PC已被證明是更困難的方式 – Kosz

回答

1

如果你希望你的代碼繼續就一些預定義的地址,你可以做這樣的在你的彙編代碼(僞代碼):

push myNewAddress 
ret 

,或者如果你喜歡它不同的方式被使用寄存器:

mov eax, myNewAddress 
jmp eax 

您不能直接用指令修改PC,因爲它總是在當前指令所在的位置。但是,您應該意識到這可能會導致內存泄漏或其他副作用,因爲可能無法正確處理堆棧。

+0

謝謝!不幸的是,當試圖跳轉時,我不斷收到「分段錯誤」,但我認爲你在正確的軌道 – Kosz

+0

你試過了哪一個?如果你使用'ret',那麼檢查你是否有正確的push和ret的指令大小。 – Devolus