The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: jj2007 on February 19, 2010, 04:45:45 PM

Title: Two-way MACRO
Post by: jj2007 on February 19, 2010, 04:45:45 PM
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
Title: Re: Two-way MACRO
Post by: dedndave on February 19, 2010, 08:37:45 PM
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
Title: Re: Two-way MACRO
Post by: FORTRANS on February 19, 2010, 10:00:04 PM
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.
Title: Re: Two-way MACRO
Post by: dedndave on February 19, 2010, 10:15:27 PM
Quoteyou could really do some trick stuff, i think

perhaps i should have underlined "you" - lol
Jochen is the macro guy - not me
Title: Re: Two-way MACRO
Post by: qWord on February 20, 2010, 12:00:48 AM
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 <&param>
IF lx_cntr EQ pos1
lx_param TEXTEQU <lx_1>
lx_2 TEXTEQU <&param>
ENDIF
IF lx_cntr EQ pos2
lx_param TEXTEQU <lx_2>
lx_1 TEXTEQU <&param>
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
Title: Re: Two-way MACRO
Post by: jj2007 on February 20, 2010, 12:15:47 AM
Madman! :cheekygreen:
Title: Re: Two-way MACRO
Post by: dedndave on February 20, 2010, 01:07:08 AM
and it's recursive !!!  :U
Title: Re: Two-way MACRO
Post by: oex on February 20, 2010, 04:35:53 AM
heh nice 1 qWord tested OK on 6.15 also
Title: Re: Two-way MACRO
Post by: FORTRANS on February 20, 2010, 03:08:12 PM
Hi,

   Thank you very much!  I think.  At any rate excellent.

Regards,

Steve N.
Title: Re: Two-way MACRO
Post by: dedndave on February 20, 2010, 04:37:45 PM
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
Title: Re: Two-way MACRO
Post by: hutch-- on February 21, 2010, 12:36:25 AM
qWord,

A masterpiece.  :U