tags:

views:

147

answers:

2

I'm a beginner learning some assembly, when preserving the ESP register before a function call does it matter if you do it by adding or subtracting? hard to explain, consider the following

mov esi, esp
sub esp, 12 // on 32bit OS this would mean that there are 3 arguments to the function
// push, function call etc
cmp esi, esp // should be the same

or

mov esi, esp
// push, function call etc
add esp, 12
cmp esi, esp // should be the same

Also if for some reason the cmp fails, is it safe to do mov esp, esi to re-align the stack?

Thanks

EDIT: Also how come i need to do this for a call like sprintf, but MessageBox seems to fix ESP for me? How am i to know what function needs this and what doesn't?

A: 

Also how come i need to do this for a call like sprintf, but MessageBox seems to fix ESP for me?

This is because the MessageBox() function clears the parameters off the stack when it returns. It can do this because the number of parameters is fixed.

However, the sprintf() function is called with a variable number of parameters. The function doesn't know how many the caller may have pushed on to the stack, so it's the caller's responsibility to clean them up when the call returns.

Michael Burr
Ah i see that makes sense, thanks for your input
Daniel
+2  A: 

Yes, it is important to get the sign correct when using esp (in this case, subtracting, but also sometimes you need to add when referencing something already on the stack, like arguments inside a function). The reason for this is that the stack grows downward in memory. This is counter to how we usually think of a stack (you place things on top and remove them from the top), in memory this would be higher and higher addresses as the stac k grows. But the call stack on X86 (and most other) processors actually grows downward. This is like adding plates to the bottom of the stack, and removing them from the bottom... in memory the addresses get lower and lower as more things are added to the stack.

Yes, it is safe to change the value to esp as long as you are sure what you're setting it to is a valid location inside the stack, and as long as you're sure you didn't need any of the information you're losing by doing that. In this case, you're saving esp in esi for exactly this reason... you can restore esp from esi so no matter what the previous function call did, you know esp is just where you want it to be.

The difference between sprint and MessageBox is the "calling convention". This tells higher level languages (C) how to handle the stack frame and registers when they are called. sprintf is a cdecl, while MessageBox is a stdcall.

SoapBox
very informative thanks
Daniel