push ebx
push ebp
mov ebp,[esp+14]
push esi
mov esi,[esp+14]
push edi
mov [esp+10],00000000
cmp dword ptr [ebp+00],05
jne aheadInThisFx
mov eax,[esp+20]
mov edi,[ebp+08]
push eax
push edi
push esi
call SomeItherFx
//more code
aheadInThisFx:
上面的代码是函数启动的反汇编,很奇怪。什么样的编译器会产生这样的废话?
如果您已经遇到类似的事情,请向我解释一下。
我不理解调用约定。
在第3行,它意味着什么:
mov ebp,[esp+14]
不应该是:
push ebp
mov ebp,esp
和论据,[ebp-4],[ebp-8]?
感谢
答案 0 :(得分:0)
通常的x86-32调用约定仅指定如何在堆栈上布置参数,谁删除它们以及必须保留哪些寄存器。特别是通常不需要帧指针,代码可以使用ebp
作为另一个被调用者保存的寄存器。可以相对于esp
访问参数,了解约定规定的堆栈布局以及由您自己的代码进行的任何堆栈调整。
这远非“胡说八道”,而是经常优化。鉴于x86-32不会给你很多寄存器,如果不需要帧伪指针就不会浪费ebp
。
对于引用的代码,ebx
,ebp
,esi
和edi
被推送,因为它们是被调用者保存的寄存器。我假设数字是十六进制的,所以mov ebp,[esp+14]
加载第三个参数,因为此时从esp
开始的堆栈布局是:ebp
,ebx
,{ {1}},return address
,arg1
,arg2
。类似地,arg3
将加载第二个参数,因为到那时mov esi,[esp+14]
也将在堆栈上。