为什么编译器保留一点堆栈空间而不是整个数组大小?

2023-12-26

下面的代码

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

编译成这样:

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

知道整数是 4 个字节,数组大小是 120,数组应该占用 480 个字节,但只从 ESP 中减去 360 个字节......这是为什么?


在函数使用的堆栈区域下面,有一个128字节红色区域 https://stackoverflow.com/questions/38042188/where-exactly-is-the-red-zone-on-x86-64保留供程序使用。自从main不调用其他函数,它不需要将堆栈指针移动超过它需要的范围,尽管在这种情况下这并不重要。它只减去足够的rsp以确保阵列受到红色区域的保护。

您可以通过添加函数调用来查看差异main

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

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

这给出了 https://godbolt.org/g/W9M2av:

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

您可以看到mainfunction 减去 480,因为它需要数组位于其堆栈空间中,但 test 不需要,因为它不调用任何函数。

数组元素的额外使用不会显着改变输出,但添加它是为了清楚地表明它并不是假装这些元素不存在。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么编译器保留一点堆栈空间而不是整个数组大小? 的相关文章

随机推荐