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

nidud

#45
deleted

HSE

Also I introduce a case with a value of 3500. MB is fast, but  become inmense for big values:
8151      cycles, rep(96), code(1828) for HJWASM
1481      cycles, rep(96), code(16461) for MB Switch_
28402     cycles, rep(96), code(1433) for Masm32 switch
27360     cycles, rep(96), code(1433) for ObjAsm switch
27170     cycles, rep(96), code(1439) for ifproc
hit any key to continue...

It's compiled with a HJWAsm modified for no collition with ObjAsm (.for is .forh, etc).

A diferent compilation with ASMC (some problem with MB):
6940      cycles, rep(96), code(1855) for ASMC
26649     cycles, rep(96), code(1433) for Masm32 switch
24479     cycles, rep(96), code(1433) for ObjAsm switch
29691     cycles, rep(96), code(1439) for ifproc
hit any key to continue...
Equations in Assembly: SmplMath

habran

Hi HSE,
are you using 32 bit or 64 bit HJWasm?
Cod-Father

HSE

32 bit.
Perfect:
swproc proc value ; OPT_Assembler asmc
mov eax,value
.SWITCHh eax                      ; this is the line 183
enum = 0
repeat count
%   .caseh @CatStr(%enum) ; nidud
;; .caseh enum                  ; JJ
mov eax,enum
.break
enum = enum + 1
endm                                    ; this is the line 191
        .caseh lejos
.defaulth
xor eax,eax
.break
        .endswitch
        @CCCD0:
           
ret
swproc endp


Without modification (only MASM32, no ObjAsm) :timeit2.asm(183) : Error A2209: Syntax error: .
timeit2.asm(191) : Error A2209: Syntax error: .
MacroLoop(1): iteration 1: Macro called from
  timeit2.asm(191): Main line code
Equations in Assembly: SmplMath

hutch--

If I have what is going on in this discussion, its the difference between the design of an assembler and algorithm design. A traditional "switch" block in C is a sequential set of comparisons and in most cases is easily fast enough in comparison to the high level code it is used in where if you are writing bare algorithms where there is a wide range of branching, you would normally write something like a table of label addresses and substantially reduce the search overhead for the right branch.

Now the example I used years ago was for a WndProc that instead of sequential comparisons, a zero filled array was allocated in dynamic memory then for each message that you wanted to process, you wrote the label address at the correct array offset. Now as most messages occur at under 1024, it meant you could run a 4k size array which is trivial by even old standards and for the odd message that is over 1024 you did a test first and shoved it somewhere else. In high level code which a Wndproc is you could not see the difference so while it was fast, it was a "who cares" improvement.

Now to address what is being done with this discussion on structuring a "switch" block in an assembler, when you start going into specific algorithm design you are going beyond an assembler design and entering into algorithm design which is probably best left to the individual genius of programmers. You could go down the path of adding runtime support for such a mechanism but then you are turning the assembler into a compiler which may not be the target you want.

HSE

Agree with the concepts.

Very effective idea(MB table and plain code):8580      cycles, rep(96), code(1828) for HJWASM
1706      cycles, rep(96), code(16463) for MB Switch_
895       cycles, rep(96), code(1438) for mixed <-----  hutch comcept
28583     cycles, rep(96), code(1433) for Masm32 switch
26762     cycles, rep(96), code(1433) for ObjAsm switch
22800     cycles, rep(96), code(1439) for ifproc
hit any key to continue...

Equations in Assembly: SmplMath

habran

HSE, that is not perfect yet because as far as I can see EXIT label is not getting constructed,  that is why you need to use @CCCD0 after the .endswitch

I have to find out why 32 bit doesn't run properly and fix it

try to use this code and see what will happen:
Quote
  mov eax,252
.switch eax
.case 273
     mov  edx,273 
     .break
    .case 280
     mov  edx,280 
    .break
.case 252
     mov  edx,252 
    .break
.case 274
      mov edx,274
    .break
.case 277
     mov  edx,277
    .break
.case 281
     mov  edx,281 
    .break
.case 269
     mov  edx,269
    .break
.case 282
     mov  edx,282
    .break
.case 283
     mov  edx,283
    .break
.case 286
     mov  edx,286
    .break
.default
     mov edx,0
     .break
.endswitch
Cod-Father

HSE

hab1.asm(67) : Error A2102: Symbol not defined : @CCCD0

With @CCCD0 there is no problem
Equations in Assembly: SmplMath

habran

