Does anyone know how to get a listing with fullly expanded macros from Masm32? The usual options in the source code didn't work the way I expected, and I don't see a setting in the IDE that came with the download. Maybe use the command line and use a switch?
Thanks.
If you are doing this in QEDITOR the only workable method that I am aware of is to create a makeit.bat (using Create makeit.bat on the Script menu) and modify the ML command line to include the necessary switches:
ML [ /options ] filelist [ /link linkoptions ]
/AT Enable tiny model (.COM file) /nologo Suppress copyright message
/Bl<linker> Use alternate linker /Sa Maximize source listing
/c Assemble without linking /Sc Generate timings in listing
/Cp Preserve case of user identifiers /Sf Generate first pass listing
/Cu Map all identifiers to upper case /Sl<width> Set line width
/Cx Preserve case in publics, externs /Sn Suppress symbol-table listing
/coff generate COFF format object file /Sp<length> Set page length
/D<name>[=text] Define text macro /Ss<string> Set subtitle
/EP Output preprocessed listing to stdout /St<string> Set title
/F <hex> Set stack size (bytes) /Sx List false conditionals
/Fe<file> Name executable /Ta<file> Assemble non-.ASM file
/Fl[file] Generate listing /w Same as /W0 /WX
/Fm[file] Generate map /WX Treat warnings as errors
/Fo<file> Name object file /W<number> Set warning level
/FPi Generate 80x87 emulator encoding /X Ignore INCLUDE environment path
/Fr[file] Generate limited browser info /Zd Add line number debug info
/FR[file] Generate full browser info /Zf Make all symbols public
/G<c|d|z> Use Pascal, C, or Stdcall calls /Zi Add symbolic debug info
/H<number> Set max external name length /Zm Enable MASM 5.10 compatibility
/I<name> Add include path /Zp[n] Set structure alignment
/link <linker options and libraries> /Zs Perform syntax check only
http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Appendix_C.htm
To run the batch file select Run Makeit.bat on the Project menu.
AFAIK generating a first pass listing (/EP) will always terminate with an error (so the source will not be assembled), even when the listing is generated. If your program contains the typical includes you should expect a large listing. By default the listing is printed to stdout. It would probably be more useful if you redirected it to a file.
Include this in your batch file
\masm32\bin\ml.exe /c /Fl "MyProgram.asm" > MyProgram.lst
You will get EVERYTHING and it can be extrembly large
Sorry about the above, it wont work. But the below will:
Save it as a .bat file
@echo off
\masm32\bin\ml.exe /c /Fl "MyProgram.asm"
if errorlevel 0 dir "MyProgram.*" >> %MyProgram.lst
\masm32\qeditor.exe MyProgram.lst
Using the following four listing control directives,
.NOCREF .NOLIST .LIST .LISTMACROALL
in your code will produce macro expansion
in a much shorter listing file.
.586
.model flat,stdcall
option casemap:none
.NOCREF
.NOLIST
--INCLUDES--
--INCLUDELIBS--
.LIST
.LISTMACROALL
---MACROS--
.data
---rest of code--
Thanks, dsouza123, I was also looking for that.
.LISTMACRO is an alternative to .LISTMACROALL
to list macro expansions that generate code or data
versus all statements
For looking at macro expansion, I tend to use the /EP option.
drv:\path\ml.exe /c /coff /EP yourfile.asm > dump.txt
In my post above I referred to generating a first pass listing using /EP. From the MASM 6.0 Programmer's Guide:
QuoteThe /EP command-line option may be used to produce a listing during the assembler's first pass. This listing is printed to standard output and is suitable for processing by the assembler. A first pass listing can be helpful for locating problems when there are many errors, or when unmatched nesting errors occur.
Although apparently not supported by MASM 6.0 or 6.1, MASM 6.14+ supports a /Sf switch for the /Fl option that is supposed to generate a first pass listing, so I decided to investigate this.
Using this source:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
.nolist
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\macros\macros.asm
.list
printv MACRO varname:VARARG
FOR arg, <varname>
invoke StdOut, reparg(arg)
ENDM
ENDM
NL equ SADD(13,10)
.data
buffer db 30 dup(0)
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
printv NL, chr$("Press enter to exit..."), NL
invoke StdIn, addr buffer, 1
exit
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
The /Fl listing is 1.38MB, the /FL /Sf listing 2.34MB, and the /EP listing 1.05MB. The /Sf switch adds ~1MB to the /Fl listing, but here is the portion that is specifically labeled as first pass:
Microsoft (R) Macro Assembler Version 6.14.8444 12/31/04 13:32:59
First Pass 1 - 1
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
.nolist
.list
printv MACRO varname:VARARG
FOR arg, <varname>
invoke StdOut, reparg(arg)
ENDM
ENDM
NL equ SADD(13,10)
.data
buffer db 30 dup(0)
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
printv NL, chr$("Press enter to exit..."), NL
2 .data
2 .code
3C .data
3C .code
3C .data
3C .code
invoke StdIn, addr buffer, 1
exit
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
And here is the macro expansion part of the /EP listing:
.data
buffer db 30 dup(0)
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
??0019 db "Press enter to exit...",0
.code
quot SUBSTR <NL>,1,1
.data
??001B db 13,10,0
align 4
.code
invoke StdOut, ADDR ??001B
quot SUBSTR <OFFSET ??0019>,1,1
invoke StdOut, OFFSET ??0019
quot SUBSTR <NL>,1,1
.data
??001E db 13,10,0
align 4
.code
invoke StdOut, ADDR ??001E
invoke StdIn, addr buffer, 1
invoke ExitProcess, 0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
So the two are obviously not equivalent.
Use .nolist & .listall in source file.
.listall can extande Macro .
\masm32\bin\ml /c /Sc /Sl 250 /Fl /Sn /coff %1.asm
Quote from: Kestrel on December 31, 2004, 10:35:30 PM
Use .nolist & .listall in source file.
.listall can extande Macro .
\masm32\bin\ml /c /Sc /Sl 250 /Fl /Sn /coff %1.asm
Yes, thanks for pointing that out. :U The resulting listing for /Fl /Sf contained several strings of nulls that I had to remove before I could post it, but the listing seems to include quite a bit more than the /EP listing.
Microsoft (R) Macro Assembler Version 6.14.8444 12/31/04 17:47:32
First Pass 1 - 1
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
.nolist
.listall
printv MACRO varname:VARARG
FOR arg, <varname>
invoke StdOut, reparg(arg)
ENDM
ENDM
NL equ SADD(13,10)
00000000 .data
buffer db 30 dup(0)
00000000 .code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
printv NL, chr$("Press enter to exit..."), NL
0000001E 2 .data
2 ??0019 db "Press enter to exit...",0
00000000 2 .code
2 EXITM <OFFSET ??0019>
1 FOR arg, <NL,OFFSET ??0019,NL>
1 invoke StdOut, reparg(arg)
1 ENDM
3 quot SUBSTR <NL>,1,1
3 IFIDN quot,<">
3 .data
3 ??001A db NL,0
3 .code
3 EXITM <ADDR ??001A>
3 ELSE
3 EXITM <NL>
3C EXITM <ADDR literal(13,10)>
00000035 3C .data
3C ??001B db 13,10,0
3C align 4
00000000 3C .code
3C EXITM <??001B>
2 invoke StdOut, ADDR ??001B
3 quot SUBSTR <OFFSET ??0019>,1,1
3 IFIDN quot,<">
3 .data
3 ??001C db OFFSET ??0019,0
3 .code
3 EXITM <ADDR ??001C>
0
3 ELSE
3 EXITM <OFFSET ??0019>
2 invoke StdOut, OFFSET ??0019
3 quot SUBSTR <NL>,1,1
3 IFIDN quot,<">
3 .data
3 ??001D db NL,0
3 .code
3 EXITM <ADDR ??001D>
3 ELSE
3 EXITM <NL>
3C EXITM <ADDR literal(13,10)>
0000003B 3C .data
3C ??001E db 13,10,0
3C align 4
0000001E 3C .code
3C EXITM <??001E>
2 invoke StdOut, ADDR ??001E
invoke StdIn, addr buffer, 1
exit
1 invoke ExitProcess, 0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start