Reputation: 299
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:
The code above is the disassembly of the start of a function, it is very strange. What kind of compiler would generate such nonsense ?
If you already encountered something alike, please explain it to me too.
I don't understand the calling convention.
At line 3, what does it mean to:
mov ebp,[esp+14]
shouldn't it be:
push ebp
mov ebp,esp
and the arguments, [ebp-4], [ebp-8] ?
Thanks
Upvotes: 0
Views: 206
Reputation: 58762
The usual x86-32 calling conventions only specify how the arguments need to be laid out on the stack, who removes them and which registers have to be preserved. In particular a frame pointer is not typically required and code may use ebp
as just another callee-saved register. The arguments can be accessed relative to esp
, knowing the stack layout prescribed by the convention and any stack adjustments made by your own code.
This is far from "nonsense", it's a frequent optimization. Given that x86-32 doesn't give you very many registers, it makes sense not to waste ebp
for a frame pointer if it's otherwise not required.
As for the quoted code, ebx
, ebp
, esi
and edi
are pushed because they are callee-saved registers. I assume the numbers are in hex, so the mov ebp,[esp+14]
loads the 3rd argument, since stack layout at that point, starting from esp
, is: ebp
, ebx
, return address
, arg1
, arg2
, arg3
. Similarly, the mov esi,[esp+14]
will load the 2nd argument because by that point esi
will also be on the stack.
Upvotes: 0