Error A2102: Symbol not defined : @CCCD0 should not happen
I've been tying today to find a problem but on my computer I get error A2168: General Failure
Can you send me a source you are testing with please?
Cod-Father

HSE

Now I have the phone.
That results are with modified hjwasm. I obtain general failure or something like that with original one. Perhaps a collition with switch.
Equations in Assembly: SmplMath

jj2007

I am a bit confused with all these versions. Where exactly are latest executables of
- HJWasm with .switch
- asmc with .switch
??

habran

JJ2007, here
HSE, can you please send me that modified source, so that I can find where is the bug
Cod-Father

jj2007

Quote from: habran on April 14, 2016, 05:40:13 AM
JJ2007, here

Thanks. HJWasm32.exe gives me general failure with the timeit.asm test, while HJWasm64 complains about rax and rdx not defined for MENDSW ::)

AsmC builds testit.asm without errors. Same for this little testbed (the .breaks should really disappear :():
include \masm32\include\masm32rt.inc
.code
swproc proc value
mov eax, value
mov ecx, 7
.Switch eax
.Case 0
print "case 0", 13, 10
.break
.Case 1
print "case 1", 13, 10
.break
.Case 2
print "case 2", 13, 10
.break
.Case ecx
print "case ecx", 13, 10
.break
.Case 10 .. 20
print str$(eax), " (case 10 .. 20)", 13, 10
.break
.Default
print str$(eax), " (default)", 13, 10
.Endsw
ret
swproc endp
start:
  invoke swproc, -99
  invoke swproc, 0
  invoke swproc, 1
  invoke swproc, 2
  invoke swproc, 7
  invoke swproc, 10
  invoke swproc, 20
  invoke swproc, 99
  exit
end start


Output:
-99 (default)
case 0
case 1
case 2
case ecx
10 (case 10 .. 20)
20 (case 10 .. 20)
99 (default)


Under the hood it's a series of comparisons:
004010B4             ³> À83F8 00            cmp eax, 0
004010B7             ³. 0F84 54FFFFFF      je 00401011
004010BD             ³.  83F8 01            cmp eax, 1
004010C0             ³. 0F84 64FFFFFF      je 0040102A
004010C6             ³.  83F8 02            cmp eax, 2
004010C9             ³. 0F84 74FFFFFF      je 00401043
004010CF             ³.  3BC1               cmp eax, ecx
004010D1             ³. 74 89              je short 0040105C
004010D3             ³.  83F8 0A            cmp eax, 0A
004010D6             ³. 72 05              jb short 004010DD
004010D8             ³.  83F8 14            cmp eax, 14
004010DB             ³. 76 95              jbe short 00401072
004010DD             ³> EB B4              jmp short 00401093


habran

You are correct, HJWasm64 can run x64 only and HJWasm32 x86 only for the SWITCH
The 32 binaries from Teraspace cause general failure.

This attached version is a debug 32 version and it does a job properly if you assemble code bellow in this order I gave
If you change the order of the code it causes general failure, when I tested 32 bit in the first hand I had that code and that is why I thought that it runs OK. I don't understand why it causes general failure if I change the order of these code bellow :dazzled:


mov eax,252 
.switch eax
.case 2
     mov  edx,2 
     .break
.case 280
     mov  edx,280 
    .break
.case 252
     mov  edx,252 
    .break
.case 274
      mov edx,274
    .break
.case 277
     mov  edx,277
    .break
.case 281
     mov  edx,281 
    .break
.case 269
     mov  edx,269
    .break
.case 282
     mov  edx,282
    .break
.case 283
     mov  edx,283
    .break
.case 286
     mov  edx,286
    .break
.default
     mov edx,0
     .break
.endswitch

  mov eax,252
.switch eax
.case 273
     mov  edx,273 
     .break
    .case 280
     mov  edx,280 
    .break
.case 252
     mov  edx,252 
    .break
.case 274
      mov edx,274
    .break
.case 277
     mov  edx,277
    .break
.case 281
     mov  edx,281 
    .break
.case 269
     mov  edx,269
    .break
.case 282
     mov  edx,282
    .break
.case 283
     mov  edx,283
    .break
.case 286
     mov  edx,286
    .break
.default
     mov edx,0
     .break
.endswitch

  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


Cod-Father

HSE

Hi habran!

I just add a final "h" to .for, .switch, .case and .default.

Perhaps there is a confict with the "c" language switch (but not with switchh :biggrin:)
Equations in Assembly: SmplMath