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
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
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.
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.
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
====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
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
Hi hutch-:
It works for me!
Good Work.
Regards herge.
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.
I couldn't resist the temptation to refine it a little bit...
[attachment deleted by admin]
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 ....
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]
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.
Quote from: Jimg on June 20, 2008, 02:37:03 PM
Try running two or more mbdebugs in one program.
Delete this line:
LOCAL mbDebugbptrThanks 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...
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
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]
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
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
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
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.
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]