After sending hours trying to determine why a macro I was working on was failing, I finally tracked the problem down to a coding detail in the pushtext and pushtxt macros, which I think is running afoul of a bug in the MASM text macro system. The problem is with recursive assignments in a single statement:
$text_stack$ CATSTR <name>, <#>, $text_stack$
@_txt_stack_@ CATSTR <arg^>,@_txt_stack_@
But only when the last equate pushed is otherwise assigned a value after it is pushed and before it is popped. A quick fix is to add a dummy equate that is pushed last and popped first, but a better fix is to split the recursive assignment into two statements:
_pushtext MACRO name:req
local tmp
tmp CATSTR <name#>, $text_stack$
$text_stack$ TEXTEQU tmp
ENDM
This illustrates the problem and the fix:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
equ1 TEXTEQU <>
equ2 TEXTEQU <>
test1 MACRO arg
%echo e1 = <equ1>
%echo e2 = <equ2>
echo push e1
pushtext equ1
echo push e2
pushtext equ2
echo assign 1 to e1
equ1 TEXTEQU <1>
echo assign 2 to e2
equ2 TEXTEQU <2>
%echo e1 = <equ1>
%echo e2 = <equ2>
echo pop e2
poptext equ2
%echo e2 = <equ2> <=== error
echo pop e1
poptext equ1
%echo e1 = <equ1>
echo
ENDM
equ3 TEXTEQU <>
equ4 TEXTEQU <>
test2 MACRO arg
%echo e3 = <equ3>
%echo e4 = <equ4>
echo push e3
pushtxt equ3
echo push e4
pushtxt equ4
echo assign 3 to e3
equ3 TEXTEQU <3>
echo assign 4 to e4
equ4 TEXTEQU <4>
%echo e3 = <equ3>
%echo e4 = <equ4>
echo pop e4
equ4 TEXTEQU poptxt$()
%echo e4 = <equ4> <=== error
echo pop e3
equ3 TEXTEQU poptxt$()
%echo e3 = <equ3>
echo
ENDM
_pushtext MACRO name:req
local tmp
tmp CATSTR <name#>, $text_stack$
$text_stack$ TEXTEQU tmp
ENDM
equ5 TEXTEQU <>
equ6 TEXTEQU <>
test3 MACRO arg
%echo e5 = <equ5>
%echo e6 = <equ6>
echo push e5
_pushtext equ5
echo push e6
_pushtext equ6
echo assign 5 to e5
equ5 TEXTEQU <5>
echo assign 6 to e6
equ6 TEXTEQU <6>
%echo e5 = <equ5>
%echo e6 = <equ6>
echo pop e6
poptext equ6
%echo e6 = <equ6> <=== no error
echo pop e5
poptext equ5
%echo e5 = <equ5>
echo
ENDM
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
test1
test2
test3
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Keep in mind the 256 character limit on these strings as well. It caught me out rather badly when I was doing something similar to this
Cheers,
Zooba :U