News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

debug a macro?

Started by minor28, December 12, 2009, 12:14:14 PM

Previous topic - Next topic

minor28

How can I debug my macro code? Is it possible?

I have learning difficulties to write macros. I read "Masm programmer´s guide" and "Microsoft Macro Assembler Reference" so I have a fairly god knowledge of symbols and so on. As it is now I either get a compile error or the result is not the expected. I need to step through the macro to see what is happening. How do I do that?

dedndave

simply use the macro in a simple piece of code and debug it
when you debug, you are looking at the EXE
at that point, the macro has been expanded to the code that it represents
remember - macros are really a type of "text file helper"
they save you typing steps
dependong on the macro, it may be expanded differently with different usage
but that just makes it a complex text file helper - lol
that means that you may have to use it several ways to generate the code to fully test the macro

qWord

generate a listing by adding the commandline parameter  '/FlList.txt'  and '/Sn'.
I suggest you to write '.nolist' at the top of your Program - otherwise all includes will be listed.
Write '.listall / .nolist' around the macro-call to get information about it.
.nolist
include masm32rt.inc
...
.listall
mymacro ...
.nolist
...
FPU in a trice: SmplMath
It's that simple!

minor28

Thank you for your answers

dedndave:
I debug as you say but I can only see the result of the macro. I need to step through the macro to see what is happening.

qWord:
I did what you suggested and got a textfile with the same text as the macro I have already written. But how do I debug the macro?

qWord

In the listing files the expansion is shown step by step - this is the way to "debug" macros. An other technique is to add echo's inside the macro to print intermediate result in build console.
Here an simple example for listing:
.nolist
include masm32rt.inc

GetArg macro num,args:VARARG
cntr = 1
txt TEXTEQU <>
FOR arg,<args>
IF num EQ cntr
txt TEXTEQU <&arg>
EXITM
ENDIF
cntr = cntr + 1
ENDM
EXITM txt
endm

.listall
%echo GetArg(3,eax,edx,ecx,ebx,edi)
.nolist

.code
start:
ret
end start

the listing:
                include masm32rt.inc

                GetArg macro num,args:VARARG
                    cntr = 1
                    txt TEXTEQU <>
                    FOR arg,<args>
                        IF num EQ cntr
                            txt TEXTEQU <&arg>
                            EXITM
                        ENDIF
                        cntr = cntr + 1
                    ENDM
                    EXITM txt
                endm

= 00000001      1      cntr = 1
=               1      txt TEXTEQU <>
                 1      FOR arg,<eax,edx,ecx,ebx,edi>
                 1          IF 3 EQ cntr
                 1              txt TEXTEQU <&arg>
                 1              EXITM
                 1          ENDIF
                 1          cntr = cntr + 1
                 1      ENDM
                 2          IF 3 EQ cntr
                 2              txt TEXTEQU <eax>
                 2              EXITM
                 2          ENDIF
= 00000002      2          cntr = cntr + 1
                 2          IF 3 EQ cntr
                 2              txt TEXTEQU <edx>
                 2              EXITM
                 2          ENDIF
= 00000003      2          cntr = cntr + 1
                 2          IF 3 EQ cntr
= ecx           2              txt TEXTEQU <ecx>
                 2              EXITM
                 1      EXITM txt
                .listall
                    %echo GetArg(3,eax,edx,ecx,ebx,edi)
FPU in a trice: SmplMath
It's that simple!

dedndave

minor - i am no expert on macros, either   :bg
if i had a macro that i was having trouble with, i would post the code for it here and let these guys tell me what i was doing wrong
what you are trying to do is examine how the assembler interprets the macro definition
i really don't think there is a way to do that, per se

if you do not want to post the entire macro, simply make a simpler version of it with the same form, and post that
i.e. - same structure in terms of arguments, parameters, operators, and directives

some of these guys are "macro junkies" - i am sure they would love to help   :P

jj2007

The easiest way to understand what's going on is echo.  You can use it inside and outside of macros, and you will see what exactly are your current strings and numeric variables in the output window. Example below.

Quoteresults MACRO algo
LOCAL tmp$
   tmp$ CATSTR <print str$(eax), 9, "cycles for >, <algo>, <, ">
   % echo Step A: tmp$
   tmp$
   @CatStr(<mov eax, >, <algo>, <_endp>)
   @CatStr(<sub eax, >, <algo>)
   ifidn <algo>, <parseTable>
      add eax, ptEnd-pt+1
   elseifidn <algo>, <parseTableS>
      add eax, ptEndS-ptS+1
   elseifidn <algo>, <parseDave>
      add eax, ptEndS-ptS+1         ; we treat it as if the standard jumps had been used
      ;add eax, Build_T-Build+1
   endif
   print str$(eax), " bytes ", 9, "#h="
   print str$(NumH), ", #dots="
   print str$(NumDots), 13, 10
ENDM

dedndave

Danger !!! - Macro Junkie at Work    ^ ^ ^

qWord

echo numeric values using: %echo @CatStr(<myVar = >,%(myVar))
FPU in a trice: SmplMath
It's that simple!

minor28

Thank you all for your help. Now I understand little more and I have succeeded to watch my macro

Thank you

jj2007

There are quite a number of tricks to play with. Here is a test macro. In the output, I marked the less useful ones in red..

Quote"Hello"="Hello", ??001A=123 ;; ??001A: a locally generated variable
"Hello"="Hello", TheCt=123
myarg="Hello", 3*TheCt=369
@CatStr(<myarg=>, <"Hello">)
myarg="Hello"
@CatStr(<??001B=>, <??001B>)
Ciao bello=Ciao bello
Ciao bello=Ciao bello
mylocvar=Ciao bello
tmp_file.asm(35) : error A2052:forced error : That's me, I forced an error
include \masm32\include\masm32rt.inc

MyMac MACRO MyArg
LOCAL tmp$, ct, MyLocVar
  ct=123
  tmp$ CATSTR <MyArg=>, <MyArg>, <, ct=>, %ct
  % echo tmp$
  tmp$ CATSTR <MyArg=>, <MyArg>, <, TheCt=>, %ct
  % echo tmp$
  tmp$ CATSTR <myarg=>, <MyArg>, <, 3*TheCt=>, %ct*3
  % echo tmp$
  echo @CatStr(<myarg=>, <MyArg>)
  % echo @CatStr(<myarg=>, <MyArg>)

  MyLocVar equ <Ciao bello>
  echo @CatStr(<MyLocVar=>, <MyLocVar>)

  MyLocVar equ <Ciao bello>
  % echo @CatStr(<MyLocVar=>, <MyLocVar>)

  MyLocVar equ <Ciao bello>
  % echo @CatStr(<MyLocVar=>, MyLocVar)

  MyLocVar equ <Ciao bello>
  % echo @CatStr(<mylocvar=>, MyLocVar)

  .err <That's me, I forced an error>
ENDM

.data? ; non-initialised variables
MyVar dd ?

.code
start:
MyMac "Hello"
inkey "Press any key"
exit

end start

minor28

Thank you jj2007. I really appreciate your help. Now it is much easier to write macros.

Best regards