当与程序集结合时,gcc mingw提供垃圾输出

时间:2019-02-03 18:14:49

标签: c gcc assembly mingw calling-convention

我的gcc:线程模型:posix

gcc版本8.1.0(x86_64-posix-seh-rev0,由MinGW-W64项目构建)

我正在尝试创建一个简单的应用程序,该应用程序使用gcc和intel语法(其中saberi表示求和)将两个数字与两个文件saberi.c和saberi.s求和。

saberi.c

#include <stdio.h>
int saberi(int a, int b);
int main()
{   
    int a, b;
    scanf("%d %d", &a, &b);
    printf("Sum is: %d\n", saberi(a, b));
    return 0;
}

saberi.s

.intel_syntax noprefix
.text
    .globl saberi
saberi:
    enter 0,0
    mov eax, edi
    add eax, esi
    leave
    ret

然后我执行gcc saberi.c saberi.s,当我打开可执行文件并键入例如两个任意数字(1和2)时,我得到一个随机值作为总和。

1 个答案:

答案 0 :(得分:4)

默认情况下,MinGW编译器针对Windows目标进行编译。意味着编译器遵循Windows ABI和Windows调用约定。 前两个整数参数在rcxrdx中传递,而不是像System V ABI中那样传递rdirsi

您可以通过将saberi.c的程序集生成为-

进行验证
gcc -S saberi.c -o saberi_compiled.s

您将看到,在调用saberi之前,编译器将参数移至ecxedx中。

因此,您的saberi.s应该更改为-

intel_syntax noprefix
.text
    .globl saberi
saberi:
    enter 0,0
    mov eax, ecx
    add eax, edx
    leave
    ret

您应该得到正确的结果。

另一个选择是告诉编译器在调用saberi时使用System V ABI。可以在gcc(MinGW)中使用sysv_abi函数的saberi属性作为-

int saberi(int a, int b) __attribute__((sysv_abi));

然后,您可以使程序集保持不变。当您要编写跨平台可移植的程序集时,此方法很有用。但是当然它仅限于gcc