Hi,
It seems that eax is the working register on the x86, but are there any rules pertaining to the other registers?
Is there a convention when using the Win32 APIs that I need to be aware of?
I see there are two instructions that conveniently pushes/pops all the registers in one instruction (18 cycles according to the MASM docs), whilst elsewhere I've read that you only need to protect 3 registers (I can't find which they were right now). How critical is this? So far, I haven't done this, and apparently without ill effect?
Thanks!
Best regards,
Astro.
API's preserve EBX, EBP, ESI, and EDI, as well as leave the direction flag cleared
if you write a proc that may get used in a callback, it should do the same
EAX, ECX, and EDX are fair game
many functions return status in EAX
generally speaking,
EAX - accumulator
EBX - base/index
ECX - count
EDX - data
ESI - source index
EDI - destination index
EBP - base pointer
ESP - stack pointer
EIP - instruction pointer
well, that was the intent on the 8086/8088
with pentiums, any of them may be used for addressing (except EIP, of course)
stro,
Have a look at the help file ASMINTRO.CHM for the section "Register Preservation Convention", save me typing so much data. This is not an optional matter, get it right or write unreliable code that does not run properly on all Windows versions.
the convention you should be following is 'stdcall'. different systems use different parameter passing conventions. for example 64 bit windows systems use fastcall instead. but on 32 bit you should use stdcall
http://msdn.microsoft.com/en-us/library/984x0h58(VS.71).aspx
Ahh - I knew I read it somewhere! Thanks Hutch.
@Slugsnack - thanks!
Best regards,
Astro.
OK - so I only need to preserve the registers if *I* modify them for ANYTHING?
Best regards,
Astro.
well you should make it so any procedures/functions you make abide by the rules of stdcall. your 'main' function, you can modify any registers as you wish. but since all functions should using stdcall convention it is assumed that they will preserve all registers except eax/ecx/edx
for example if you are making a window.. and your wndproc modifies esi or edi then most likely the window will hang because windows expected those registers not to have been changed in your procedure. or at least if for you to restore their values if you had used them
OK.
I'm thinking that if I don't use them, why preserve them...
Best regards,
Astro.
Yes, if you are not using the registers there is no need to save and restore them.
Hi,
OK!
As well as saving the registers, would it be wise to save the flags as well?
I see there is PUSHFD and POPFD.
Best regards,
Astro.
the direction flag should be cleared
CLD (faster) before you exit if you ever use STD
OK! Thanks! :thumbu
Best regards,
Astro.
this is something that I think you need to know:
ebp,esp: in protected/long modes using these in "lea" or "mov xx, [esp/ebp]" will result in additional byte
esp: modifying this reg with something other than push/pop will sometime result in additional speed penalty
ebp: it is used for 'leave' instruction
ecx: nobodoy uses 'loop' because its slow, but be careful if you wants to shift a register by unknown # of bits
eax: using al/eax instead of any other *l/**x may result in smaller oppcode
in long mode using r** instead of e** for "lea" or "mov xx, [r**]" will result in smaller oppcode
using 16bit reg sometimes(CMP for instance) will result in same size oppcode as 32bit reg, so you may as well use 32bit reg; in long mode 16bit sometimes larger than 32bit
xor reg32, reg32 is smaller than xor reg64, reg64 in long mode; same speed, both clear highest 32bits of reg64
there are tonsĀ :dazzled: of other "features" butĀ I think its enough for now