Ok, burn me at the stake if you must but I have a question:

I read all the time about 'you need to preserve the registers', but when you're using api's that trash them anyway, why worry about ruining a good thing? In other words, why go through the trouble with your own apps to save the regs when some of the windoze api's don't?  I have learned the hard way to save whatever I need to use before each api call and retrieve it afterwards at the point I need it as physically possible.
Posted on 2005-07-27 05:52:46 by drarem

I read all the time about 'you need to preserve the registers', but when you're using api's that trash them anyway, why worry about ruining a good thing? In other words, why go through the trouble with your own apps to save the regs when some of the windoze api's don't?  I have learned the hard way to save whatever I need to use before each api call and retrieve it afterwards at the point I need it as physically possible.

It's all about the standard calling convention rules, and Application Binary Interface as defined by intel (which most OSes and compilers follow).

EBX ESI EDI EBP ESP are the registers to preserve
EAX ECX EDX can be freely trashed.

This means a few things, namely:

*) if you call an API, you must always assume that EAX, ECX and EDX are trashed, but you can be sure that EBX, ESI, EDI, EBP and ESP will not.

*) in callback routines, such as wndprocs, you must preserve EBX, ESI, EDI, EBP, ESP. To avoid bull from a certain person, http://dictionary.reference.com/search?q=preserve - in other words, you don't have to do anything about those registers unless you mess with them. You can freely trash EAX, ECX, and EDX in callbacks (EAX is used as return value though, so be sure to return something sensible).

*) you don't HAVE to follow the standard register preservation rules in your own routines, but it's a good idea to do so, since it will save you a lot of headaches. If register preservation is a speed issue to you, you're most likely suffering from bad program design anyway. (but in callbacks, you have to follow the register preservation rules.)

There's a few other things to keep in mind too, like not touching the segment/selector registers, keeping the stack 4-byte aligned, keeping structures (pointer arguments in general) 4-byte aligned, and preserving the direction flag (CLD if you STD).
Posted on 2005-07-27 07:13:26 by f0dder
Thank you for the detailed explanation, I'll work on it - a question about the alignment, sometimes I see in code..

align dword

and sometimes more than once thruout the code.

How does the coder know where and when to add the alignment, and how much..  at beginning or end of .data variables?  How much to align?
Posted on 2005-07-27 11:50:37 by drarem
Normally you should make sure that you align LOCAL variables (those on the stack), so that they all occupy a size divisible by 4. All other alignments are optional and are used for speed optimization purposes.
Posted on 2005-07-27 11:53:58 by ti_mo_n

How does the coder know where and when to add the alignment, and how much..  at beginning or end of .data variables?  How much to align?

A rule of thumb is to keep everything aligned at 4 bytes - it saves you trouble in "those instances", and it has a minor speed advantage, too. PUt an "align 4" before strings (or make a string declaration macro that does this automatically).

As for code, that is purely for speed optimizations. You can put an "align 4" before labels used for loops.
Posted on 2005-07-27 12:14:48 by f0dder
@drarem: f0dder explained perfectly, here are some docs to have handy
agner.org/assem/#callconv
agner.org/assem/#optimize? chapter 8

@ti_mo_n: masm does that automatically (if you use LOCAL)

also a note that some windows structures _must_ be aligned (CONTEXT iirc),
Posted on 2005-07-27 13:29:07 by drizz
Why do I get the impression that C compilers align struct to 4 bytes?
Posted on 2005-07-28 08:57:29 by roticv
hmmmmm,

Someone here is a slow learner.


*) in callback routines, such as wndprocs, you must preserve EBX, ESI, EDI, EBP, ESP. To avoid bull from a certain person, http://dictionary.reference.com/search?q=preserve - in other words, you don't have to do anything about those registers unless you mess with them. You can freely trash EAX, ECX, and EDX in callbacks (EAX is used as return value though, so be sure to return something sensible).


Programming "in use definition" for "preserve / restore" registers in x86 means save registers somewhere (usually the stack) and copy them back when you have finished. Term redefinitions here do not help as they lead to contradictions, preserve in a callback by doing nothing and preserve in another proc by doing something.

There is only one rule of register preservation when dealing with an operating system specified criterion, preserve and restore on te basis of NEED ALONE, forget callbacks as they are nothing special from any other procedure that interacts with the operating system. To put it bluntly, if you DON'T MODIFY a system defined register in a callback, DON'T PRESERVE IT.

One day someone here will learn.

Regards,

hutch at movsd dot com
Posted on 2005-07-28 09:21:26 by hutch--

*) in callback routines, such as wndprocs, you must preserve EBX, ESI, EDI, EBP, ESP. To avoid bull from a certain person, http://dictionary.reference.com/search?q=preserve - in other words, you don't have to do anything about those registers unless you mess with them. You can freely trash EAX, ECX, and EDX in callbacks (EAX is used as return value though, so be sure to return something sensible).



There is only one rule of register preservation when dealing with an operating system specified criterion, preserve and restore on te basis of NEED ALONE, forget callbacks as they are nothing special from any other procedure that interacts with the operating system. To put it bluntly, if you DON'T MODIFY a system defined register in a callback, DON'T PRESERVE IT.


Er... same idea, different words...  :roll:
Posted on 2005-07-28 10:02:06 by QvasiModo

Er... same idea, different words...  :roll:

You'll never convince him of that. Have a look at another thread he trashed, which is the reason I added that disclaimer: http://www.asmcommunity.net/board/index.php?topic=12811.0
Posted on 2005-07-28 11:32:42 by f0dder
Enough of this stupid argument with two people saying exactly the same thing but one too stubborn to admit it. I have closed this thread and if it continues in another I will close that as well. This argument is over as far as Win32Asm community is concerned and the answer is...

It's all about the standard calling convention rules, and Application Binary Interface as defined by intel (which most OSes and compilers follow).

EBX ESI EDI EBP ESP are the registers to preserve
EAX ECX EDX can be freely trashed.


However be advised that EAX is the return value register and most callbacks expect it to be TRUE or FALSE on return and ESP/EBP are generally handled by the automated stack frame of your compiler.
Posted on 2005-07-28 18:33:28 by donkey