Search code examples
cassemblyx86x86-64red-zone

disassembly of C array gives weird results


int square() {
    char test[50];
}

The above code produces

square():
        push    rbp
        mov     rbp, rsp

When i change the code a little to

int square() {
    char test[150];
}

The assembly generated is

square():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 40

Which is still weird because I cannot understand why it does not allocate for previous creations. I'm running at -O0 so gcc doesn't optimize it out. Why is gcc creating code for wrong sized arrays?

int square() {
    char a[50];
    char b[50];
}
square():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 8

Similarly for x86

int square() {
    char a[500];
}

compiled with -m32 gives me:

square():
        push    ebp
        mov     ebp, esp
        sub     esp, 512

Where is this extra 12 bytes from? And why does -m32 have an sub instruction for char test[50] but x86_64 doesn't?


Solution

  • GCC is using the x86-64 System V ABI's 128-byte Red Zone below the stack pointer for the variables, only reserving some extra stack space when that's not sufficient

    For the last example, GCC subs 512 to keep the stack (and the array) aligned.

    The i386 System V ABI does not have a red zone so it has to reserve space for the whole array (neither does Windows x64, for that matter).