如何使用gcc asm关键字在寄存器中传递函数参数

如何使用gcc asm关键字在寄存器中传递函数参数,c,gcc,assembly,parameter-passing,calling-convention,C,Gcc,Assembly,Parameter Passing,Calling Convention,在gcc中,您可以使用以下语法声明应将局部变量放入寄存器中 register int arg asm("eax"); 在我在internet上找到的一些旧代码中,该语法用于声明函数的参数应在寄存器中传递: void foo(register int arg asm("eax")) 但当我尝试这个例子时: /* Program to demonstrate usage of asm keyword to allocate register for a variable. */ #incl

在gcc中,您可以使用以下语法声明应将局部变量放入寄存器中

register int arg asm("eax");
在我在internet上找到的一些旧代码中,该语法用于声明函数的参数应在寄存器中传递:

void foo(register int arg asm("eax"))
但当我尝试这个例子时:

/*
   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;
}
现在我的问题是:
上述asm语法是否正确(在gcc中,即函数的形式参数) gcc是否曾支持这一点?
如果这不是正确的语法,那么如何实现这一点呢?

谢谢,

//jk

我知道的唯一方法是使用fastcall属性:

(通用条款手册第6.30节)

快速呼叫

在英特尔386上,fastcall属性使编译器传递寄存器ECX中的第一个参数(如果为整数类型),然后 寄存器EDX中的第二个参数(如果为整型)。 随后的参数和其他类型的参数在堆栈上传递。这个 被调用的函数将从堆栈中弹出参数。如果 参数是可变的所有参数都被推送到堆栈上

在以下示例代码中使用它:

__attribute__((fastcall,noinline)) int add (int a, int b)
{
  return a + b;
}

int main () {
  return add (1, 2);
}
将导致:

    .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

别忘了在其他翻译单元的任何声明中提到fastcall属性,否则可能会发生一些奇怪的事情。

谢谢你的建议。但我认为gcc可能支持或者已经支持一种更通用的语法。哇,生成的函数有一半以上都是无用的开场白/尾声废话,这是多么丑陋啊。。。是用
-O0
还是…?不-用-O0它会变得更有趣,因为无论出于什么原因,通过ecx和edx传递的参数都会首先存储在堆栈上。这是(没有开玩笑的)gcc将对-O0做的事情:
add:pushl%ebp movl%esp,%ebp subl$8,%esp movl%ecx,-4(%ebp)movl%edx,-8(%ebp)movl-8(%ebp),%eax movl-4(%ebp),%edx leal(%edx,%eax leaf ret
还有
gcc-mregparm=3
,或者作为每个函数属性。
    .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