News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Preservation of esi, edi, ebx in general code

Started by satpro, June 09, 2012, 02:20:00 AM

Previous topic - Next topic

jj2007

6 cycles, 0.2% slower. Show me one WM_nnn that needs less than 3000 cycles...

(actually, there is one: WM_MOUSEMOVE takes only 600 cycles... which means that with the uses esi edi ebx, your WM_MOUSEMOVE processing will take approx. 0.00408 milliseconds instead of only 0.004 milliseconds... ::))

hutch--

Its all of the extra clutter that is the problem and the added problem associated with multiple exits, the much cleaner and simpler technique is to preserve required registers on a needs basis for each message processed. A WndProc is a messy enough affair to start with, essentially a single collector procedure with multiple functions based on the number of processed messages being handled, different messages having different needs, this is why a catch all is bad design.

dedndave

it's really true
a top-level window with a mouse moving over it gets hundreds, if not thousands of messages
they usually go to DefWindowProc - but only after passing through the epilogue

jj2007

Quote from: dedndave on June 10, 2012, 12:39:54 AM
a top-level window with a mouse moving over it gets hundreds, if not thousands of messages

Most of them are WM_MOUSEMOVE - a particularly fast one with only 600 cycles. 3 push/pop pairs delay WM_MOUSEMOVE by 0.00008 milliseconds - how significant is that delay?

To put it differently: Launch a simple window, then Task Manager, and try to get CPU usage above 0% by frenetically moving the mouse over the window. Have fun.

satpro

Sorry, guys...  didn't mean to shake the tree.


So if I:


-- PUSH (or USES)  ESI or EDI or EBX   (in a procedure IF modified in the procedure)
-- PUSH  EAX or ECX or EDX                 (before entering a procedure IF the value held is needed afterwards)
-- Assume other programmers assume esi, edi, and ebx will be preserved; eax, ecx, and edx will be trashed in procedures.


...it should be okay.  Does that sound about right?

dedndave

yes - and let's not forget EBP - it should be preserved also
typically, we do not use EBP because the default epilogue for masm PROC's uses it for parms
the assembler takes care of preserving it for you

BogdanOntanu

Do not PUSH EAX because it is normally used for the return value...
Ambition is a lame excuse for the ones not brave enough to be lazy, www.oby.ro

Ryan

Quote from: BogdanOntanu on June 10, 2012, 08:33:48 AM
Do not PUSH EAX because it is normally used for the return value...
What do you mean?  If the value in EAX is still needed, it has to be pushed, else it will be lost.

dedndave

you are right, Ryan
most functions do return a result in EAX, however
but - you could do something like...
        push    eax
        INVOKE  SomeFunction
        or      eax,eax                ;test returned value
        pop     eax                    ;restore saved value
        jz      SomeLabel              ;branch on result of test

another way to go might be to restore it into EDX (or ECX)
        push    eax
        INVOKE  SomeFunction
        or      eax,eax                ;test returned value
        pop     edx                    ;restore saved value
        jz      SomeLabel              ;branch on result of test

that way, the returned value is not destroyed