Saving and Restoring Registers via Push/Pop - Problem?

Started by Chip, July 07, 2006, 06:52:51 AM

Previous topic - Next topic

Chip

I try to save my registers prior to calling a windows procedure
by PUSHing key registers.  After the procedure returns, I POP all of the
registers.

Unfortunately, what is Pushed is not what is Popped!
I have included my code, as well as the Register Dump available in GoBug

Am I doing something wrong?

Chip
                  Computer        AMD FX-53
                  Operating Sys       Windows XP/32
                  Using GoASM      55.03 Beta 2002/6
                          GoLink         0.26.4
                        GoBug        2.03


                   GoBug - copyright Jeremy Gordon 1996-2005
                  Date: Thursday, July 06, 2006 Time: 22:45:16
*************************************************************************************************************************************
                  xor eax, eax               ;Reset all Registers to Zero
xor ebx, ebx
xor ecx, ecx
xor edx, edx      
xor edi, edi
xor esi, esi   
mov ebx, [FileSizeLow]                   ;Size of file on Disk                        

.quickloop                     ;Quick and Dirty debugging loop!
push eax, ebx, ecx, edx, edi, esi      ;Save all Register Contents

                  REGISTERS BEFORE INVOKE READ
________________________________________________________________________
      EDI=00000000h            ESI=00000000h            EBX=05F81800h
        EDX=00000000h            ECX=00000000h            EAX=00000000h
        EBP=0012FFF0h            EIP=00401094h            ESP=0012FFACh
         GS=00000000h             FS=0000003Bh             ES=00000023h
         DS=00000023h             CS=0000001Bh             SS=00000023h
                C=0   P=1   A=0   Z=1   S=0   O=0   D=0   
__________________________________________________________________________


INVOKE  ReadFile,   
                  REGISTERS AFTER INVOKE READ
__________________________________________________________________________
        EDI=00000000h            ESI=00000000h            EBX=05F81800h
        EDX=7C90EB94h            ECX=7C801898h            EAX=00000001h
        EBP=0012FFF0h            EIP=004010BAh            ESP=0012FFA8h
         GS=00000000h             FS=0000003Bh             ES=00000023h
         DS=00000023h             CS=0000001Bh             SS=00000023h
                C=0   P=0   A=0   Z=0   S=0   O=0   D=0   
__________________________________________________________________________



pop eax, ebx, ecx, edx, edi, esi
                  REGISTERS AFTER POPS OF ALL REGISTERS
__________________________________________________________________________
        EDI=00000000h            ESI=05F81800h            EBX=00000000h
        EDX=00000000h            ECX=00000000h            EAX=00000000h
        EBP=0012FFF0h            EIP=004010C0h            ESP=0012FFC0h
         GS=00000000h             FS=0000003Bh             ES=00000023h
         DS=00000023h             CS=0000001Bh             SS=00000023h
                C=0   P=0   A=0   Z=0   S=0   O=0   D=0   
__________________________________________________________________________
add edx,  1                            ;Count the Number of read blocks
add edi,  [NumberOfBytesToRead]                ;Increment bytes read after each read
cmp edi,  ebx                     ;If bytes read is less than file size,
jnb .quickloop                     ;   read again

******************************************************************************************************************************************************************************


NOTICE that the value in the EBX Register has been moved to the ESI Register.
ALSO, (Not Shown) a value placed in EDI before read loop Disappears after second set of pops.

I am on Skype under my email address!

James Ladd

I think that invoke is doing the register presevation for you and therefore you dont need to do it as well.
Also, im not sure you need to or should be pushing and poping edi and esi.

ToutEnMasm

Hello,
Your code don't follow the rules.For the stack,the last in must be the first out.
example:
push eax
push esi
--------------
pop esi
pop eax
You can use also pushad popad and uses just after PROC
example

MyProc PROC uses esi edi ebx parameter:DWORD
;-------------------
   ret
MyProc endp

                                 ToutEnMasm

jorgon

In GoAsm FRAME .. ENDF is used instead of PROC.  This is to emphasise the fact that when you use this, you are creating a stack frame (to hold local data or to receive parameters in for example a windows procedure or callback).

In GoAsm you can use USES .. ENDU at any time, not just within a FRAME.

See the GoAsm manual for details of how to use FRAME .. ENDF and USES.. ENDU and for answers to other questions about GoAsm.

Chip, as ToutEnMasm says, your error is caused by not following the last in, first out rule for PUSHes and POPs.

And as James Ladd inferred, all Windows APIs (with one or two minor exceptions) preserve the EBX,ESI,EBP and EDI registers so there is no need to preserve these a second time.  Also there would be no need to preserve registers as a matter of course normally anyway, unless they contain important information for your program.  An exception to this is in Windows callback procedures (for example window procedures) which must preserve the EBX,ESI,EBP and EDI registers.  Also personally I never use the EBP register without preserving it, although this may not strictly be necessary these days.
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

Chip

To All,

Many of you may THINK that I am trying to relearn Assembler.

However, the truth is: I am writing a book on how many
consecutive dumb mistakes I can make per day!  If, at
the end of the week, I have made the SAME mistake at
least 10 times per day, I give myself a blue ribbon.

I thank you one and all for observing my research project!


In reality, I resisted seeking the aid of you all for months,
knowing that mistakes are part of the game.   I can
generally figure them out - after a supreme effort in
re-reading documentation so many times I will soon have
it memorized.  (But, not learned - yet!)

So be assured that I have spent hours trying to solve my
problems before seeking your counsel.

I truly thank those who read my queries and give assistance. 

Chip
I am on Skype under my email address!