Question

In gcc you can declare that a local variable should be put in a register using the following syntax.

register int arg asm("eax");

In some old code I found on the internet this syntax was used to declare that the parameters to a function should be passed in a register:

void foo(register int arg asm("eax"))

But when I try this example:

/*
   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;
}

And compile with gcc I get an error:

gcc main.c -o test-asm.exe
main.c:7:27: error: expected ';', ',' or ')' before 'asm'

Now my questions are:
Is the asm syntax above correct, in gcc that is, for formal parameters of a function?
Has this ever been supported by gcc?
If this is not the correct syntax, how can this be accomplished then?

Thanks,
//jk

Was it helpful?

Solution

The only method I know of is using the fastcall attribute:

(GCC Manual section 6.30) http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html#Function-Attributes

fastcall

On the Intel 386, the fastcall attribute causes the compiler to pass the first argument (if of integral type) in the register ECX and the second argument (if of integral type) in the register EDX. Subsequent and other typed arguments are passed on the stack. The called function will pop the arguments off the stack. If the number of arguments is variable all arguments are pushed on the stack.

Using it in on the following example code:

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

int main () {
  return add (1, 2);
}

will result in:

    .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

Don't forget to mention the fastcall attribute in any declaration in other translation units, otherwise rather strange things might happen.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top