The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: hutch-- on June 18, 2008, 11:44:41 AM

Title: Multi value debugging macro.
Post by: hutch-- on June 18, 2008, 11:44:41 AM
I am doing a job at the moment that needs to show multiple values at any given point of the procedure so I put this macro together. It suits my purpose at the moment to show signed values but it could be twiddled easily enough to do unsigned.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    mbDebug MACRO txt_title,args:VARARG
      LOCAL buff,bptr,slen,rslt
      pushad
      pushfd
      .data?
        buff db 8192 dup (?)
      .data
        bptr dd buff
      .code
        mov eax, OFFSET buff
        mov DWORD PTR [eax], 0
        for arg, <args>
          quot SUBSTR <arg>,1,1
            IFIDN quot,<">
              mov bptr, cat$(bptr,arg)
            ELSE
              mov bptr, cat$(bptr,sstr$(arg),"    ")
            ENDIF
        ENDM
        fn MessageBox,0,rslt,txt_title,MB_OK
      popfd
      popad
    ENDM

    .code

start:

    call main
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    LOCAL var1  :DWORD
    LOCAL var2  :DWORD
    LOCAL var3  :DWORD

    mov var1, 111
    mov var2, 222
    mov var3, 333

    mbDebug "Debug Test","var1 = ",var1,"var2 = ",var2," var3 = ",var3

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 18, 2008, 12:07:20 PM
Nice, but the fn MessageBox throws an error on my installation (Masm32 v10 of 26.5.2008).
This one works fine:

              mov bptr, cat$(bptr,sstr$(arg),chr$(13,10))  ; CrLf's look better ;-)
            ENDIF
        ENDM
        invoke MessageBox,0,addr buff, reparg(txt_title),MB_OK
        ; fn MessageBox,0,rslt, txt_title,MB_OK

Errors:
tmp_file.asm(47) : error A2006: undefined symbol : ??001C
fn(5): Macro Called From
  mbDebug(20): Macro Called From
   tmp_file.asm(47): Main Line Code
tmp_file.asm(47) : error A2114: INVOKE argument type mismatch : argument : 2
fn(5): Macro Called From
  mbDebug(20): Macro Called From
   tmp_file.asm(47): Main Line Code
Title: Re: Multi value debugging macro.
Post by: hutch-- on June 18, 2008, 01:23:11 PM
jj,

Have you changed anything, the macro should be able to pass a quoted text and the cat$ macro should be able to put it into the list.
Title: Re: Multi value debugging macro.
Post by: herge on June 18, 2008, 02:26:18 PM
 Hi jj:

I get similiar errors.


C:\masm32\bin>/masm32/bin/ML.exe /c /coff /Zi /Zd /nologo dbgmac.asm
Assembling: dbgmac.asm
dbgmac.asm(49) : error A2006: undefined symbol : ??001C
fn(5): Macro Called From
  mbDebug(19): Macro Called From
   dbgmac.asm(49): Main Line Code
dbgmac.asm(49) : error A2114: INVOKE argument type mismatch : argument : 2
fn(5): Macro Called From
  mbDebug(19): Macro Called From
   dbgmac.asm(49): Main Line Code


This is a very recent install.

Regards herge.
Title: Re: Multi value debugging macro.
Post by: hutch-- on June 18, 2008, 02:31:37 PM
I may have posted the wrong one.

Try this.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    mbDebug MACRO txt_title,args:VARARG
      LOCAL buff,bptr
      pushad
      pushfd
      .data?
        buff db 8192 dup (?)
      .data
        bptr dd buff
      .code
        mov eax, OFFSET buff
        mov DWORD PTR [eax], 0
        for arg, <args>
          quot SUBSTR <arg>,1,1
            IFIDN quot,<">
              mov bptr, cat$(bptr,arg," ")
            ELSE
              mov bptr, cat$(bptr,sstr$(arg),"     ")
            ENDIF
        ENDM
        fn MessageBox,0,bptr,txt_title,MB_OK
      popfd
      popad
    ENDM

    .code

start:

    call main
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    LOCAL var1  :DWORD
    LOCAL var2  :DWORD
    LOCAL var3  :DWORD

    mov var1, 111
    mov var2, 222
    mov var3, 333

    mbDebug "Debug Test","var1 = ",var1,"var2 = ",var2,"var3 = ",var3

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start


