News:

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

Main Menu

HJWasm .SWITCH - .CASE - .DEFAULT - .ENDSWITCH

Started by habran, April 10, 2016, 08:26:42 PM

Previous topic - Next topic

habran

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:
 
;//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

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:

         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

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



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

#3
deleted

habran

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:

.data?
align 32
testloc3 XMMWORD ? ;// not aligned 
align 32
testloc2 YMMWORD ? ;// aligned

in .data segment the first var is aligned


.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

nidud, Johnsa and I have concluded that .ENDSWITCH is more appropriate than .ENDSW and that we both like it more
Cod-Father

hutch--

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.

nidud

#7
deleted

nidud

#8
deleted

habran

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

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

#11
deleted

habran

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--

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.

habran

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