wonderful (eh... i missed this thread a long time ago!) so this prove me that macro isn't bad after all. it's just an alternative way of coding something that masm can't provide.

hey rake, do you think you can explain how the switch/case works in pseudo code? or the logic behinds it? (you know, i feel very odd using code that i don't understand the logic behinds it...)
Posted on 2001-07-21 07:43:14 by disease_2000

disease_2000, I thought no one was going to ask. :) I designed it by knowing when MASM evaluates expressions - the algorithms are very simple - the macro language is hard to read. I guess I could comment the code and repost it. If I don't, I'll most likely forget how it works in a couple weeks. :grin:

It's a bubble sort, and a binary tree transversal:
``````
; Bubble Sort by Andrew Howe
outerloop:  lea     ebx,[edi+ecx*4]
mov     eax,[edi]
cmploop:    sub     ebx,4
cmp     eax,[ebx]
jle     notyet
xchg    eax,[ebx]
notyet:     cmp     ebx,edi
jnz     cmploop
stosd
loop    outerloop
;-----------------------------------------
;Binary Tree Transverase of a Sorted Array by bitRAKE ( just now :P )
BiGLooP: ;ordered range is [esi, edi], transverse it like a tree!
mov eax,edi
sub eax,esi
sar eax,2 ;get # of dwords in range - 1
dec eax ;we take the one in the middle for this node!
jle Done ;1 or 2 nodes=(we are done with this branch)
sar eax,1 ;cut the list in half
push edi
push eax
lea edi,[esi+eax*4]
call BiGLooP
pop eax
pop edi
push eax
push esi
neg eax
lea esi,[edi+eax*4]
call BiGLoop
pop esi
pop eax
One:
; [esi+eax*4+4] is a pointer to a leaf
; do something here with that leaf
ret
Done: ;A leaf can end in a fork = two branches
jne One
call One
dec eax
jmp One``````

The binary tree is laid out flat to save memory sometimes and we have that nice sorted list :), or in this case because we can't have a real tree without much headache! It is very time consuming to add nodes to this tree - only use this method for pseudo-static trees in real code. Does this help a little? It's just an array of DWORDs, but I go through it like it was a btree. You know trees usually have big structures (*This, Level, *LeftNode, *RightNode) to allow you to add, delete, find itmes within them. This is a big waste for just an array of DWORDs that aren't that dynamic. If you want to load/save a btree fast to disk then you might want to remember this code. Or you could search an array fast with this method.
Posted on 2001-07-21 15:02:36 by bitRAKE
I've added some comments. Please ask specific questions and I'll at least direct you to the propper sections of chapter 9 of the manual.

Does anyone have any problems or additions for my macro?

Code on y'all! :alright:
Posted on 2001-07-22 18:38:50 by bitRAKE
there's a problem with *txt file. i think Hiro should fix this problem....
Posted on 2001-07-23 15:10:11 by disease_2000
Please, describe what you mean if you are going to make such a statement. I have no problem with either file. That kind of statement just confuses without explaination. :rolleyes:
Posted on 2001-07-23 17:10:47 by bitRAKE
I noticed Andrew Howe's bubblesort code, and since John Eckerdal (Assembly Gems) never posted the smaller version I sent to him, here it is :-)

``````
;=====================================================================
;   16 byte bubblesort by Joergen Ibsen / Jibz <jibz@hotmail.com>
;     enter:  edi -> array
;             ecx =  #elements
;     exit:   edi -> array
;             ecx =  0
;     modify: ecx
;=====================================================================
outerloop:
pushad                         ; save edi and ecx
mov     esi, edi
innerloop:
lodsd
cmp     eax, [esi]              ; do we need to swap?
jge     order_ok
xchg    eax, [esi]              ; if so, this is first step
order_ok:
stosd                         ; second step, or just write back eax
loop    innerloop
popad                         ; pop edi and ecx
loop    outerloop             ; ecx is used for both loops
``````
Posted on 2001-08-17 14:14:08 by Jibz
Cool, thanks. I think we really need a code repository for assembly.
Posted on 2001-08-17 14:20:02 by bitRAKE

