非法指令gcc汇编程序

时间:2010-05-16 18:57:40

标签: linux gcc assembly

汇编程序:

.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集群中运行程序,所以我没有更改任何设置..)

2 个答案:

答案 0 :(得分:3)

你的最后两条指令破坏了堆栈基指针。任何依赖ebp(基指针)指向实际堆栈空间的代码都将失败。通常期望ebp指向堆栈空间是一个安全的假设,并且在与C代码连接时不应使该假设无效。

您正在执行pushl %eax(或任何其他注册),然后执行popl %ebp。这两者具有与movl %eax, %ebp相同的效果。

我假设您正在尝试返回存储在eax中的值。在C调用约定中,eax用于返回值,因此不需要推送它或对其执行任何操作,只需将值保留在其中,其他代码将获取它。如果那不是你想要做的,那么我很难过为什么你会在这个函数结束时推动%eax。

答案 1 :(得分:2)

leave替换pop指令。这将恢复堆栈和基址指针。