I've always thought it is a pity that macros have either the
DoStuff args or the
mov eax, DoStuff(args) form. Now I stumbled over a simple workaround: return an empty string as
exitm <>, and the macro becomes "standalone". Here is a simple example, using also a second feature
.if 1 ... .endif that prevents a user from forgetting the matching end macro.
Quote.nolist
include \masm32\include\masm32rt.inc
Timer MACRO arg
push ecx
push edx
invoke GetTickCount
pop edx
pop ecx
ifidni <arg>, <start>
.if 1
push eax
EXITM <> ;; the trick: return an empty string
else
pop edx
sub eax, edx
.endif
EXITM <eax>
endif
ENDM
.code
start:
Timer(start)
invoke Sleep, 500
print str$(Timer())
getkey
exit
end start
it's funny you mention that, Jochen
you know how much of a n00b i am with macros
but the other day when we were playing with CodeAlign, it dawned on me that
macros could "call" other macros and they could also be recursive
it would be interesting to see what you could do with that idea :bg
you could really do some trick stuff, i think
Hi Dave,
Okay, a macro quicksort should be your next project.
Just kidding, I can imagine the code generated though.
Probably wouldn't work out well as macros are compile
time and passing the data to sort as a literal argument
seems inefficient.
Cheers,
Steve N.
Quoteyou could really do some trick stuff, i think
perhaps i should have underlined "you" - lol
Jochen is the macro guy - not me
quicksort-macro ... nothing easier than this :toothy
(requies macros.asm)
quicksort macro array:=<>
qs_cnt = argcount(<&array>)
qs_arr TEXTEQU <>
IF qs_cnt NE 0
qs_arr TEXTEQU _quicksort(1,qs_cnt,<&array>)
ENDIF
EXITM qs_arr
endm
_quicksort macro left,right,array:=<>
LOCAL i,j,k,pivot,arr
i=left
j=right
pivot = getarg((left + right) / 2,<&array>)
arr TEXTEQU <&array>
WHILE i LE j
k = getarg(i,<%arr>)
WHILE k LT pivot
i = i + 1
k = getarg(i,<%arr>)
ENDM
k = getarg(j,<%arr>)
WHILE k GT pivot
j = j - 1
k = getarg(j,<%arr>)
ENDM
IF i LE j
arr TEXTEQU xchgarg(i,j,<%arr>)
i = i + 1
j = j - 1
ENDIF
ENDM
IF left LT j
arr TEXTEQU _quicksort(left,j,<%arr>)
ENDIF
IF i LT right
arr TEXTEQU _quicksort(i,right,<%arr>)
ENDIF
EXITM arr
endm
xchgarg macro pos1:req,pos2:req,list:=<>
LOCAL lx_1,lx_2
lx_cntr = 1
lx_tmp TEXTEQU <>
FOR param,<&list>
lx_param TEXTEQU <¶m>
IF lx_cntr EQ pos1
lx_param TEXTEQU <lx_1>
lx_2 TEXTEQU <¶m>
ENDIF
IF lx_cntr EQ pos2
lx_param TEXTEQU <lx_2>
lx_1 TEXTEQU <¶m>
ENDIF
IFNB lx_tmp
lx_tmp CATSTR lx_tmp,<,>,lx_param
ELSE
lx_tmp CATSTR lx_param
ENDIF
lx_cntr = lx_cntr + 1
ENDM
lx_tmp TEXTEQU lx_tmp
EXITM lx_tmp
endm
the most trickiest part was the xchgarg-macro.
works perfect with ml 10.x:
%echo <quicksort(<9,1,5,7,3,2,6,0,8,4>)>
%echo <quicksort(<500,7,1,4329,1,4,123,1235,73,888,552,111,1,6,9,12,12312,6,9,3,563,124,1324,34,234,23,4,1,7,68,8,1,12463,63,4,235,2,57,3>)>
=>echo:
<0,1,2,3,4,5,6,7,8,9>
<1,1,1,1,1,2,3,3,4,4,4,6,6,7,7,8,9,9,12,23,34,57,63,68,73,111,123,124,234,235,500,552,563,888,1235,1324,4329,12312,12463>
:green
Madman! :cheekygreen:
and it's recursive !!! :U
heh nice 1 qWord tested OK on 6.15 also
Hi,
Thank you very much! I think. At any rate excellent.
Regards,
Steve N.
well - it may generate a lot of code for long sorts
but it might be handy for short ones :bg
what made me think of recursive macros was the CodeAlign problem
the macro could do a partial align, then call itself (repeatedly, perhaps) until the alignment is complete
really - not a great idea as, if you are aligning more than 16 bytes, a JMP is in order (per Michael)
the thought of recursive macros was interesting, though
qWord,
A masterpiece. :U