;################################## ; bitRAKE (aka Rickey Bowers Jr.) ;################################## ; please, forward changes: ; bitRAKE@home.com ;################################## ; If you read Chapter 9 of the MASM ; manual you will understand this. ;################################## ;ToDo: ; A little error checking wouldn't hurt w/ intelligent error messages... ; Allow any memory, register value to switch on... ;Improvements: ; Switch stack for nexted switch statements - I don't think so! ; weighted case matching instead of balanced ; radix jump tables on sequencial values ;################################## ;General Notes: ; This is not the easiest code to try an explain, please ask questions. SwitchThreshHold = 3 ;when is a bad idea to partition @switch MACRO def SwitchNodes = 0 SwitchDefault TEXTEQU <&def> SwitchExit TEXTEQU <> ENDM @case MACRO xVal:REQ, xNode:REQ @CatStr(, %SwitchNodes) = &xVal @CatStr(, %SwitchNodes) TEXTEQU <&xNode> SwitchNodes = SwitchNodes + 1 ENDM @endswitch MACRO sexit LOCAL TheEnd, ww, oo, temp1, temp2, temp3, temp4 SwitchExit TEXTEQU <&sexit> ;; This is a bubble sort on the values of the case statements ;; the labels follow their associated values. ww = SwitchNodes WHILE ww ww = ww - 1 oo = ww WHILE oo oo = oo - 1 temp1 = @CatStr(, %oo) temp2 = @CatStr(, %ww) ;; We need MASM to evaluate this at assemble-time % IF &temp1 GT &temp2 ;; Numberic values can be swaped easily @CatStr(, %oo) = &temp2 @CatStr(, %ww) = &temp1 ;; Strings are a little harder... ;; Get the variable names temp3 TEXTEQU @CatStr(, %oo) temp4 TEXTEQU @CatStr(, %ww) ;; Get the value of those varibles ;; MASM doesn't allow &@CatStr(...)! temp3 TEXTEQU &temp3 temp4 TEXTEQU &temp4 ;; Swap them @CatStr(, %oo) TEXTEQU &temp4 @CatStr(, %ww) TEXTEQU &temp3 ENDIF ENDM ENDM ;; This starts the trasversal of the array as if it were a bbtree @SwitchPartition 0, SwitchNodes - 1 ;; Output the code for the case nodes that haven't been done already ww = SwitchNodes WHILE ww ww = ww - 1 ;; Previously output nodes are cleared in the transveral % IFNB <@CatStr(, %ww)> @CatStr(, %ww, <:>) % @CatStr(, %ww) IFNB <&SwitchExit> % &SwitchExit ELSE jmp SwitchExitLabel ENDIF ENDIF ENDM SwitchDefaultLabel: IFNB <&SwitchDefault> % &SwitchDefault IFNB <&SwitchExit> % &SwitchExit ENDIF ENDIF SwitchExitLabel: ENDM ;; Transverse the sorted array of variables that was created for each ;; case statement like a balanced binary tree... @SwitchPartition MACRO _min:REQ, _max:REQ LOCAL delta, mmin, HighHalf delta = _max - _min mmin = _min IF delta LT SwitchThreshHold ;; Output a string of nodes comparisons and a node on the end WHILE delta GT 0 % cmp eax, @CatStr(, %mmin) je @CatStr(, %mmin) mmin = mmin + 1 delta = delta - 1 ENDM % cmp eax, @CatStr(, %mmin) jne SwitchDefaultLabel % @CatStr(, %mmin) ;; Clear this label variable so we don't output the code again @CatStr(, %mmin) TEXTEQU <> IFNB <&SwitchExit> % &SwitchExit ELSE jmp SwitchExitLabel ENDIF ELSE ;; Output a branch test delta = _min + (delta/2) % cmp eax, @CatStr(, %delta) jg HighHalf je @CatStr(, %delta) ;; Re-Enter this macro until we've tested all the nodes ;; note that we skip the node we just tested for. @SwitchPartition _min, (delta-1) ;; Lower half of the range HighHalf: @SwitchPartition (delta+1), _max ;; High half of the range ENDIF ENDM TestValue0 = 0 TestValue1 = 1 TestValue2 = 2 TestValue3 = 3 TestValue4 = 4 TestValue5 = 5 TestValue6 = 6 TestValue7 = 7 TestValue8 = 8 TestValue9 = 9 TestValue10 = 10 CaseRoutine0 MACRO mov eax, -1-0 ENDM CaseRoutine1 MACRO mov eax, -1-1 ENDM CaseRoutine2 MACRO mov eax, -1-2 ENDM CaseRoutine3 MACRO mov eax, -1-3 ENDM CaseRoutine4 MACRO mov eax, -1-4 ENDM CaseRoutine5 MACRO mov eax, -1-5 ENDM CaseRoutine6 MACRO mov eax, -1-6 ENDM CaseRoutine7 MACRO mov eax, -1-7 ENDM CaseRoutine8 MACRO mov eax, -1-8 ENDM CaseRoutine9 MACRO mov eax, -1-9 ENDM CaseRoutine10 MACRO mov eax, -1-10 ENDM CaseDefaultRoutine MACRO xor eax, eax ENDM CaseExitRoutine MACRO retn ENDM ;=================================================================== TestProc PROC ;eax is the test value @switch ;optional parameter @case TestValue2, ;These are mixed-up @case TestValue1, ;to demonstrate the @case TestValue0, ;sort code working. @case TestValue5, @case TestValue10, @case TestValue6, @case TestValue7, @case TestValue4, @case TestValue8, @case TestValue3, @case TestValue9, @endswitch ;optional parameter TestProc ENDP ;===================================================================

what to do with that. MASM complains.

japheth
Posted on 2001-08-20 10:14:28 by japheth
do "save target as " and open it in notepad or something

eko
Posted on 2001-08-20 10:16:59 by eko
thanks eko. got it now.

japheth
Posted on 2001-08-20 10:23:03 by japheth
Here is the code again:
Posted on 2002-02-13 09:03:25 by bitRAKE
Thanks a lot for having posted it again BitRAKE. ;)
Posted on 2002-02-13 17:19:04 by JCP