gpt4 book ai didi

linux - 为什么在函数的开头经常出现 "lea..and..push"汇编代码?

转载 作者:行者123 更新时间:2023-12-03 09:58:47 24 4
gpt4 key购买 nike

我在通过GDB查看一些文件的时候发现,很频繁,函数开头有这三行代码

   0x08048548 <+0>:     lea    ecx,[esp+0x4]
0x0804854c <+4>: and esp,0xfffffff0
0x0804854f <+7>: push DWORD PTR [ecx-0x4]

我通常会忽略它们,因为在创建这三行堆栈帧之后,函数通常是这样启动的。

谢谢你。

最佳答案

这是将堆栈指针对齐到 16 字节边界,因为有时(对于 SSE)CPU 需要 16 字节的数据对齐。

一个好的编译器会检查调用图(找出什么调用什么),并决定:

  • 该函数本身不需要堆栈对齐,也不会调用其他需要堆栈对齐的函数;因此不需要堆栈对齐
  • 该函数的所有调用者都使用对齐的堆栈,因此:
  • 该函数只需要进行固定调整即可重新建立预先存在的对齐方式,例如 sub esp, 8 (可以与任何为局部变量保留堆栈空间的代码合并)
  • 实际需要16字节对齐的数据可以给定16字节对齐,而不用对齐栈本身
  • 以上都不能被证明是正确的,所以函数必须假设“最坏的情况”并自行强制对齐(例如你在函数开始时看到的指令)

  • 当然,对于一个好的编译器来说,最后一种情况(需要您显示的代码)是非常罕见的。

    然而;大多数编译器都不好,因为它们无法看到整个程序(如果将程序拆分为多个单独编译的目标文件,那么编译器一次只能看到程序的一小部分)。他们无法弄清楚很多/任何调用图,因此最后一种情况(需要您显示的代码)变得非常普遍。要解决这个问题,您需要“链接时间代码生成”,但通常人们不会打扰。

    注意:对于 AVX2,您需要 32 字节对齐,对于 AVX512,您需要 64 字节对齐,并且对于某些事情(为了避免重线程代码中的错误共享),您可能需要“缓存行大小对齐”(通常也是 64 字节对齐)。这使得“检查调用图以确定实际需要什么对齐”算法比我描述的要复杂一些。

    关于linux - 为什么在函数的开头经常出现 "lea..and..push"汇编代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59331096/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com