我正在分析用vc ++编译的c ++函数(可能是vs10),之前我从未见过这个序言模式。
它似乎是一个 stdcall ,但序幕有点不同:
stdcall 通常使用以下序言模式启动该函数:
push ebp
mov ebp, esp
sub esp, const
然而,我正在分析的这个功能的序言如下:
push ebp
lea ebp, [esp - 0x4C]
sub esp, 0x80
分析使用相同序言/结语的同一个PE中的其他功能似乎 RETN 总是在 LEAVE 指令之后,这是我从未见过的另一件事定期 cdecl 功能。
我想知道为什么编译器会这样做。它似乎在 ESP (由sub esp, const
)上开放空间,那么为什么它会在lea ebp, [esp - const]
之前打开另一个堆栈?
有谁知道编译器为什么这样做?这是 stdcall 的不同调用约定吗?
我在网上做了一些研究,并研究了这个具体的汇编代码,但未发现需要。
提前致谢!
使用序言/结语的屏幕进行编辑:
答案 0 :(得分:1)
由于评论中没有人在这里写下答案,我们去......
"通常"之间的序言/结语差异的原因 stdcall ,我在本主题中谈到的是代码密度的编译器优化。
在序言中偏移EBP
,编译器能够缩短访问某些堆栈变量的函数中的指令。它现在可以使用EBP
和EBP + N
访问局部变量(EBP - M
来访问更大的堆栈内存块(取决于序言偏移量N
)多长时间。 1}}和M
是-128和+ 127之间的常量。当然,访问超出EBP偏移量的变量的指令将使用4个字节的位移,但使用此优化技巧,该函数的整体代码将更短。