Seems this should be a very easy question, but I can't find the answer by Googling. I have some large macros in MASM that are fully-contained algorithm blocks. When debugging (in Visual Studio 2019), I am unable to trace into these macros. Example:
AlgoBlock MACRO Parm1, Parm2, Parm3
(20-30 instructions)
ENDM
Main PROC
....
AlgoBlock 1, 2, 3 <-- debugger will not step into this
AlgoBlock 4, 5, 6
AlgoBlock 7, 8, 9
ret
Main ENDP
I probably need to do something along the lines of enabling opening a macro-expanded listing, but I can't get any further. Thx for any help.
When debugging in source mode,the result depend only of the compiler and how .pdb and other files are made.
You can just try to insert an instruction to stop the debugger, like ,"mov eax,0".
My largest macros are several hundred lines long, e.g. deb (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019) at 851 lines, so I know what you are talking about. The short answer is you can't debug them.
The long answer is "your debugger (e.g. Olly (http://www.ollydbg.de/version2.html)) will show you only the few lines of real code inserted by the macro". Which may wildly differ from what you thought to see.
One way to look at it is the listing, enabled by assembler option /Fl (see also .listall and .nolist in the MASM manual).
Another way is echoing what the macro does. Example:
Int64 MACRO arg ; usage: movlps xmm0, Int64(0BBBBBBBBAAAAAAAAh)
Local tmp$
.DATA
tmp$ QWORD arg
% echo arg inserted in the data section
.CODE
echo now exiting
EXITM <tmp$>
ENDM
You can use that technique also for error messages:
is INSTR argC$, <shl 24>
ife is
tmp$ CATSTR <## line >, %@Line, <: first arg in RgbCol must be _alpha_ for Gdi+ pen ##>
% echo tmp$
.err
EXITM
endif
In this case, the macro stops the build and echoes to the output window ## line 123: first ... ##
To make debugging with Olly or similar easier, insert an INT 3:
int 3
inkey "where does this macro start and end?"
nops 8
int 3
Now you press F9 (in Olly) to run until the int 3 instruction, and you see immediately, thanks to 8 nop instructions, where your macro ended.
Thanks for the replies -- jj2007 in particular seems to understand exactly the issue. The problem in my case isn't the macro expansion itself though (that's fairly basic) but the actual algorithms, as they are heavily recursive and convoluted, so I really need to see the register values while single-stepping.
I found a partial solution on my own -- VS allows you to expand the assembly at a given point (I'd done this in HLLs before, but never tried it in ASM) by using the Ctrl-K,G chord. This shows you the macro expansion, though without symbolic imformation of course, just raw assembly. I'm going to experiment with jj2007's suggestion to look at the listing files -- there may be some way to have the debugger load them for trace-level debugging with symbolic info.
Quote from: FellGleaming on January 26, 2021, 02:07:12 AMI really need to see the register values while single-stepping.
Check the deb macro (http://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1019), it's part of MasmBasic (http://masm32.com/board/index.php?topic=94.0):
include \masm32\MasmBasic\MasmBasic.inc ; use instead of masm32rt.inc
.data
TwoQwords dq 1234567890abcdefh, 2222222222222222h
OneOword OWORD ?
.code
start:
mov ecx, chr$("a string")
mov eax, offset start
movups xmm0, TwoQwords
movups OneOword, xmm0
fldpi ; long live the FPU!
mov ebx, 1234567890
or eax, -1 ; set the sign? flag
deb 4, "Registers and flags remain intact", x:eax, ebx, $ecx, x:xmm0, x:OneOword, ST(0), flags
deb 4, "... as you can see", x:eax, ebx, $ecx, x:xmm0, x:OneOword, ST(0), flags
mov ecx, 15
.Repeat
PSLLDQ xmm0, 1
deb 6, "Shifting", x:xmm0 ; the "6" means show only the first 6 results
dec ecx
.Until Sign?
exit
end start
Output:
Registers and flags remain intact
x:eax FFFFFFFF
ebx 1234567890
$ecx a string
x:xmm0 22222222 22222222 12345678 90ABCDEF
x:OneOword 22222222 22222222 12345678 90ABCDEF
ST(0) 3.141592653589793238
flags: czSo
... as you can see
x:eax FFFFFFFF
ebx 1234567890
$ecx a string
x:xmm0 22222222 22222222 12345678 90ABCDEF
x:OneOword 22222222 22222222 12345678 90ABCDEF
ST(0) 3.141592653589793238
flags: czSo
Shifting x:xmm0 22222222 22222212 34567890 ABCDEF00
Shifting x:xmm0 22222222 22221234 567890AB CDEF0000
Shifting x:xmm0 22222222 22123456 7890ABCD EF000000
Shifting x:xmm0 22222222 12345678 90ABCDEF 00000000
Shifting x:xmm0 22222212 34567890 ABCDEF00 00000000
Shifting x:xmm0 22221234 567890AB CDEF0000 00000000
You can transform a macro into a procedure and after debug that program.
Put global variables instead of local variables just for test. Forgot now options to create simbolic debug.
AlgoBlock proc Parm1, Parm2, Parm3
(20-30 instructions)
AlgoBlock endp
Main PROC
....
int 3h ;debugger will stop here if you run your program, a breakpoint
;depends of your debugger, some will jump to next instruction and pause
;others will stop at int 3h address, so you need select next instruction and step from here
;or you can change ip/eip/rip address by hands.
invoke AlgoBlock 1, 2, 3
nop ;no operation
invoke AlgoBlock 4, 5, 6
nop
invoke AlgoBlock 7, 8, 9
ret
Main ENDP
Quote from: FellGleaming on January 26, 2021, 02:07:12 AM
Thanks for the replies -- jj2007 in particular seems to understand exactly the issue. The problem in my case isn't the macro expansion itself though (that's fairly basic) but the actual algorithms, as they are heavily recursive and convoluted, so I really need to see the register values while single-stepping.
I found a partial solution on my own -- VS allows you to expand the assembly at a given point (I'd done this in HLLs before, but never tried it in ASM) by using the Ctrl-K,G chord. This shows you the macro expansion, though without symbolic imformation of course, just raw assembly. I'm going to experiment with jj2007's suggestion to look at the listing files -- there may be some way to have the debugger load them for trace-level debugging with symbolic info.
debugger have different tabs for different kind of data to keep track of below in the debugger window,autos: is most current registers variables,locals:local variables...
rightclick and you can switch between hexadecimal or decimal showing values,hexadecimal is easier when you wanna know if logical AND,OR,XOR,NOT works correctly
I think you also can move over different variables and registers in edit source code while debugging and you can see their values
Some great info here, thx for all the replies. I am poring over the documentation for MasmBasic now, it looks like it will be very helpful in the long run.