2017-08-29 56 views
3

这是我的汇编程序add.s调用汇编函数导致段错误

.globl add 

add: 
    movl 4(%esp), %eax 
    movl 8(%esp), %ebx 
    addl %ebx, %eax 
    ret 

这是我的C程序。我正试图从C程序中调用汇编程序。

#include <stdio.h> 

int add(int a, int b); 

int main() { 
    int res = add(5,6); 
    printf("%d",res); 
    return 0; 
} 

但上面的代码给了我一个分段错误。什么导致这个错误,我该如何解决它?

+2

如果你创建在C相同的功能,编译器如何生成代码它?它会执行一些堆栈设置吗?它是否保存它用来不打开它们的寄存器(也许它们在其他地方使用)? –

+2

这是用'x86-64'标记的。如果这是真的,那么在我意识到的任何ABI中,这不是如何传递参数。它编译的实际操作系统和体系结构是什么?它是如何编译和链接的? (可能会发生崩溃,因为从(%esp)读取不好,因为它应该是%rsp)。 – Art

+0

我不得不赞同艺术。你是否将其编译为32位或64位代码? –

回答

4

假设的cdecl调用约定,您使用的是ebx寄存器这应该不会是重挫:其值必须被保存,然后由被叫恢复的,如果它要进行修改。

调用者假定ebx不会通过调用函数来改变。因此,如果被调用者修改ebx它必须先保存它,然后在从函数返回之前将其恢复到其原始值。


寄存器eaxecxedx可在不必将其保存,然后再恢复使用。因此,我建议在你的代码替换edxebx

add: 
    movl 4(%esp), %eax 
    movl 8(%esp), %edx 
    addl %edx, %eax 
    ret 
+0

我以为'ebx'是一个通用寄存器(在这里阅读http://www.eecg.toronto.edu/~amza/www.mindsec.com/files/x86regs.html),为什么它不应该被覆盖? – CIsForCookies

+1

@CIsForCookies它可以被覆盖,但调用者认为寄存器'ebx'不会通过调用函数来改变,因此被调用者必须先保存它,然后在返回之前将其恢复。 –

+0

哦......好的。 'add'开头的'push ebx'怎么办?它会好吗? (显然使用'edx'代替是正确的方法,但只是试图理解) – CIsForCookies

相关问题