Author Topic: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH  (Read 21205 times)

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« on: April 10, 2016, 08:26:42 PM »
Hi all,
Just a short introduction how to use a new feature in hjwasm.
It can be used with integers which need to be put in eax register.
Cases can contain decimal or hexadecimal integers.
Now you can also use hexadecimal numbers in C stile (0x or 0X) prefix.

.SWITCH can be used without 'eax', however, it is easier to understand code if 'eax' is present.
Inside the .case and .break you can write your code or function calling
The body of .SWITCH - .CASE - .DEFAULT - .ENDSWITCH must have all 4 elements present.


Here are some examples:
Code: [Select]
 
;//this one will use .if .elseif
mov eax,280
.switch eax
   .case 273
     mov  edx,273 
   .break
   .case 280
     mov  edx,280 
   .break
   .case 275
     mov edx,275
    .break
   .default
     mov edx,0
   .break
.endswitch

;//this one will use binary tree search because max - min is greater than 256
;//binary tree search is very fast and you can have cases more than 256
mov eax,252h
.switch eax
    .case 2
    .case 5
    .case 6
        mov  edx,2 
    .break
    .case 280h
       mov  edx,280h 
    .break
    .case 252h
       mov  edx,252h 
    .break
    .case 274h
        mov edx,274h
    .break
    .case 277
        mov  edx,277h
    .break
    .case 281
       mov  edx,281h 
    .break
    .case 269h
       mov  edx,269h
    .break
    .case 282h
       mov  edx,282h
    .break
    .case 283h
       mov  edx,283h
    .break
    .case 286h
       mov  edx,286h
    .break
    .default
     mov edx,0
     .break
.endswitch

;//this one will use jump table because max - min is inside 256
;//jump table is based on 1 byte pointer, that is why you can have maximum of 256 cases
  mov eax,0x1252
.switch eax
    .case 0x1273
       mov  edx,0x1273 
    .break
    .case 0x1280
       mov  edx,0x1280 
    .break
    .case 0x1252
       mov  edx,0x1252 
    .break
    .case 0x274
        mov edx,0x1274
    .break
    .case 277
       mov  edx,0x1277
    .break
    .case 0x1281
       mov  edx,0x1281 
    .break
    .case 0x1269
       mov  edx,0x1269
    .break
    .case 0x1282
       mov  edx,0x1282
    .break
    .case 0x1283
       mov  edx,0x1283
    .break
    .case 0x1286
       mov  edx,0x1286
    .break
    .default
       mov edx,0
    .break
.endswitch
Cod-Father

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #1 on: April 10, 2016, 08:47:53 PM »
I just want to tank Johnsa for request of that feature and for his involvement in designing, creating and testing it :t
I also thank you JJ2007 for your 'Magic Macro' although I could not use it as it was, but it gave me a great insight how to do it.
I also have to thank bitRake for his macro, which gave me some idea how to use binary tree search, although his binary tree search is recursive which can cause a stack overflow.
here is a simple but effective function which I used for the binary tree search:
Code: [Select]
         while (low <= high) {
            int mid = (low + high) / 2;
            if (pcases[mid] == casen)
              return mid;
            else if (pcases[mid] < x)
              low = mid + 1;
            else high = mid - 1;
        }
   
Cod-Father

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #2 on: April 10, 2016, 11:12:32 PM »
Now alignment 16 (xmm) or 32(ymm) byte for locals has been fixed in PROC FRAME
If you want locals to be aligned you have to put them on the top
There is a problem with 32 byte alignment because system doesn't give you 32 but 16 byte aligned
so we have to do it manually, at the start of our program, to make we have it aligned properly.
We should do it in the startup only ones and hjwasm will than take care that all next function have the proper alignment

I have to remind you as well that since AVX supports ymm registers we can not any more push xmm registers as parameters but ymm registers
so for example:
WinMain proc FRAME uses rbx xmm6 xmm7  hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:UINT
will cause an error. You have to use :
WinMain proc FRAME uses rbx ymm6 ymm7  hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:UINT


Code: [Select]
WinMainCRTStartup proc FRAME
    ;// Because the system doesn't provide 32 byte alignment
    ;// This four lines will ensure that alignment in next procedures
    mov  rax, [rsp]               ;// keep return address in rax
    add rsp, 32                   ;// make sure wee don't delete some important data on the stack
    and rsp, 0FFFFFFFFFFFFFFE0h   ;// align it to 32 byte
    mov [rsp], rax                ;// put return addres again on the stack
    invoke GetModuleHandleA, NULL
    mov    hInstance, rax
    invoke GetCommandLine
    mov    CommandLine, rax
    invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess, eax
WinMainCRTStartup endp

I attached one simple example to see how it looks like in 64 bite

Cod-Father

nidud

  • Member
  • *****
  • Posts: 1569
    • https://github.com/nidud/asmc
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #3 on: April 10, 2016, 11:20:20 PM »
Code: [Select]
.WHILE --> .ENDWHILE
.SWITCH --> .ENDSWITCH

Code: [Select]
.WHILE --> .ENDW
.SWITCH --> .ENDSW

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #4 on: April 10, 2016, 11:31:35 PM »
When aligning data to 32 or 64 byte (not bite) be aware that the first var in .data? segment will not be aligned
 but the second will:
Code: [Select]
.data?
align 32
testloc3 XMMWORD ? ;// not aligned 
align 32
testloc2 YMMWORD ? ;// aligned
in .data segment the first var is aligned

