我試圖獲得在C當前堆棧指針時(使用內聯ASM)碰到一些奇怪的行爲。代碼如下:獲取堆棧指針用C在Mac OS X Lion的
$ g++ test.cc -o test
它產生下面的彙編:
#include <stdio.h>
class os {
public:
static void* current_stack_pointer();
};
void* os::current_stack_pointer() {
register void *esp __asm__ ("rsp");
return esp;
}
int main() {
printf("%p\n", os::current_stack_pointer());
}
如果我使用標準的GCC選項編譯代碼
__ZN2os21current_stack_pointerEv:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp,%rbp
0000000000000004 movq %rdi,0xf8(%rbp)
0000000000000008 movq 0xe0(%rbp),%rax
000000000000000c movq %rax,%rsp
000000000000000f movq %rsp,%rax
0000000000000012 movq %rax,0xe8(%rbp)
0000000000000016 movq 0xe8(%rbp),%rax
000000000000001a movq %rax,0xf0(%rbp)
000000000000001e movq 0xf0(%rbp),%rax
0000000000000022 popq %rbp
如果我運行生成的二進制它使用SIGILL(非法指令)崩潰。但是,如果我加一點優化編譯:
$ g++ -O1 test.cc -o test
生成的程序集簡單得多:
0000000000000000 pushq %rbp
0000000000000001 movq %rsp,%rbp
0000000000000004 movq %rsp,%rax
0000000000000007 popq %rbp
0000000000000008 ret
和代碼運行正常。所以對於這個問題,在Mac OS X上有沒有更穩定的從C代碼中獲取堆棧指針?相同的代碼在Linux上沒有問題。
是不是一個_function call_設計得到的堆棧地址基本上註定了設計? – zneak
此外,爲什麼該函數是一個非靜態類方法*?你可能想要一個'this'指針? –
檢查了原始代碼,並將其聲明爲靜態,並且更新了該問題。我只是在做一些現有的代碼。大多數用例使用不等式,所以如果該值稍微偏離,那麼它不是太多問題。對我來說關鍵的問題是非法指令的例外。 –