Title: Re: Multi value debugging macro.
Post by: Jimg on June 18, 2008, 02:57:06 PM
====SNATCH=====

I like that macro, thanks Hutch.   I made a small change to reuse the buffer space for calling from multiple places-
    mbDebug MACRO txt_title,args:VARARG
      pushad
      pushfd
      ifndef mbDebugbuff
          .data?
            mbDebugbuff db 8192 dup (?)
            mbDebugbptr dd ?
          .code
      endif
        mov eax, OFFSET mbDebugbuff
        mov mbDebugbptr,eax
        mov DWORD PTR [eax], 0
        for arg, <args>
          quot SUBSTR <arg>,1,1
            IFIDN quot,<">
              mov mbDebugbptr, cat$(mbDebugbptr,arg," ")
            ELSE
              mov mbDebugbptr, cat$(mbDebugbptr,sstr$(arg),"     ")
            ENDIF
        ENDM
        fn MessageBox,0,mbDebugbptr,txt_title,MB_OK
      popfd
      popad
    ENDM
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 18, 2008, 03:04:59 PM
Quote from: hutch-- on June 18, 2008, 02:31:37 PM
I may have posted the wrong one.

Try this.

Yep, that one works, but mine with the CrLf's is more beautiful  :toothy
Title: Re: Multi value debugging macro.
Post by: herge on June 18, 2008, 06:24:55 PM

Hi hutch-:

It works for me!
Good Work.

Regards herge.
Title: Re: Multi value debugging macro.
Post by: hutch-- on June 19, 2008, 12:05:58 AM
I like both of the suggested mods, I originally wrote it to have different data for each call but Jims mod makes sense as it only ever displays data one at a time.

JJs change of putting a CRLF instead of the spacing is also something I would like as an option as I can see the use of both display formats. MAybe as an optional trailing parameter IFIDN arg, <CRLF> or similar.
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 19, 2008, 08:25:11 AM
I couldn't resist the temptation to refine it a little bit...

[attachment deleted by admin]
Title: Re: Multi value debugging macro.
Post by: hutch-- on June 20, 2008, 08:48:22 AM
jj,

It looks good. I would like to see a version that can do either horizontal display like the original or the vertical list that your version does. It only needs an extra argument, 0 or 1 and it could choose to do either.


macroname 0,"Tite text","arg1 = ",arg1 etc ....
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 20, 2008, 09:24:44 AM
Quote from: hutch-- on June 20, 2008, 08:48:22 AM
It looks good.
Thanks :green

We are quickly approaching perfection:

   mbDebug "Show me five variables:",\
   MyCounter, My2ndVar, MyThirdVar, MyFilePath$, MyGreets$

Full code attached.

[attachment deleted by admin]
Title: Re: Multi value debugging macro.
Post by: Jimg on June 20, 2008, 02:37:03 PM
jj-

Try running two or more mbdebugs in one program.

Also, once you get that fixed, if you set a permanent flag when the user stops a loop, you will not be able to use the macro again.
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 20, 2008, 02:55:13 PM
Quote from: Jimg on June 20, 2008, 02:37:03 PM
Try running two or more mbdebugs in one program.
Delete this line:
LOCAL mbDebugbptr
Thanks for the hint...

Quote
Also, once you get that fixed, if you set a permanent flag when the user stops a loop, you will not be able to use the macro again.

That's the whole point: You are stuck in an 1000 iterations loop and want to finish the proggie without killing it. So press Cancel and you are done. I've used that feature many times...
Title: Re: Multi value debugging macro.
Post by: Jimg on June 20, 2008, 04:35:12 PM
You may want to kill that particular loop, but further down in the program, you may want to look at different info with a different mbdebug.  Perhaps it should return a flag for the main program to test?
I can certainly see both sides of the issue, to each his own.

also, you can certainly save edx if you want to be able to print it-

push edx
mov edx, OFFSET mbDebugbuff
mov mbDebugbptr, edx
mov DWORD PTR [edx], 0
pop edx


or perhaps better don't use it at all-

push OFFSET mbDebugbuff
pop mbDebugbptr
mov byte ptr mbDebugbuff, 0
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 20, 2008, 05:34:47 PM
Quote from: Jimg on June 20, 2008, 04:35:12 PM
You may want to kill that particular loop, but further down in the program, you may want to look at different info with a different mbdebug.  Perhaps it should return a flag for the main program to test?
...
also, you can certainly save edx if you want to be able to print it-

