奇怪的汇编调用约定

时间:2015-02-08 18:56:51

标签: assembly x86 calling-convention

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]? 感谢

1 个答案:

答案 0 :(得分:0)

通常的x86-32调用约定仅指定如何在堆栈上布置参数,谁删除它们以及必须保留哪些寄存器。特别是通常不需要帧指针,代码可以使用ebp作为另一个被调用者保存的寄存器。可以相对于esp访问参数,了解约定规定的堆栈布局以及由您自己的代码进行的任何堆栈调整。

这远非“胡说八道”,而是经常优化。鉴于x86-32不会给你很多寄存器,如果不需要帧伪指针就不会浪费ebp

对于引用的代码,ebxebpesiedi被推送,因为它们是被调用者保存的寄存器。我假设数字是十六进制的,所以mov ebp,[esp+14]加载第三个参数,因为此时从esp开始的堆栈布局是:ebpebx,{ {1}},return addressarg1arg2。类似地,arg3将加载第二个参数,因为到那时mov esi,[esp+14]也将在堆栈上。