Search code examples
assemblyx86-64stack-memoryred-zone

Why does the compiler reserve a little stack space but not the whole array size?


The following code

int main() {
  int arr[120];
  return arr[0];
}

Compiles into this:

  sub     rsp, 360
  mov     eax, DWORD PTR [rsp-480]
  add     rsp, 360
  ret

Knowing the ints are 4 bytes and the array is size 120, the array should take 480 bytes, but only 360 bytes are subtracted from ESP... Why is this?


Solution

  • Below the stack area used by a function, there is a 128-byte red zone that is reserved for program use. Since main calls no other function, it has no need to move the stack pointer by more than it needs, though it doesn't matter in this case. It only subtracts enough from rsp to ensure that the array is protected by the red zone.

    You can see the difference by adding a function call to main

    int test() {
      int arr[120];
      return arr[0]+arr[119];
    }
    
    int main() {
      int arr[120];
      test();
      return arr[0]+arr[119];
    }
    

    This gives:

    test:
      push rbp
      mov rbp, rsp
      sub rsp, 360
      mov edx, DWORD PTR [rbp-480]
      mov eax, DWORD PTR [rbp-4]
      add eax, edx
      leave
      ret
    main:
      push rbp
      mov rbp, rsp
      sub rsp, 480
      mov eax, 0
      call test
      mov edx, DWORD PTR [rbp-480]
      mov eax, DWORD PTR [rbp-4]
      add eax, edx
      leave
      ret
    

    You can see that the main function subtracts by 480 because it needs the array to be in its stack space, but test doesn't need to because it doesn't call any functions.

    The additional usage of array elements does not significantly change the output, but it was added to make it clear that it's not pretending that those elements don't exist.