Setting up local stack according to x86-64 calling convention on linux

184 views Asked by At

I am doing some extended assembly optimization on gnu C code running on 64 bit linux. I wanted to print debugging messages from within the assembly code and that's how I came accross the following. I am hoping someone can explain what I am supposed to do in this situation.

Take a look at this sample function:

    void test(int a, int b, int c, int d){


        __asm__ volatile (

        "movq $0, %%rax\n\t"
        "pushq %%rax\n\t"
        "popq %%rax\n\t"


        :
        :"m" (a)
        :"cc", "%rax"
        );

}

Since the four agruments to the function are of class INTEGER, they will be passed through registers and then pushed onto the stack. The strange thing to me is how gcc actually does it:

test:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -4(%rbp)
        movl    %esi, -8(%rbp)
        movl    %edx, -12(%rbp)
        movl    %ecx, -16(%rbp)

        movq $0, %rax
        pushq %rax
        popq %rax

        popq    %rbp
        ret

The passed arguments are pushed onto the stack, but the stack pointer is not decremented. Thus, when I do pushq %rax, the values of a and b are overwritten. What I am wondering: is there a way to ask gcc to properly set up the local stack? Am I simply not supposed to use push and pop in function calls?

1

There are 1 answers

2
Jester On BEST ANSWER

x86-64 abi provides a 128 byte red zone under the stack pointer, and the compiler decided to use that. You can turn that off using -mno-red-zone option.