Code: [Select]
.data
align 32
testloc YMMWORD 0  ;// aligned to 32 byte
test1 dq 0                ;// aligned to 32 byte
align 32                   ;// after  QWWORD we have to align it again manualy
testloc1 YMMWORD 0;//aligned to 32 byte
Cod-Father

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #5 on: April 10, 2016, 11:39:14 PM »
nidud, Johnsa and I have concluded that .ENDSWITCH is more appropriate than .ENDSW and that we both like it more
 
Cod-Father

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5659
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #6 on: April 10, 2016, 11:58:22 PM »
Habran,

Why are you using the C format of .break ? There is no gain from doing it that way and even K&R thought that it should have been done in the original design of C as a language.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

nidud

  • Member
  • *****
  • Posts: 1569
    • https://github.com/nidud/asmc
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #7 on: April 11, 2016, 12:39:59 AM »
When are you going to release a version including this .switch?

Tried the x86 binary but it is still not a valid 32-bit exe.
Tried building from source but don’t seems to include the .switch.

nidud

  • Member
  • *****
  • Posts: 1569
    • https://github.com/nidud/asmc
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #8 on: April 11, 2016, 04:32:27 AM »
Manage to build a 32-bit version from the source, but it fails.

Code: [Select]
mov eax,280
.switch eax
   .case 273
     mov  edx,273
   .break
   .case 280
     mov  edx,280
   .break
   .case 275
     mov edx,275
    .break
   .default
     mov edx,0
   .break
.endswitch
;@CCCD0:

Code: [Select]
test.asm(19) : Error A2102: Symbol not defined : @CCCD0
test.asm(19) : Error A2102: Symbol not defined : @CCCD0
test.asm(19) : Error A2102: Symbol not defined : @CCCD0

If I add the missing label I get this:
Code: [Select]
; Disassembly of file: test.obj
; Sun Apr 10 20:18:10 2016
; Mode: 32 bits
; Syntax: MASM/ML
; Instruction set: 80386

.386
.model flat

FLAT    GROUP


_TEXT   SEGMENT DWORD PUBLIC 'CODE'                     ; section number 1

        mov     eax, 280                                ; 0000 _ B8, 00000118
        jmp     ?_002                                   ; 0005 _ EB, 1C

; Note: No jump seems to point here
        mov     edx, 273                                ; 0007 _ BA, 00000111
        jmp     ?_003                                   ; 000C _ EB, 2C

; Note: No jump seems to point here
        mov     edx, 280                                ; 000E _ BA, 00000118
        jmp     ?_003                                   ; 0013 _ EB, 25

; Note: No jump seems to point here
        mov     edx, 275                                ; 0015 _ BA, 00000113
        jmp     ?_003                                   ; 001A _ EB, 1E

?_001:  mov     edx, 0                                  ; 001C _ BA, 00000000
        jmp     ?_003                                   ; 0021 _ EB, 17

?_002:  cmp     eax, 273                                ; 0023 _ 3D, 00000111
        jz      ?_003                                   ; 0028 _ 74, 10
        cmp     eax, 280                                ; 002A _ 3D, 00000118
        jz      ?_003                                   ; 002F _ 74, 09
        cmp     eax, 275                                ; 0031 _ 3D, 00000113
        jz      ?_003                                   ; 0036 _ 74, 02
        jmp     ?_001                                   ; 0038 _ EB, E2

_TEXT   ENDS

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #9 on: April 11, 2016, 05:52:42 AM »
nidud, @CCCD0 means that labels are not saved in uint_16 *plabels;
I had that while working on it. Maybe Johnsa put an older version of hll.c
I will attach here the proper version and than see if it will work with it
Cod-Father

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #10 on: April 11, 2016, 06:09:17 AM »
Hi hutch :biggrin:
I don't understand what are you trying to say :dazzled:
.break is important part of HLL in masm, jwasm  and now in hjwasm
C uses break without a leading dot :icon_exclaim:
Please explain
Cod-Father

nidud

  • Member
  • *****
  • Posts: 1569
    • https://github.com/nidud/asmc
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #11 on: April 11, 2016, 06:15:55 AM »
Same result.

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #12 on: April 11, 2016, 06:23:58 AM »
What about if you add one more case
try with this if it works:

mov eax,280
.switch eax
   .case 273
     mov  edx,273
   .break
   .case 280
     mov  edx,280
   .break
   .case 275
     mov edx,275
    .break
   .case 283
     mov edx,283
    .break
   .default
     mov edx,0
   .break
.endswitch

I have to go now but I will be bck in about two hours than I will see if what is appening
if you will be here we can find what is the problem
It was working on my computer
Cod-Father

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5659
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #13 on: April 11, 2016, 09:24:47 AM »
Habran,

"break" or ".break" is a redundancy left over from the early days of C language design that is not needed in a "switch" block. A "switch" block should automatically exit each option to the end of the switch block.


switch condition
  case 1
    do this
  case 2
    do that
  case else
    do default
endsw(itch)


All "break" or ".break" gives you is extra typing. We already have a macro that does this in MASM32.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

habran

  • Member
  • *****
  • Posts: 1170
    • uasm
Re: HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH
« Reply #14 on: April 11, 2016, 09:53:58 AM »
Hi hutch,
thanks for that, sounds reasonable, I will see if I can make it work that way, I like the idea :t
Cod-Father