首页 > 解决方案 > gcc mingw 与程序集结合时会产生垃圾输出

问题描述

我的 gcc:线程模型:posix

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

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

saber.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;
}

军刀

.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)时,我得到一个随机值作为总和。

标签: cgccassemblymingwcalling-convention

解决方案


MinGW 编译器默认为 Windows 目标编译。这意味着编译器遵循Windows ABI和 Windows 调用约定。前两个整数参数传入rcxandrdx而不是System V ABI 中的rdiand 。rsi

您可以通过为 saberi.c 生成程序集来验证 -

gcc -S saberi.c -o saberi_compiled.s

您会看到在调用之前saberi,编译器将参数移入ecxand中edx

所以你的 saberi.s 应该改为 -

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

你应该得到正确的结果。

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

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

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


推荐阅读