我的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)时,我得到一个随机值作为总和。
答案 0 :(得分:4)
默认情况下,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)中使用sysv_abi
函数的saberi
属性作为-
int saberi(int a, int b) __attribute__((sysv_abi));
然后,您可以使程序集保持不变。当您要编写跨平台可移植的程序集时,此方法很有用。但是当然它仅限于gcc
。