一尘不染

试图了解gcc在main顶部复制返回地址的复杂堆栈对齐方式

linux

嗨,我已经分解了一些程序(Linux),我写这些程序是为了更好地理解它的工作原理,并且我注意到main函数总是以以下内容开头:

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

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


阅读 288

收藏
2020-06-03

共1个答案

一尘不染

我已经尝试了:

;# 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
2020-06-03