gcc mingw 在与程序集结合时给出垃圾输出
gcc mingw gives garbage output when combining with assembly
我的gcc:Thread模特:posix
gcc 版本 8.1.0(x86_64-posix-seh-rev0,由 MinGW-W64 项目构建)
我正在尝试创建一个简单的应用程序,它使用 gcc 和 intel 语法将两个数字与两个文件 saberi.c 和 saberi.s 相加,其中 saberi 表示总和。
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)时,我得到一个随机值作为总和。
MinGW 编译器默认为 Windows 目标编译。这意味着编译器遵循 Windows ABI 和 windows 调用约定。
前两个整数参数在 rcx
和 rdx
中传递,而不是像在 System V ABI 中那样在 rdi
和 rsi
中传递。
您可以通过为 saberi.c 生成程序集来验证 -
gcc -S saberi.c -o saberi_compiled.s
您会看到,在调用 saberi
之前,编译器会移动 ecx
和 edx
中的参数。
所以你的 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) 中使用 saberi
函数的 sysv_abi
属性来完成,如 -
int saberi(int a, int b) __attribute__((sysv_abi));
然后你可以保持你的程序集不变。当您想要编写可跨平台移植的程序集时,此方法很有用。但当然仅限于gcc
。
我的gcc:Thread模特:posix
gcc 版本 8.1.0(x86_64-posix-seh-rev0,由 MinGW-W64 项目构建)
我正在尝试创建一个简单的应用程序,它使用 gcc 和 intel 语法将两个数字与两个文件 saberi.c 和 saberi.s 相加,其中 saberi 表示总和。
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)时,我得到一个随机值作为总和。
MinGW 编译器默认为 Windows 目标编译。这意味着编译器遵循 Windows ABI 和 windows 调用约定。
前两个整数参数在 rcx
和 rdx
中传递,而不是像在 System V ABI 中那样在 rdi
和 rsi
中传递。
您可以通过为 saberi.c 生成程序集来验证 -
gcc -S saberi.c -o saberi_compiled.s
您会看到,在调用 saberi
之前,编译器会移动 ecx
和 edx
中的参数。
所以你的 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) 中使用 saberi
函数的 sysv_abi
属性来完成,如 -
int saberi(int a, int b) __attribute__((sysv_abi));
然后你可以保持你的程序集不变。当您想要编写可跨平台移植的程序集时,此方法很有用。但当然仅限于gcc
。