kin*_*gW3 1 c assembly gcc mingw calling-convention
我的 gcc:线程模型: posix
gcc 版本 8.1.0(x86_64-posix-seh-rev0,由 MinGW-W64 项目构建)
我正在尝试创建一个简单的应用程序,它使用 gcc 和 intel 语法对两个文件 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;
}
Run Code Online (Sandbox Code Playgroud)
军刀
.intel_syntax noprefix
.text
.globl saberi
saberi:
enter 0,0
mov eax, edi
add eax, esi
leave
ret
Run Code Online (Sandbox Code Playgroud)
然后我执行 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
Run Code Online (Sandbox Code Playgroud)
您将看到,在调用之前saberi,编译器将参数移动到ecx和中edx。
所以你的 saberi.s 应该改为 -
intel_syntax noprefix
.text
.globl saberi
saberi:
enter 0,0
mov eax, ecx
add eax, edx
leave
ret
Run Code Online (Sandbox Code Playgroud)
你应该得到正确的结果。
另一种选择是告诉编译器在调用时使用 System V ABI saberi。sysv_abi这可以在 gcc (MinGW) 中使用函数属性来完成saberi:
int saberi(int a, int b) __attribute__((sysv_abi));
Run Code Online (Sandbox Code Playgroud)
然后你可以保持你的装配相同。当您想要编写可跨平台移植的程序集时,此方法非常有用。但当然仅限于gcc。