j.k*_*son 9 c assembly gcc parameter-passing calling-convention
在gcc中,您可以使用以下语法声明应将局部变量放入寄存器中.
register int arg asm("eax");
Run Code Online (Sandbox Code Playgroud)
在我在互联网上找到的一些旧代码中,这种语法用于声明函数的参数应该在寄存器中传递:
void foo(register int arg asm("eax"))
Run Code Online (Sandbox Code Playgroud)
但是当我尝试这个例子时:
/*
Program to demonstrate usage of asm keyword to allocate register for a variable.
*/
#include <stdio.h>
/* Function with argument passed in register */
void foo(register int arg asm("eax") )
{
register int loc asm("ebx");
loc = arg;
printf("foo() local var: %d\n", loc);
}
int main(void)
{
foo(42);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用gcc编译我得到一个错误:
gcc main.c -o test-asm.exe
main.c:7:27: error: expected ';', ',' or ')' before 'asm'
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:
上面的asm语法是正确的,在gcc中,对于函数的形式参数是什么?
这有没有得到gcc的支持?
如果这不是正确的语法,那么如何实现呢?
谢谢,
// jk
我知道的唯一方法是使用 fastcall 属性:
(GCC 手册第 6.30 节)http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html#Function-Attributes
快速呼叫
在 Intel 386 上,fastcall 属性使编译器将第一个参数(如果是整型)传递到寄存器 ECX 中,将第二个参数(如果是整型)传递到寄存器 EDX 中。后续和其他类型参数在堆栈上传递。被调用的函数将从堆栈中弹出参数。如果参数的数量是可变的,则所有参数都将被压入堆栈。
在以下示例代码中使用它:
__attribute__((fastcall,noinline)) int add (int a, int b)
{
return a + b;
}
int main () {
return add (1, 2);
}
Run Code Online (Sandbox Code Playgroud)
将导致:
.file "main.c"
.text
.globl add
.type add, @function
add:
pushl %ebp
movl %esp, %ebp
leal (%edx,%ecx), %eax
popl %ebp
ret
.size add, .-add
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $2, %edx
movl $1, %ecx
call add
popl %ebp
ret
.size main, .-main
Run Code Online (Sandbox Code Playgroud)
不要忘记在其他翻译单元的任何声明中提及 fastcall 属性,否则可能会发生相当奇怪的事情。