为什么我会得到一个无条件跳转的SIGSEGV?
问题描述:
我试图在Linux上运行该代码,看看会发生什么:为什么我会得到一个无条件跳转的SIGSEGV?
int fn(void) { return 0; }
int main(void) { __asm__("jmp fn;"); }
我看不出有任何理由要执行由SIGSEGV终止,但是这就是我得到的。我预计流程将被重定向到_start
,因为堆栈在main
和fn
之内没有任何修改,并且激活记录中的返回地址仍应该是“可用的”。
你能解释一下这是什么吗?
答
return 0
产生类似
mov $0x0, %eax
ret
其中ret
从栈中弹出返回地址并跳转那里。简单的jmp
不会推送任何返回地址,因此ret
会弹出堆栈上的任何内容。
+0
更具体地说,他想用'call'来代替'jmp',事情将按预期工作。 – danem
'因为堆栈没有以任何方式修改主'这是不正确的。看看汇编代码。 – tkausl
这是因为当你到达fn()的末尾时,它会从堆栈中弹出返回地址,但是之前没有被推到那里,因为你“跳”到那里而不是“调用”那里。 – BrunoLevy
生成程序集输出并查看它。 –