Fresco
Fresco

Reputation: 299

Strange assembly 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:

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

Answers (1)

Jester
Jester

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

Related Questions