我正在編寫代碼以臨時使用我自己的堆棧進行實驗。當我使用文字內聯彙編時,這工作。我將變量位置硬編碼爲ebp的偏移量。不過,我希望我的代碼能夠在不需要硬編碼內存地址的情況下工作,所以我一直在尋找GCC的擴展聯機彙編。我有以下幾點:
volatile intptr_t new_stack_ptr = (intptr_t) MY_STACK_POINTER;
volatile intptr_t old_stack_ptr = 0;
asm __volatile__("movl %%esp, %0\n\t"
"movl %1, %%esp"
: "=r"(old_stack_ptr) /* output */
: "r"(new_stack_ptr) /* input */
);
這樣做的關鍵是首先將堆棧指針保存到變量old_stack_ptr中。接下來,堆棧指針(%esp)被我保存在new_stack_ptr中的地址覆蓋。
儘管如此,我發現GCC正在將%esp保存到old_stack_ptr中,但並未用new_stack_ptr替換%esp。在更深入的考察,我發現它實際上擴大了我的組裝和增加它自己的指令,它有以下幾種:
mov -0x14(%ebp),%eax
mov %esp,%eax
mov %eax,%esp
mov %eax,-0x18(%ebp)
我認爲GCC試圖ESP保存%,因爲我沒有做到這一點明確的聲明爲一個「輸出」操作數...我可能是完全錯誤的...
我真的想用擴展內聯彙編做到這一點,因爲如果不是這樣,似乎我必須「硬編碼」的位置從%ebp偏移到程序集中,我寧願使用像這樣的變量名...尤其是因爲此代碼需要在幾個不同的系統上工作,這似乎都以不同的方式偏移了我的變量,因此使用擴展內聯程序集讓我明白Ÿ說變量的位置......但我不明白爲什麼它正在做額外的東西,而不是讓我像以前一樣覆蓋堆棧指針,自從我開始使用擴展裝配以來,它一直在這樣做。
我感謝任何幫助!
不知道這是否有幫助,但'-fomit-frame-pointer'(用'-O1'啓用)會消除「%ebp」的問題。 – DaoWen
額外的東西可能在那裏,因爲你正在做一個調試(沒有優化)構建和GCC默認情況下它捕捉潛在的錯誤。搜索「GCC Stack Frame Checks」查看GCC提供的選項。 – Skizz