The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Astro on July 19, 2009, 03:13:38 AM

Title: Registers
Post by: Astro on July 19, 2009, 03:13:38 AM
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.
Title: Re: Registers
Post by: dedndave on July 19, 2009, 03:20:38 AM
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)
Title: Re: Registers
Post by: hutch-- on July 19, 2009, 03:38:25 AM
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.
Title: Re: Registers
Post by: Slugsnack on July 19, 2009, 10:09:06 AM
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
Title: Re: Registers
Post by: Astro on July 19, 2009, 02:43:08 PM
Ahh - I knew I read it somewhere! Thanks Hutch.

@Slugsnack - thanks!

Best regards,
Astro.
Title: Re: Registers
Post by: Astro on July 21, 2009, 03:19:07 PM
OK - so I only need to preserve the registers if *I* modify them for ANYTHING?

Best regards,
Astro.
Title: Re: Registers
Post by: Slugsnack on July 21, 2009, 04:20:51 PM
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
Title: Re: Registers
Post by: Astro on July 21, 2009, 04:35:21 PM
OK.

I'm thinking that if I don't use them, why preserve them...

Best regards,
Astro.
Title: Re: Registers
Post by: disintx on July 21, 2009, 10:08:38 PM
Yes, if you are not using the registers there is no need to save and restore them.
Title: Re: Registers
Post by: Astro on July 23, 2009, 11:58:57 PM
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.
Title: Re: Registers
Post by: dedndave on July 24, 2009, 12:53:22 AM
the direction flag should be cleared
CLD (faster) before you exit if you ever use STD
Title: Re: Registers
Post by: Astro on July 24, 2009, 02:53:19 AM
OK! Thanks!   :thumbu

Best regards,
Astro.
Title: Re: Registers
Post by: cmpxchg on July 24, 2009, 05:26:13 AM
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