News:

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

Main Menu

bitRAKE's SWITCH MACRO

Started by habran, February 22, 2016, 08:57:29 PM

Previous topic - Next topic

jj2007

include \masm32\MasmBasic\MasmBasic.inc
  Init
  mov ecx, 3
  Switch_ ecx
  Case_ 0
PrintLine "0"
  Case_ 3
PrintLine "3"
  Default_
PrintLine "default"
  Endsw_
EndOfCode


0088107C             ³.  B9 03000000        mov ecx, 3
00881081             ³.  3B0D D0108800      cmp ecx, [8810D0]
00881087             ³.  8B15 CC108800      mov edx, [MbSw1L]
0088108D             ³. 7F 2B              jg short MbSw1D
0088108F             ³.  03D1               add edx, ecx
00881091             ³. 7C 27              jl short MbSw1D
00881093             À.  FF2495 D4108800    jmp near [edx*4+8810D4]
MbSw10               Ú>  68 50908800        push offset ra_lbl2
0088109F             ³.  6A 01              push 1
008810A1             ³.  6A 02              push 2
008810A3             ³.  E8 BE130000        call MbPrint
008810A8             À. EB 3A              jmp short MbSw1
MbSw11               Ú>  68 54908800        push offset ra_lbl3
008810AF             ³.  6A 01              push 1
008810B1             ³.  6A 02              push 2
008810B3             ³.  E8 AE130000        call MbPrint
008810B8             À. EB 2A              jmp short MbSw1
MbSw1D               Ú>  68 58908800        push offset ra_lbl4        ; ASCII "default"
008810BF             ³.  6A 01              push 1
008810C1             ³.  6A 02              push 2
008810C3             ³.  E8 9E130000        call MbPrint
008810C8             ³. EB 1A              jmp short MbSw1
008810CA             ³   8BFF               mov edi, edi
MbSw1L               ³.  00000000           dd 00000000
008810D0             ³.  03000000           dd 00000003
008810D4             ³.  9A108800           dd MbSw10
008810D8             ³.  BA108800           dd MbSw1D
008810DC             ³.  BA108800           dd MbSw1D
008810E0             ³.  AA108800           dd MbSw11
MbSw1                ³>  6A 00              push 0


habran

OK, jj2007, I will test it and report to you ;)
Cod-Father

habran

Are you kidding me :icon_eek:
What I was expecting is that you routine will not need to test for each occurrence and jump, but do something like this:
for 64 bit:
lea rax, @Jumptable
jmp [rax+rcx*8]

or for 32 bit:
jmp  @Jumptable[ecx*4]

not :
           cmp ecx,3
           jg @L1
           jmp  Case2
@L1:   cmp ecx,4
           jg @L2
           jmp  Case2
@L2:    cmp ecx,5
            jg @L3
           ---------
Cod-Father

jj2007

#18
Quote from: habran on February 24, 2016, 12:01:52 AM
jmp  @Jumptable[ecx*4]

see disassembly:
jmp near [edx*4+8810D4]

P.S.: In case you meant the two jumps, attached a special high performance version for use with plain Masm32. It saves 4 bytes (i.e. the two jumps), and should be significantly faster, too. All you have to do is to specify "unsafe" as the second argument.

include \masm32\include\masm32rt.inc
include SwitchUnsafe.mac
.code
start:
  m2m ecx, 1
  Switch_ ecx, unsafe
  Case_ 0
print "0"
  Case_ 3
print "3"
  Default_
print "default"
  Endsw_
  inkey chr$(13, 10, "bye")
  exit
end start

habran

jj2007 :t :eusa_clap:
It really works, I will test it more and come back to you :greenclp:
Cod-Father

habran

jj2007, this macro is a peace of art :dazzled:
There is only need to fix an overflow. If the number is greater than the greatest case than it jumps in a wilderness.
Can you make it to work in 64 bit?
Cod-Father

jj2007

Quote from: habran on February 24, 2016, 08:36:35 AMThere is only need to fix an overflow. If the number is greater than the greatest case than it jumps in a wilderness.

I don't understand. Can you post an example please?

habran

include \masm32\include\masm32rt.inc
include SwitchUnsafe.mac
.code
start:
  mov ecx, 18                    ;this will produce that jump
  Switch_ ecx, unsafe
  Case_ 0
   print "0"
  Case_ 3
   print "3"
  Default_
   print "default"
  Endsw_
  inkey chr$(13, 10, "bye")
  exit
end start
Cod-Father

jj2007

Just delete the "unsafe", and it will be safe (but 4 bytes longer) :P

  m2m ecx, 18
  Switch_ ecx

habran

Thank you, jj2007 :t
Now, what about 64 bit? Are you CANDO CAN'TDO? ;)
Cod-Father

jj2007


habran

there is something wrong it throws this error:
1>simple.asm(251): error A2048: Operands must be the same size: 4 - 8
Cod-Father

habran

mistake is somewhere here:
  @CatStr(<cmp >, tmp$, <, MbSw>, %MbSct, <L[4]>) ; max
  @CatStr(<mov rdx, MbSw>, %MbSct, <L>) ; min
  ifdifi <smode>, <unsafe>
@CatStr(<jg @MbSw>, %MbSct, <D>)
  endif
  @CatStr(<add rdx, >, tmp$)
  ifdifi <smode>, <unsafe>
@CatStr(<jl @MbSw>, %MbSct, <D>)
  endif
  @CatStr(<jmp MbSw>, %MbSct, <L[4*rdx+8]>)
Cod-Father

jj2007

Quote from: habran on February 24, 2016, 10:59:01 PM
mistake is somewhere here:
  @CatStr(<cmp >, tmp$, <, MbSw>, %MbSct, <L[4]>) ; max

Yes, it probably needs some adjustments, e.g. [8] instead of [4] etc

TWell

include SwitchUnsafe64.mac
extern ExitProcess :proc

.data
s1 db "0",0
s3 db "3",0
sd db "default",0

.code
start:
  sub rsp, 40
  mov rcx, 18         ;this will produce that jump
  Switch_ ecx;, unsafe
  Case_ 0
   mov rcx, offset s1
  Case_ 3
   mov rcx, offset s3
  Default_
   mov rcx, offset sd
  Endsw_
  xor ecx, ecx
  call ExitProcess
end ;start
ml64 -c SwitchUnsafe64.asm
Microsoft (R) Macro Assembler (x64) Version 14.00.23506.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Assembling: SwitchUnsafe64.asm
SwitchUnsafe64.asm(13) : error A2022:instruction operands must be the same size
Switch_(11): Macro Called From
  SwitchUnsafe64.asm(13): Main Line Code
SwitchUnsafe64.asm(13) : error A2022:instruction operands must be the same size
Switch_(15): Macro Called From
  SwitchUnsafe64.asm(13): Main Line Code
SwitchUnsafe64.asm(13) : error A2024:invalid operand size for instruction
Switch_(19): Macro Called From
  SwitchUnsafe64.asm(13): Main Line Code