汇编程序:
.globl _test
_test:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
pushl %eax
call printf
popl %ebp
ret
从c
打电话main()
{
_test("Hello");
}
编译:
gcc -m32 -o test test.c test.s
此代码有时会给我非法指令,而其他时候会分段错误。 在gdc我总是得到非法指令,这只是一个简单的测试,我有一个更大的程序正在工作,突然没有上诉理由停止工作,现在我总是得到这个错误,即使我从头开始如上。
我已将其缩小到pushl%eax&调用printf,如果我注释掉这些行代码运行正常。
有什么想法吗? (我在我的大学linux集群中运行程序,所以我没有更改任何设置..)
答案 0 :(得分:3)
你的最后两条指令破坏了堆栈基指针。任何依赖ebp(基指针)指向实际堆栈空间的代码都将失败。通常期望ebp指向堆栈空间是一个安全的假设,并且在与C代码连接时不应使该假设无效。
您正在执行pushl %eax
(或任何其他注册),然后执行popl %ebp
。这两者具有与movl %eax, %ebp
相同的效果。
我假设您正在尝试返回存储在eax中的值。在C调用约定中,eax用于返回值,因此不需要推送它或对其执行任何操作,只需将值保留在其中,其他代码将获取它。如果那不是你想要做的,那么我很难过为什么你会在这个函数结束时推动%eax。
答案 1 :(得分:2)
用leave
替换pop指令。这将恢复堆栈和基址指针。