Author Topic: Preservation of esi, edi, ebx in general code  (Read 16765 times)

jj2007

  • Member
  • *****
  • Posts: 9633
  • Assembler is fun ;-)
    • MasmBasic
Re: Preservation of esi, edi, ebx in general code
« Reply #15 on: June 09, 2012, 06:52:15 PM »
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--

  • Administrator
  • Member
  • ******
  • Posts: 6582
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Preservation of esi, edi, ebx in general code
« Reply #16 on: June 09, 2012, 09:08:59 PM »
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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: Preservation of esi, edi, ebx in general code
« Reply #17 on: June 10, 2012, 12:39:54 AM »
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

  • Member
  • *****
  • Posts: 9633
  • Assembler is fun ;-)
    • MasmBasic
Re: Preservation of esi, edi, ebx in general code
« Reply #18 on: June 10, 2012, 03:23:28 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

  • Member
  • **
  • Posts: 116
Re: Preservation of esi, edi, ebx in general code
« Reply #19 on: June 10, 2012, 04:20:09 AM »
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

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: Preservation of esi, edi, ebx in general code
« Reply #20 on: June 10, 2012, 07:11:28 AM »
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

  • Global Moderator
  • Member
  • *****
  • Posts: 63
    • Solar_OS, Solar_Asm and HE RTS Game
Re: Preservation of esi, edi, ebx in general code
« Reply #21 on: June 10, 2012, 08:33:48 AM »
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

  • Guest
Re: Preservation of esi, edi, ebx in general code
« Reply #22 on: June 10, 2012, 09:54:03 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

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: Preservation of esi, edi, ebx in general code
« Reply #23 on: June 10, 2012, 10:02:10 AM »
you are right, Ryan
most functions do return a result in EAX, however
but - you could do something like...
Code: [Select]
        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)
Code: [Select]
        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