echo, %out,
title, subttl, page, .list, .nolist, and .xlist. There
are several others, but these are the most important.echo and %out directives simply print
whatever appears in its operand field to the video display during assembly.
Some examples of echo and %out appeared in the
sections on conditional assembly and macros. Note that %out is
an older form of echo provided for compatibility with old source
code.. You should use echo in all your new code.title assembler directive assigns a title to your source
file. Only one title directive may appear in your program.
The syntax for this directive is
title text
MASM will print the specified text at the top of each page of the assembled
listing. subttl (subtitle) directive is similar to the title
directive, except multiple subtitles may appear within your source
file. Subtitles appear immediately below the title at the top of each page
in the assembled listing. The syntax for the subttl directive
is
subttl text
The specified text will become the new subtitle. Note that MASM will not
print the new subtitle until the next page eject. If you wish to place the
subtitle on the same page as the code immediately following the directive,
use the page directive (described next) to force a page ejection.page directive performs two functions- it can force
a page eject in the assembly listing and it can set the width and length
of the output device. To force a page eject, the following form of the page
directive is used:
page
If you place a plus sign, "+", in the operand field, then MASM
performs a page break, increments the section number, and resets the page
number to one. MASM prints page numbers using the format page command lets you set the printer
page width and length values. It takes the form:
page length, width
where length is the number of lines per page (defaults to 50, but 56-60
is a better choice for most printers) and width is the number of characters
per line. The default page width is 80 characters. If your printer is capable
of printing 132 columns, you should change this value to 132 so your listings
will be easier to read. Note that some printers, even if their carriage
is only 8-1/2" wide, will print at least 132 columns across in a condensed
mode. Typically some control character must be sent to the printer to place
it in condensed mode. You can insert such a control character in a comment
at the beginning of your source listing.list, .nolist, and .xlist directives
can be used to selectively list portions of your source file during assembly.
.List turns the listing on, .Nolist turns the
listing off. .Xlist is an obsolete form of .Nolist for
older code.
.list
.nolist
.xlist
in
and out instructions, which are really just special
mov instructions, and the echo/%out directives
that perform assembly-time output, not the run-time output you want. Is
there no way to do I/O from assembly language? Of course there is. You can
write procedures that perform the I/O operations like "read" and
"write". Unfortunately, writing such routines is a complex task,
and beginning assembly language programmers are not ready for such tasks.
That's where the UCR Standard Library for 80x86 Assembly Language Programmers
comes in. This is a package of procedures you can call to perform simple
I/O operations like "printf".include directive, when encountered in a source file,
switches program input from the current file to the file specified in the
parameter list of the include. This allows you to construct
text files containing common equates, macros, source code, and other assembler
items, and include such a file into the assembly of several separate programs.
The syntax for the include directive is
include filename
Filename must be a valid DOS filename. MASM merges the specified
file into the assembly at the point of the include directive.
Note that you can nest include statements inside files you
include. That is, a file being included into another file during assembly
may itself include a third file.include directive by itself does not provide separate
compilation. You could use the include directive to break up
a large source file into separate modules and join these modules together
when you assemble your file. The following example would include the
PRINTF.ASM and PUTC.ASM files during the assembly of your program:
include printf.asm
include putc.asm
<Code for your program goes here>
end
Now your program will benefit from the modularity gained by this approach.
Alas, you will not save any development time. The include directive
inserts the source file at the point of the include during
assembly, exactly as though you had typed that code in yourself. MASM still
has to assemble the code and that takes time. Were you to include all the
files for the Standard Library routines, your assemblies would take forever.include directive to include
source code as shown above. Instead, you should use the include directive
to insert a common set of constants (equates), macros, external procedure
declarations, and other such items into a program. Typically an assembly
language include file does not contain any machine code (outside of a macro).
The purpose of using include files in this manner will become
clearer after you see how the public and external declarations work.include directive provides you with all
the facilities you need to create modular programs. You can build up a library
of modules, each containing some specific routine, and include any necessary
modules into an assembly language program using the appropriate include
commands. MASM (and the accompanying LINK program) provides a better
way: external and public symbols. include mechanism is that once you've
debugged a routine, including it into an assembly wastes a
lot of time since MASM must reassemble bug-free code every time you assemble
the main program. A much better solution would be to preassemble the debugged
modules and link the object code modules together rather than reassembling
the entire program every time you change a single module. This is what the
public and extern directives provide for you.
Extrn is an older directive that is a synonym for extern.
It provides compatibility with old source files. You should always use the
extern directive in new source code.public and extern facilities, you must
create at least two source files. One file contains a set of variables and
procedures used by the second. The second file uses those variables and
procedures without knowing how they're implemented. To demonstrate, consider
the following two modules:
;Module #1:
public Var1, Var2, Proc1
DSEG segment para public 'data'
Var1 word ?
Var2 word ?
DSEG ends
CSEG segment para public 'code'
assume cs:cseg, ds:dseg
Proc1 proc near
mov ax, Var1
add ax, Var2
mov Var1, ax
ret
Proc1 endp
CSEG ends
end
;Module #2:
extern Var1:word, Var2:word, Proc1:near
CSEG segment para public 'code'
.
.
.
mov Var1, 2
mov Var2, 3
call Proc1
.
.
.
CSEG ends
end
Module #2 references Var1, Var2, and Proc1,
yet these symbols are external to module #2. Therefore, you must declare
them external with the extern directive. This directive takes
the following form:
extern name:type {,name:type...}
Name is the name of the external symbol, and type
is the type of that symbol. Type may be any of near,
far, proc, byte, word, dword, qword, tbyte, abs (absolute,
which is a constant), or some other user defined type. name to
see if the types agree. Therefore, you must exercise caution when defining
external symbols. The public directive lets you export a symbol's
value to external modules. A public declaration takes the form:
public name {,name ...}
Each symbol appearing in the operand field of the public statement
is available as an external symbol to another module. Likewise, all external
symbols within a module must appear within a public statement
in some other module.extern directive defines a symbol in your source
file. Any attempt to redefine that symbol elsewhere in your program will
produce a "duplicate symbol" error. This, as it turns out, is
the source of problems which Microsoft solved with the externdef directive.externdef directive is a combination of public
and extern all rolled into one. It uses the same syntax
as the extern directive, that is, you place a list of name:type
entries in the operand field. If MASM does not encounter another definition
of the symbol in the current source file, externdef behaves
exactly like the extern statement. If the symbol does appear
in the source file, then externdef behaves like the public
command. With externdef there really is no need to use
the public or extern statements unless you feel
somehow compelled to do so.externdef directive is that it
lets you minimize duplication of effort in your source files. Suppose, for
example, you want to create a module with a bunch of support routines for
other programs. In addition to sharing some routines and some variables,
suppose you want to share constants and macros as well. The include
file mechanism provides a perfect way to handle this. You simply
create an include file containing the constants, macros, and externdef
definitions and include this file in the module that implements your
routines and in the modules that use those routines:
Note that extern and public wouldn't work in
this case because the implementation module needs the public directive
and the using module needs the extern directive. You would
have to create two separate header files. Maintaining two separate header
files that contain mostly identical definitions is not a good idea. The
externdef directive provides a solution.
Within your headers files you should create segment definitions that match
those in the including modules. Be sure to put the externdef directives
inside the same segments in which the symbol is actually defined. This associates
a segment value with the symbol so that MASM can properly make appropriate
optimizations and other calculations based on the symbol's full address:
; From "HEADER.A" file:
cseg segment para public 'code'
externdef Routine1:near, Routine2:far
cseg ends
dseg segment para public 'data'
externdef i:word, b:byte, flag:byte
dseg ends
This text adopts the UCR Standard Library convention of using an ".a"
suffix for assembly language header files. Other common suffixes in use
include ".inc" and ".def".dependent-file : list of filesExample:
pgm.exe: pgma.obj pgmb.objThis statement says that "pgm.exe" is dependent upon pgma.obj and pgmb.obj. Any changes that occur to pgma.obj or pgmb.obj will require the generate of a new pgm.exe file.
pgm.exe: pgma.obj pgmb.obj ml /Fepgm.exe pgma.obj pgmb.obj(The "/Fepgm.exe" option tells MASM to name the executable file "pgm.exe.")
pgm.exe: pgma.obj pgmb.obj ml /Fepgm.exe pgma.obj pgmb.obj pgma.obj: pgma.asm ml /c pgma.asm pgmb.obj: pgmb.asm ml /c pgmb.asmThe nmake.exe program will process the first dependency line it finds in the file. However, the files pgm.exe depends upon themselves have dependency lines. Therefore, nmake.exe will first ensure that pgma.obj and pgmb.obj are up to date before attempting to execute MASM to link these files together. Therefore, if the only change you've made has been to pgmb.asm, nmake.exe takes the following steps (assuming pgma.obj exists and is up to date).
pgm.exe: pgma.obj pgmb.obj ml /Fepgm.exe pgma.obj pgmb.obj pgma.obj: pgma.asm pgm.a ml /c pgma.asm pgmb.obj: pgmb.asm pgm.a ml /c pgmb.asmNote that any changes to the pgm.a file will force nmake.exe to reassemble both pgma.asm and pgmb.asm since the pgma.obj and pgmb.obj files both depend upon the pgm.a include file. Leaving include files out of a dependency list is a common mistake programmers make that can produce inconsistent .exe files.