News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

New on Masm32 Forum and new in assembly language

Started by Drakasm, October 26, 2012, 12:48:14 AM

Previous topic - Next topic

qWord

Quote from: jj2007 on October 28, 2012, 05:07:20 AMWe often use the Switch/Case macro instead
no, You offten use the Switch/Case macro instead  :biggrin:
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on October 28, 2012, 05:50:31 AM
Quote from: jj2007 on October 28, 2012, 05:07:20 AMWe often use the Switch/Case macro instead
no, You offten use the Switch/Case macro instead  :biggrin:

Well, me, Michael, you and a few others ;-)

qWord

Quote from: jj2007 on October 28, 2012, 06:16:53 AM
Well, me, Michael, you and a few others ;-)
Da musstest du jetzt aber lange suchen und dann ist der ursprüngliche Code nicht mal von mir ;-D
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on October 28, 2012, 06:50:50 AM
...und dann ist der ursprüngliche Code nicht mal von mir ;-D

Na sowas, Freiherr vuz qBerg, haben wir also wieder mal das Zitieren vergessen??
:icon14:

qWord

MREAL macros - when you need floating point arithmetic while assembling!

dedndave

actually, this is quite efficient...
      mov eax,uMsg
      cmp eax,WM_DESTROY
      je  WindowDestruction
      cmp eax,WM_CREATE
      je  Creation
;
;


to be honest, i haven't disassembled a SWITCH/CASE implementation to see what it generates, though   :P

hutch--

They all take about the same in terms of overhead, depends how much typing you want to do. I have seen in old TASM code despatchers that more or less do the job but if you are really serious about the speed of a selection machanism, you use an address table so that every choice has the same instruction count.

Convenience goes for .IF blocks, the "switch" blocks are semantically a bit cleaner and if you enjoy the extra typing for no purpose, do it the hard way.  :P

dedndave

i tried a dispatch table, just to time it
a well-designed branch method is a little faster - and smaller

if you want it to be efficient, the best way i have found is to use something of a "tree"
where groups of message numbers are repeatedly split into smaller groups
when you get down to a group of 4 or 5 handled messages, dispatch it as above
this keeps most of the branches of the SHORT variety, rather than NEAR

Drakasm

Thanks K_F, jj2007, qWord, dedndave, hutch--.  :biggrin:
Quoteif you want it to be efficient, the best way i have found is to use something of a "tree"
where groups of message numbers are repeatedly split into smaller groups
when you get down to a group of 4 or 5 handled messages, dispatch it as above
this keeps most of the branches of the SHORT variety, rather than NEAR

I honestly didn't  know of the possibility of switch case.
I read the code proposed by jj2007 to realize how it works.  :icon_eek:

But this is what I wanted to ask.....  how i set up the whole code
is correct from the point of view of an assembly language programmer ?

or am I doing something wrong ? :icon_confused:




jj2007

Quote from: Drakasm on October 28, 2012, 06:23:44 PM
or am I doing something wrong ? :icon_confused:

No, you are not doing anything wrong. Your code works fine. The only argument here is readability for others, and for yourself when you need to change something two years later. It helps to use "standard" ways of coding. Here is a typical WndProc, first with Switch/Case, then with if/elseif/endif.

WndProc proc uses esi edi ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL rc:RECT, ps:PAINTSTRUCT
  SWITCH uMsg
  CASE WM_DESTROY
   invoke PostQuitMessage, NULL

  CASE WM_CREATE
   call CreateMyControls   ; lots of code, deserves a separate proc

  CASE WM_COMMAND   ; react here to menus and controls
   movzx eax, word ptr wParam   ; the Ids are in the lowword of wParam

   switch eax   ; to enhance readability, we use lowercase at level 2
   case IdMenuNew   ; feel free to call your own stuff here...
      invoke SendMessage, hStatic, WM_SETTEXT, 0, chr$("You clicked New")
   case IdButton1
      ; call MyButtonProc   ; lots of code, deserves a separate proc
   case IdEscape
;      MsgBox 0, chr$("Sure to exit?"), "Bye?", MB_YESNO
;      .if eax==IDYES
         invoke SendMessage, hWnd, WM_CLOSE, 0, 0   ; Escape: exit without asking!
         xor eax, eax
         jmp RetZeroOrOne   ; same as return 0 but shorter code
;      .endif
   default
      MsgBox 0, str$(eax), "Unknown ID, add to the list above:", MB_OK
   endsw

  CASE WM_PAINT
   ; invoke BeginPaint...
  ENDSW
  invoke DefWindowProc, hWnd, uMsg, wParam, lParam
 
RetZeroOrOne:
  ret

CreateMyControls:
  MsgBox 0, "A label placed inside the WndProc can access the local variables but must exit with retn, not ret", "Hi", MB_OK
  retn
WndProc endp


Now the same code but using .if/.elseif/.endif:

WndProc proc uses esi edi ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL rc:RECT, ps:PAINTSTRUCT
  .if uMsg==WM_DESTROY
   invoke PostQuitMessage, NULL

  .elseif uMsg==WM_CREATE
   call CreateMyControls   ; lots of code, deserves a separate proc

  .elseif uMsg==WM_COMMAND   ; react here to menus and controls
   movzx eax, word ptr wParam   ; the Ids are in the lowword of wParam

   switch eax         ; somewhat inconsistent, there should be if/else/endif again ;-)
   case IdMenuNew   ; feel free to call your own stuff here...
      invoke SendMessage, hStatic, WM_SETTEXT, 0, chr$("You clicked New")
   case IdButton1
      ; call MyButtonProc   ; lots of code, deserves a separate proc
   case IdEscape
;      MsgBox 0, chr$("Sure to exit?"), "Bye?", MB_YESNO
;      .if eax==IDYES
         invoke SendMessage, hWnd, WM_CLOSE, 0, 0   ; Escape: exit without asking!
         return 0
;      .endif
   default
      MsgBox 0, str$(eax), "Unknown ID, add to the list above:", MB_OK
   endsw

  .elseif uMsg==WM_PAINT
   ; invoke BeginPaint...
  .endif
  invoke DefWindowProc, hWnd, uMsg, wParam, lParam
  ret

CreateMyControls:
  MsgBox 0, "A label placed inside the WndProc can access the local variables but must exit with retn, not ret", "Hi", MB_OK
  retn
WndProc endp


Drakasm

QuoteThe only argument here is readability for others, and for yourself when you need to change something two years later. It helps to use "standard" ways of coding. Here is a typical WndProc, first with Switch/Case, then with if/elseif/endif.

Thank you for the demonstration (Switch/Case +  if/elseif/endif ) and for the advice.  :biggrin: