linux - 试图理解 gcc 在复制返回地址的 main 顶部的复杂堆栈对齐

标签 linux gcc assembly x86 compiler-construction

你好我已经反汇编了一些我写的程序 (linux) 以更好地理解它是如何工作的,我注意到主要功能总是以:

lea    ecx,[esp+0x4] ; I assume this is for getting the adress of the first argument of the main...why ?
and    esp,0xfffffff0 ; ??? is the compiler trying to align the stack pointer on 16 bytes ???
push   DWORD PTR [ecx-0x4] ; I understand the assembler is pushing the return adress....why ?
push   ebp                
mov    ebp,esp
push   ecx  ;why is ecx pushed too ??

所以我的问题是:为什么所有这些工作都完成了?? 我只了解使用:

push   ebp                
mov    ebp,esp

其余的对我来说似乎没用......

最佳答案

我试过了:

;# As you have already noticed, the compiler wants to align the stack
;# pointer on a 16 byte boundary before it pushes anything. That's
;# because certain instructions' memory access needs to be aligned
;# that way.
;# So in order to first save the original offset of esp (+4), it
;# executes the first instruction:
lea    ecx,[esp+0x4]

;# Now alignment can happen. Without the previous insn the next one
;# would have made the original esp unrecoverable:
and    esp,0xfffffff0

;# Next it pushes the return addresss and creates a stack frame. I
;# assume it now wants to make the stack look like a normal
;# subroutine call:
push   DWORD PTR [ecx-0x4]
push   ebp
mov    ebp,esp

;# Remember that ecx is still the only value that can restore the
;# original esp. Since ecx may be garbled by any subroutine calls,
;# it has to save it somewhere:
push   ecx

关于linux - 试图理解 gcc 在复制返回地址的 main 顶部的复杂堆栈对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1147623/

相关文章:

linux - platform_device_register 和 usb ehci 驱动程序

linux - 用于从 2 个不同文件中获取相同行的 bash 脚本

c++ - 如何将 gcc include 目录添加到现有的 Makefile

assembly - 汇编中的IDIV操作(理解)

linux - 将文件夹添加到特定压缩文件

linux - Shell脚本,失败则停止运行

linux - 动态链接尝试全部产生静态链接的二进制文件?为什么?

c++ - 模板特化取决于类型

c - 在C中获取帧指针

linux - 如何使用 use as in linux 和汇编语言