You are full of good ideas, young man. Here is the luxury version ;-)

[attachment deleted by admin]
Title: Re: Multi value debugging macro.
Post by: hutch-- on June 22, 2008, 01:32:46 AM
Here is a variation that is probably more useful, instead of controling the display, it just creates a string that you can display at the console or in a GUI app in a messagebox, the titlebar or the statusbar. It has had Jim's mod done on it. I would like to see JJs version seperate so it can control the text as a column.



; code
    mov ptxt, mval$("Remainder =",rmnd,"algn =",algn)
    fn MessageBox,0,ptxt,"Results",MB_OK

; macro
     mval$ MACRO args:VARARG
      pushad
      pushfd
      IFNDEF @_buff_@
      .data?
        @_buff_@ db 1024 dup (?)
      .data
        @@_bptr_@@ dd @_buff_@
      .code
      ENDIF
        mov eax, OFFSET @_buff_@
        mov DWORD PTR [eax], 0
        for arg, <args>
          quot SUBSTR <arg>,1,1
            IFIDN quot,<">
              mov @@_bptr_@@, cat$(@@_bptr_@@,arg)
            ELSE
              mov @@_bptr_@@, cat$(@@_bptr_@@,sstr$(arg)," ")
            ENDIF
        ENDM
      popfd
      popad
      mov eax, OFFSET @_buff_@
      EXITM <eax>
    ENDM
Title: Re: Multi value debugging macro.
Post by: hutch-- on June 22, 2008, 04:25:11 AM
Since I have had some time to play with this today, here is a more powerful version that does either horizontal or column list style display with either signed or unsigned values.

Calling code

    mov ptxt, mval$("cPos=",cPos,lf,"tabSize=",tabSize,lf,"Remainder=",rmnd,lf,"algn=",*algn)
    print ptxt,13,10


Source code

    mval$ MACRO args:VARARG
    ;; ------------------------------------------------
    ;; macro accepts 4 classes of input
    ;;   1. quoted text
    ;;   2. unsigned value with a leading "*" EG *myval
    ;;   3. signed value
    ;;   4. a line feed using the notation "lf"
    ;; ------------------------------------------------
      pushad
      pushfd
      IFNDEF @_buff_@
      .data?
        @_buff_@ db 1024 dup (?)
      .data
        @@_bptr_@@ dd @_buff_@
      .code
      ENDIF
        mov eax, OFFSET @_buff_@
        mov DWORD PTR [eax], 0
        for arg, <args>
          char1 SUBSTR <arg>,1,1                                ;; get 1st character
          char2 SUBSTR <arg>,1,2                                ;; get 1st TWO characters
          char3 SUBSTR <arg>,2
            IFIDN char1,<">
              mov @@_bptr_@@, cat$(@@_bptr_@@,arg)              ;; add quoted text
              goto label0
            ENDIF
            IFIDN char2,<lf>
              mov @@_bptr_@@, cat$(@@_bptr_@@,chr$(13,10))      ;; add line feed
              goto label0
            ENDIF
            IFIDN char1,<*>
              item textequ char3
              mov @@_bptr_@@, cat$(@@_bptr_@@,ustr$(item)," ")  ;; add unsigned arg converted to string
              goto label0
            ENDIF
            mov @@_bptr_@@, cat$(@@_bptr_@@,sstr$(arg)," ")     ;; add signed arg converted to string
        :label0
        ENDM
      popfd
      popad
      mov eax, OFFSET @_buff_@
      EXITM <eax>
    ENDM
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 22, 2008, 08:15:22 AM
Quote from: hutch-- on June 22, 2008, 04:25:11 AM
Calling code

    mov ptxt, mval$("cPos=",cPos,lf,"tabSize=",tabSize,lf,"Remainder=",rmnd,lf,"algn=",*algn)
    print ptxt,13,10


For a debugging macro, I would refuse to type the var names twice... will stick to my version  :wink
Title: Re: Multi value debugging macro.
Post by: Jimg on June 22, 2008, 05:16:54 PM
Hutch-

