0

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?

fuz
  • 88,405
  • 25
  • 200
  • 352
Ivan
  • 409
  • 4
  • 17

1 Answers1

2

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.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • Thanks, this works. Is there any way to enforce this option on a function-to-function basis? – Ivan Dec 08 '14 at 16:49
  • Don't think so. But you can put your functions into a separate file. Also, if your code depends on this setting, you are probably doing something wrong. – Jester Dec 08 '14 at 17:11