2016-10-16 41 views
0

我试图在Linux上运行该代码,看看会发生什么:为什么我会得到一个无条件跳转的SIGSEGV?

int fn(void) { return 0; } 
int main(void) { __asm__("jmp fn;"); } 

我看不出有任何理由要执行由SIGSEGV终止,但是这就是我得到的。我预计流程将被重定向到_start,因为堆栈在mainfn之内没有任何修改,并且激活记录中的返回地址仍应该是“可用的”。

你能解释一下这是什么吗?

+0

'因为堆栈没有以任何方式修改主'这是不正确的。看看汇编代码。 – tkausl

+0

这是因为当你到达fn()的末尾时,它会从堆栈中弹出返回地址,但是之前没有被推到那里,因为你“跳”到那里而不是“调用”那里。 – BrunoLevy

+0

生成程序集输出并查看它。 –

回答

4

return 0产生类似

mov $0x0, %eax 
ret 

其中ret从栈中弹出返回地址并跳转那里。简单的jmp不会推送任何返回地址,因此ret会弹出堆栈上的任何内容。

+0

更具体地说,他想用'call'来代替'jmp',事情将按预期工作。 – danem

相关问题