Because it couldn't handle a single character variable name and I wanted to pass the name or address of a string, I was playing around-

    mvalx$ MACRO args:VARARG
    ;; ------------------------------------------------
    ;; macro accepts 6 classes of input
    ;;   1. quoted text
    ;;   2. unsigned value with a leading "*" EG *myval
    ;;   3. signed value
    ;;   4. a line feed using the notation "lf"
    ;;   5. name of a string variable if leading /  eg. /MyStr
    ;;   6. address of a string if leading //  eg. //MyStrAddr
    ;; ------------------------------------------------
      pushad
      pushfd
      IFNDEF @_buff_@
      .data?
        @_buff_@ db 1024 dup (?)
      .data
        @@_bptr_@@ dd @_buff_@
      .code
      ENDIF
        mov eax, OFFSET @_buff_@
        mov DWORD PTR [eax], 0
        for arg, <args>
          char1 SUBSTR <arg>,1,1                                ;; get 1st character
          if @SizeStr(<arg>) GT 1
            char2 SUBSTR <arg>,1,2                              ;; get 1st TWO characters
            char3 SUBSTR <arg>,2
            if @SizeStr(<arg>) GT 2
              char4 substr <arg>,3
            endif
          endif
            IFIDN char1,<">
              mov @@_bptr_@@, cat$(@@_bptr_@@,arg)              ;; add quoted text
              goto label0
            ENDIF
            IFIDN <arg>,<lf>
              mov @@_bptr_@@, cat$(@@_bptr_@@,chr$(13,10))      ;; add line feed
              goto label0
            ENDIF
            IFIDN char1,<*>
              item textequ char3
              mov @@_bptr_@@, cat$(@@_bptr_@@,ustr$(item)," ")  ;; add unsigned arg converted to string
              goto label0
            ENDIF
            if @SizeStr(<arg>) GT 2
                IFIDN char2,<//>
                  item textequ char4
                  mov @@_bptr_@@, cat$(@@_bptr_@@,<item>," ")  ;; was address of a string
                  goto label0
                ENDIF
            endif
            if @SizeStr(<arg>) GT 1
                IFIDN char1,</>
                  item textequ char3
                  mov @@_bptr_@@, cat$(@@_bptr_@@,addr(item)," ")  ;; was name of a string
                  goto label0
                ENDIF
            endif
            mov @@_bptr_@@, cat$(@@_bptr_@@,sstr$(arg)," ")     ;; add signed arg converted to string
        :label0
        ENDM
      popfd
      popad
      mov eax, OFFSET @_buff_@
      EXITM <eax>
    ENDM
.data
q     dd 99
cPos  dd 20
ptxt  dd 0
tSize dd 6
algn  dd 8
lfont dd 10
qtd db 'This is "quoted".',0
MyPath  db "MulDbgMacro.asm", 0
aMyPath dd txMyPath
.code
    mov ptxt, mvalx$("cPos=",cPos,lf,"tSize=",tSize,lf,"lfont=",lfont,lf ,"q = ",q,lf,"algn=",*algn,lf,"quoted=","This is ""quoted"".",lf,"quoted2=",/qtd,lf,"/path = ",/txMyPath,lf,"//path = ",//MyFilePath$)
    print ptxt,13,10

A big kludge at the moment, but might be worth a look.  There's probably a better way to distinguish strings but I couldn't think of one.
Title: Re: Multi value debugging macro.
Post by: jj2007 on June 22, 2008, 09:32:00 PM
Quote from: Jimg on June 22, 2008, 05:16:54 PM
There's probably a better way to distinguish strings but I couldn't think of one.
It depends on whether you are willing to commit the sacrilege of using $ as string suffix ;-)

I have tried to put my previous "luxury" and your version together, see attachment. You might ruthlessly steal some of my code to get register display and multi-slots working - at present eax, ecx and edx don't work. I discovered that my code can handle extra quotes, see the MsgBox, last line.

EolMode equ 13, 10
; EolMode equ 32,32,32,32 ; for horizontal display


I added this equate to allow horizontal display, although, frankly speaking, I can hardly imagine a situation where this would be advantageous.

EDIT: Is there a good explanation why...

   mov ptxt, mvalx$("cPos=",cPos,lf,"tSize=",tSize,lf,"lfont=",lfont,lf ,"q = ",q,lf,"algn=",*algn,lf,"quoted=",\
   "This is ""quoted"".",lf,"quoted2=",/qtd,lf,"/path = ",/txMyPath,lf,"//path = ",//MyFilePath$)

... the line continuation character is not being interpreted correctly?

[attachment deleted by admin]