(Untitled)

MASM32 Reference
Copyright The MASM32 Project 1998 - 2007

Using invoke
MASM High Level Syntax
Macro Reference
Full Listing
Register Summary
Ascii Characters
Calling Conventions
Processor Flags
Stack of 80-bit Data Registers
Conditional Assembly
Debugging in MASM32
Pentium Optimisation
Command Line Tools


Using invoke

Why use invoke ?
Popular legend has it that true low level assembler is written only at the mnemonic level and the rest is for people who do not properly understand what low level programming is about. The problem is for people who espouse this view is that they never produce anything much and when they do, it is usually of little consequence.

Few would understand that assembler is actually a high level language. At the hardware level, you only have opcodes and with the Intel x86 series of processors, the basic unit is a BYTE so when you use a mnemonic, you are using a high level simulation of a family of opodes that differ depending on the way the operands are arranged.

For people who are of such a robust disposition that they want to write in REAL low level code, the editor in MASM32 has the capacity to write hex directly as ascii text and save it to disk as a binary file. For the rest who want to write fast, reliable minimum size code and get it done in one lifetime, MASM has a pseudo high level syntax that has an exact correlation to code written the old hard way but without the errors, mysterious crashes and unresolvable bugs.

The traditional notation for calling procedures is the "push" parameter, "call" syntax. MASM has an alternative method of calling procedures which has many advantages in terms of both coding speed and reliability. A procedure called by INVOKE is type checked against a prototype of the same name for parameter size and number.

Traditional
push offset par4
push par3
push offset par2
push par1
call FunctionName
mov retval, eax

Invoke
invoke FunctionName,par1,ADDR par2,par3,ADDR par4
mov retval, eax

If there was an advantage in doing a function call the old way, you would bother but in this example, both assemble to the identical code but while the invoke syntax has reliable error checking against the prototype for the function that is called, the old way does not so if you put the wrong number of parameters or some other normal error, it will assemble but will crash when run.


MASM High Level Syntax

MASM has a number of built in operators that allow a programmer to use C style evaluation and loop code when writing high level Windows code that interfaces with the operating system.

More often than not, low level algorithms do not use any of the high level operators as it would produce suboptimal instruction sequences for maximum performance but much of the high level code inherant in Windows suffers from complexity rather than speed considerations and it is here where the C style high level emulation code provides its biggest advantage.

The .IF syntax allows conditional testing in a manner that makes high level Windows code far easier to both read and write. The alternative using "cmp reg, var", "jne label" produces nightmares in terms of tracking the number of jumps and labels needed and it does not perform any better or assemble any smaller.

.if uMsg == WM_COMMAND
  ;code
.elseif uMsg == WM_PAINT
  ;code
.elseif uMsg == WM_CLOSE
  etc ....

 MASM also has loop code techniques for emulating high level coding where it can be used to improve readability and maintainance.

The "condition" is evaluated using the Comparison run-time operators

Test condition at start of loop
.WHILE condition
  ; code that changes "condition"
.endw

Test condition at end of loop
.REPEAT
  ; code that changes "condition"
.until condition

 There are two methods of conditionally exiting the loops with the following operators with syntax variation depending on the task.
.BREAK
.BREAK .if condition
.CONTINUE
.CONTINUE .if condition

Example
    mov eax, 100

    .while eax > 0
      sub eax, 1
    .endw

  msgloop:
    invoke GetMessage, ADDR msg,NULL,0,0
    .break .if eax == 0
    invoke TranslateMessage, ADDR msg
    invoke DispatchMessage,ADDR msg
    jmp msgloop


MACRO Reference

One of MASM's great strengths is that it is a MACRO assembler which allows it to perform pre-processing of the text before the assembler reads the code and assembles the code. This allows the MASM programmer to wrote MACRO procedures that can expand or modify the text of the source code so that the source code can be written in convenient ways that improve the speed, reliability and throughput in the development cycle.

MACROS are the MASM programmers secret weapon in code production. Not only does the MASM programmer have the normal pseudo high level syntax to use for clear coding of complex decision making code, the "invoke" syntax for more reliable API calls and other function style procedures but they also have an almost unlimited method of expanding this capacity by writing MACROS that perform specific tasks in code manipulation.

MACROS can be used for many thing from simple text replacement, small inline conversions where the stack overhead of a procedure is bigger than the size of the expanded macro, complex looped expansion of repetitive code and in fact almost anything that will package code in more usable ways.

Basic Syntax
MACRO
ENDM
EXITM

Loop operators
FOR
FORC
GOTO
REPEAT
WHILE

Conditional testing
IF
ELSEIF
ELSE
ENDIF

Misc
Literal Text
MACRO LOCAL
PUSHCONTEXT
POPCONTEXT
 &parameter&
 Relational Operators
VARARG (Macro)
Nested Macros

Examples
Macro Function Reverse Ordering
Macro Function ArgI

Pre-defined operators for macros
CATSTR
INSTR
SIZESTR
SUBSTR


Full Listing

ALIGN ASSUME
.BREAK
.CODE
COMMENT
.CONST
.CONTINUE
.CREF
.NOCREF
.DATA
.DATA?
Data Types
ECHO
END
ENDM
EQU
TEXTEQU
.ERR
.ERRB
.ERRNB
.ERRDEF
.ERRNDEF
.ERRDIF
.ERRIDN
.ERRE
.ERRNZ
EXITM
EXTERNDEF
EXTERN
FOR
FORC
GOTO
IF
.IF
[ELSE]IF
[ELSE]IFE
[ELSE]IFB
[ELSE]IFNB
[ELSE]IFDEF
[ELSE]IFNDEF
[ELSE]IFDIF[I]
[ELSE]IFIDN[I]
INCLUDE
INCLUDELIB
INVOKE
LABEL
.LIST
.LISTALL
.LISTIF
.LISTMACRO
.LISTMACROALL
LOCAL
MACRO LOCAL
MACRO
.MODEL
.NOLIST
.NOLISTIF
.NOLISTMACRO
OPTION LJMP
OPTION NOLJMP
OPTION DOTNAME
OPTION NODOTNAME
OPTION READONLY
OPTION NOREADONLY
OPTION SCOPED
OPTION NOSCOPED
OPTION LANGUAGE
OPTION CASEMAP
OPTION EMULATOR
OPTION NOEMULATOR
OPTION OFFSET
OPTION PROLOGUE
OPTION EPILOGUE
OPTION NOKEYWORD
OPTION EXPR16
OPTION EXPR32
 OPTION SEGMENT OPTION NOSIGNEXTEND
OPTION PROC
ORG
PROC
PROTO
PUBLIC
PURGE
PUSHCONTEXT
POPCONTEXT
.RADIX
RECORD
REPEAT
.REPEAT
STRUCT
.TFCOND
TYPEDEF
TYPEDEF Directive
UNION
USES
WHILE
.WHILE
label:
Alternate Quotes
Literal Text
Character Negation
text comment
Macro text comment
Macro Expression
&parameter&
DUP
HIGH
LOW
HIGHWORD
LOWWORD
LENGTHOF
SIZEOF
LENGTH
SIZE
MASK
OFFSET
LROFFSET
PTR
SHORT
THIS
TYPE
OPATTR
WIDTH
CATSTR
INSTR
SIZESTR
SUBSTR
Local Code Labels
Line Continuation
Name Assignment
Location Counter $
Data Initialisation ?
Radix Specifiers
Logical Operators
Relational Operators
Macro Function ArgI
Macro Function Reverse Ordering
Register Summary
Processor Flags
Stack of 80-bit Data Registers
Comparison run-time operators
VARARG (Macro)
VARARG (Proc)
Calling Conventions
Memory model
.MODEL directive
Flat memory model
Nested Macros


register summary

Register Summary
The E register prefix refers to the full 32-bit register (386+)
Accumulator        [E]AX (AH/AL) Multiply, divide, I/O, fast arithmetic
Base               [E]BX (BH/BL) Pointer to base address (data segment)
Counter            [E]CX (CH/CL) Count for loops, repeats, and shifts
Data               [E]DX (DH/DL) Multiply, divide, and I/O

Source Index       [E]SI Source string and index pointer
Destination Index  [E]DI Destination string and index pointer
Base Pointer       [E]BP Pointer to stack base address
Stack Pointer      [E]SP Pointer to top of stack

Flags [E]<Flags> Processor flags
Instruction Pointer [E]IP Memory location of current instruction

Code Segment  CS Segment containing program code
Data Segment  DS Segment containing program data
Stack Segment SS Segment for stack operations
Extra Segment ES Extra program data segment
" FS Extra program data segment (386+)
" GS Extra program data segment (386+)

Control Registers CR(0-3) Paging, caching, and protection (386+)
Debug Registers DR(0-7) Data and instruction breakpoints (386+)
Test Registers TR(3-7) Testing the TLB and cache (386+)

Global Descriptor GDTR Address and limit of GDT (286+)
Local Descriptor LDTR Address, limit, and selector of LDT (286+)
Interrupt Descriptor IDTR Address and limit of IDT (286+)
Task Register TR Address, limit, selector, and attributes of current task


Ascii Characters

0  _ nul     16 _ dle ^P  32    48 0  64 @  80 P  96  `  112 p
1  _ soh ^A  17 _ dc1 ^Q  33 !  49 1  65 A  81 Q  97  a  113 q
2  _ stx ^B  18 _ dc2 ^R  34 "  50 2  66 B  82 R  98  b  114 r
3  _ etx ^C  19 _ dc3 ^S  35 #  51 3  67 C  83 S  99  c  115 s
4  _ eot ^D  20 ¶ dc4 ^T  36 $  52 4  68 D  84 T  100 d  116 t
5  _ enq ^E  21 § nak ^U  37 %  53 5  69 E  85 U  101 e  117 u
6  _ ack ^F  22 _ syn ^V  38 &  54 6  70 F  86 V  102 f  118 v
7  _ bel ^G  23 _ etb ^W  39 '  55 7  71 G  87 W  103 g  119 w
8  _ bs  ^H  24 _ can ^X  40 (  56 8  72 H  88 X  104 h  120 x
9  _ tab ^I  25 _ em  ^Y  41 )  57 9  73 I  89 Y  105 i  121 y
10 _ lf  ^J  26 _ eof ^Z  42 *  58 :  74 J  90 Z  106 j  122 z
11 _ vt  ^K  27 _ esc ^[  43 +  59 ;  75 K  91 [  107 k  123 {
12 _ np  ^L  28 _ fs  ^\  44 ,  60 <  76 L  92 \  108 l  124 |
13 _ cr  ^M  29 _ gs  ^]  45 -  61 =  77 M  93 ]  109 m  125 }
14 _ so  ^N  30 - rs  ^^  46 .  62 >  78 N  94 ^  110 n  126 ~
15 _ ¤ si ^O 31   us  ^_  47 /  63 ?  79 O  95 _  111 o  127 

The extended ascii characters generally do not display correctly with windows fonts.

128  Ç  144  É  160  á  176  _  192  +  208  -  224  _  240  _
129  ü  145  æ  161  í  177  _  193  -  209  -  225  ß  241  ±
130  é  146  Æ  162  ó  178  _  194  -  210  -  226  _  242  _
131  â  147  ô  163  ú  179  ¦  195  +  211  +  227  ¶  243  _
132  ä  148  ö  164  ñ  180  ¦  196  -  212  +  228  _  244  _
133  à  149  ò  165  Ñ  181  ¦  197  +  213  +  229  _  245  _
134  å  150  û  166  ª  182  ¦  198  ¦  214  +  230  µ  246  ÷
135  ç  151  ù  167  º  183  +  199  ¦  215  +  231  _  247  _
136  ê  152  ÿ  168  ¿  184  +  200  +  216  +  232  _  248  °
137  ë  153  Ö  169  _  185  ¦  201  +  217  +  233  _  249  •
138  è  154  Ü  170  ¬  186  ¦  202  -  218  +  234  _  250  ·
139  ï  155  ¢  171  ½  187  +  203  -  219  _  235  _  251  _
140  î  156  £  172  ¼  188  +  204  ¦  220  _  236  _  252  n
141  ì  157  ¥  173  ¡  189  +  205  -  221  ¦  237  _  253  ²
142  Ä  158  P  174  «  190  +  206  +  222  _  238  _  254  _
143  Å  159  ƒ  175  »  191  +  207  -  223  _  239  _  255


Calling Conventions

                              C    SYSCALL STDCALL  BASIC  FORTRAN  PASCAL
                          +-------+-------+-------+-------+-------+-------+
  Leading Underscore      |   X   |       |   X   |       |       |       |
                          |-------+-------+-------+-------+-------+-------|
  Capitalize All          |       |       |       |   X   |   X   |   X   |
                          |-------+-------+-------+-------+-------+-------|
  Arguments Left to Right |       |       |       |   X   |   X   |   X   |
                          |-------+-------+-------+-------+-------+-------|
  Arguments Right to Left |   X   |   X   |   X   |       |       |       |
                          |-------+-------+-------+-------+-------+-------|
  Caller Stack Cleanup    |   X   |       |   *   |       |       |       |
                          |-------+-------+-------+-------+-------+-------|
  BP Saved                |       |       |       |   X   |   X   |   X   |
                          |-------+-------+-------+-------+-------+-------|
  :VARARG Allowed         |   X   |   X   |   X   |       |       |       |
                          +-------+-------+-------+-------+-------+-------+

* The STDCALL language type uses caller stack cleanup if the :VARARG parameter is used. Otherwise, the called routine must clean up the stack.

The language type (langtype) determines the naming and calling conventions used by the assembler. This allows you to share code and data with modules written with other languages. Set the language type with the .MODEL or OPTION LANGTYPE: directives or with the /G<x> command-line option. Several directives allow you to specify a langtype parameter to temporarily override the language type.

You can use the /H command-line option to limit the length of names sent to the object file. Use this option to work with languages that limit the maximum length of identifiers.


Processor Flags

     1     1
     8     5               7             0
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |A|V|R|0|N|IO-|O|D|I|T|S|Z|0|A|0|P|1|C| -- Layout of flags register
    |C|M|F| |F|PL |F|F|F|F|F|F| |F| |F| |F|
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

     Flag                  If set:

     CF    Carry           Carry or borrow to destination operand
     PF    Parity          Even parity in low-order byte of result
     AF    Aux. Carry      Carry or borrow to low four-order bits
     ZF    Zero            Result equal to 0
     SF    Sign            Result has negative sign
     TF    Trap            Switches to single-step mode
     IF    Interrupt       Enables interrupts (disables if cleared)
     DF    Direction       String operations process down rather than up
     OF    Overflow        Result too large or small for destination
     IOPL  I/O             I/O Privilege Level for IN, INS, OUT, OUTS, Priv CLI, STI (286+)
     NF    Nested Task     Instruction caused nested task switch (286+)
     RF    Resume          Debug faults disabled during instruction execution (386+)
     VM    Virtual 8086    Currently executing 8086 code on virtual processor (386+)
     AC    Alignment       Data aligned to four-byte boundary (486+) Check


Stack of 80-bit Data Registers

            79 78     63 62                                     0
            +-+---------+---------------------------------------+
     ST     +-+---------+---------------------------------------+
     ST(1)  +-+---------+---------------------------------------+
     ST(2)  +-+---------+---------------------------------------+
     ST(3)  +-+---------+---------------------------------------+
     ST(4)  +-+---------+---------------------------------------+
     ST(5)  +-+---------+---------------------------------------+
     ST(6)  +-+---------+---------------------------------------+
     ST(7)  +-+---------+---------------------------------------+
            | |         '- Mantissa
            | '- Exponent
             '- Sign

                         Tag Word Format

        15                     8  7                     0
        +--+--+--+--+--+--+--+--++--+--+--+--+--+--+--+--+
        |TAG7 |TAG6 |TAG5 |TAG4 ||TAG3 |TAG2 |TAG1 |TAG0 |

        +--+--+--+--+--+--+--+--++--+--+--+--+--+--+--+--+

      TAG--Tag values of Data Register Stack
         00 = Valid
         01 = Zero
         10 = Invalid, infinity, or denormalized
         11 = Empty

                        Control Registers

                           +----------+
     Control Word          +----------+   Each word is 16 or 32
     Status Word           +----------+   bits, depending on
     Tag Word              +----------+   segment mode. Total

     Instruction Pointer   +          +   size of state is 14
                           +----------+   bytes in 16-bit mode
     Operand Pointer       +          +   or 28 bytes in 32-bit
                           +----------+   mode.

     Total size of environment is 94 bytes in 16-bit mode or 108 bytes in 32-bit mode.

     When DOS loads an .EXE program, it sets registers as follows:

     Register     Points to

     ES           Segment of Program Segment Prefix (PSP)

     DS           Segment of PSP
     CS:IP        CS:IP address in EXE header
     SS:SP        SS:SP address in EXE header

     When DOS loads a COM program, it sets all segment registers to the beginning of the program, and IP to 100H.


Conditional Assembly


Debugging in MASM32

This essay was written by the following author and is reproduced here for your convenience. It is a technique for programmers who own a copy of SoftICE.

Setting up MASM for use with SoftICE
------------------------------------
by Lucifer
Mon January 25, 1999

Well, I have had a pain trying to get masm produced executables to debug
correctly with SoftICE.  After some kludging I've finally figured it out...

Its actually simple to do, but if you dont know what you're doing (or haven't
read your manual), its quite a pain. Set these options when you build your
project and you should have no problems debugging it.

Step 1 -  Setting up The Assembler:
-----------------------------------
        ML /COFF /Zi ...

Step 2 - Setting up The Linker:
-------------------------------
        Link /SUBSYSTEM:WINDOWS /DEBUG /DEBUGTYPE:CV ...

Step 3 - Seting up SoftICE:

---------------------------
This batch file will translate the symbol information and package the source
code.  This will allow you full symbolic and source level debugging.
It will then launch the debugger amd break on the module's entry point
(WinMain, DllMain, or DriverEntry). This batch file will completely replace
the use of Loader32.exe, giving quick and easy access to the debugger from
the command line.

rem DEBUG.BAT ----------------------
@echo off

nmsym /translate:source,package,always /source:. /load:execute,break %1

Now all you have to do is type "DEBUG MyProgram.exe" on the command line to
automatically load the source and symbols and begin debugging.

Step 4 - Setting up the Paths:
------------------------------
Now all you need to do is add your MASM bin directory to the PATH, as in:
SET PATH = %PATH%;C:\MASM\BIN

Step 5 - Using SoftICE to Debug:
--------------------------------

Once you have the program loaded into softice you can use the SRC command to toggle between source view, code view, and mixed mode...
You can also set breakpoints on your functions by typing BPX MyFunc.
BPM MyVar will break on access to a variable.
Of course, READ YOUR MANUAL so you really know what your doing...

NOTE: These settings haven't seemed to work for everybody... so if you have
problems, or know what I am doing wrong, please let me know.

-----------------------------------------------------------------------------

Copyright (C) 1999
lord-lucifer@usa.net


Pentium Optimisation

Pentium Optimization Cross-Reference by Instruction

---------------------------------------------------------------------------
                         replacement
instruction   CPU's      or action          description/notes
---------------------------------------------------------------------------

aad (imm8)      all        AL = AL+(AH*imm8)    If imm8 is blank uses 10.

                           AH = 0               AAD is almost always slower,

                                                but only 2 bytes long.

aam (imm8)      all        AH = AL/imm8         Same as AAD.

                           AL = AL MOD imm8

add             16-bit     lea reg, [reg+reg+disp]
                                                Use LEA to add
                                                base + index + displacement
                                                Also preserves flags;

                                                for example:

                                                  add bx, 4

                                                can be replaced by:

                                                  lea  bx, [bx+4]

                                                when the flags must not
                                                be changed.

add             32-bit     lea reg, [reg+reg*scale+disp]

                                                Use LEA to add
                                                base + scaled index + disp
                                                Also preserves flags.
                                                (See previous example).
                                                The 32-bit form of LEA
                                                is much more powerful
                                                than the 16-bit version

                                                because of the scaling
                                                and the fact that almost
                                                all of the 8 General purpose
                                                registers can be used
                                                as base and index registers.

and reg, reg    Pent       test reg, reg        Use TEST instead of AND

                                                on the Pentium because
                                                fewer register conflict
                                                will result in better pairing

bswap           Pent       ror eax, 16          Pairs in U pipe, BSWAP
                                                doesn't pair.
                                                disadvantage: modifies flags
                                                (Not a direct replacement)

call dest1      286+       push offset dest2    When CALL is followed by
jmp  dest2                 jmp  dest1           a JMP, change the return
                                                address to the JMP destination.

call dest1      all        jmp  dest1           When a CALL is followed by a
ret                                             RET, the CALL can be replaced

                                                by a JMP.

cbw             386+       mov ah, 0            When you know AL < 128
                                                use MOV AH, 0 for speed.
                                                But use CBW for smaller
                                                code size.

cdq             486+       xor edx, edx         When you know EAX is positive

                                                Faster, better pairing.
                                                disadvantage: modifies flags
                Pent       mov edx, eax         When EAX value could be
                           sar edx, 31          positive or negative
                                                because of better pairing

cmp mem, reg    286        cmp reg, mem         reg, mem is 1 cycle faster

cmp reg, mem    386        cmp mem, reg         mem, reg is 1 cycle faster

dec reg16                  lea reg16, [reg16 - 1]   Use to preserve flags
                                                    for BX, BP, DI, SI

dec reg32                  lea reg32, [reg32 - 1]   Use to preserve flags
                                                    for EAX, EBX, ECX, EDX
                                                        EDI, ESI, EBP

div <op>         8088       shr accum, 1         When <op>  resolves to 2, use
                                                shift for division.
                                                (use CL for 4, 8, etc.)

div <op>         186+       shr accum, n         When <op>  resolves to a power
                                                of 2 use shifts for division.

enter imm16, 0  286+       push bp              ENTER is always slower

                           mov  bp, sp          and 4 bytes in length
                           sub  sp, imm16       if imm16 = 0 then push/mov
                                                is smaller
                386+       push ebp
                32-bit     mov  ebp, esp
                           sub  esp, imm16

inc reg16                  lea reg16, [reg16 + 1]   Use to preserve flags
                                                    for BX, BP, DI, SI

inc reg32                  lea reg32, [reg32 + 1]   Use to preserve flags
                                                    for EAX, EBX, ECX, EDX
                                                        EDI, ESI, EBP

jcxz <dest>:    486+        test cx, cx          JCXZ is faster and
                           je   <dest>:          smaller on 8088-286.
                                                On the 386 it is the

                                                about the same speed
               486+        test ecx, ecx        Never use JCXZ on 486
                           je   <dest>:         or Pentium except for
                                                compactness

lea reg, mem   8088-286    mov reg, OFFSET mem  MOV reg, imm is faster
                                                on 8088 - 286. 386+
                                                they are the same.

        Note: There are many uses for LEA, see: add, inc, dec, mov, mul

leave           486+       mov sp, bp           LEAVE is only 1 byte
                           pop bp               long and is faster
                                                on the 186-386. The
                           mov esp, ebp         MOV/POP is much faster
                           pop ebp              on 486 and Pentium

lodsb           486+       mov al, [si]         LODS is only 1 byte long
                           inc si               and is faster on 8088-386,
                                                much slower on the 486.
                                                On the Pentium the MOV/INC
                                                or MOV/ADD instructions
                                                pair, taking only 1 cycle.

lodsw           486+       mov ax, [si]         see lodsb
                           add si, 2

lodsd           486+       mov eax, [esi]       see lodsb
                           add esi, 4

loop <dest>:     386+       dec cx               LOOP is faster and
                           jnz <dest>:           smaller on 8088-286.
                                                on 386+ DEC/JNZ is

loopd <dest>:               dec ecx              much faster. On the Pentium
                           jnz <dest>:           the DEC/JNZ instructions
                                                pair taking only 1 cycle.

loopXX <dest>:   486+       je  $+5              The 3 replacement
                                                 instructions
( XX = e,ne,z or nz)       dec cx               are much faster on the 486+.

                           jnz <dest>:           LOOPxx is smaller and
                                                faster on 8088-286

loopdXX <dest>:  486+       je  $+5              The speed is about the
                           dec ecx              same on the 386.
                           jnz <dest>:

mov reg2, reg1  286+       lea reg2, [reg1+n]   LEA is faster, smaller and
 followed by:                                   preserves flags. This is a

 inc/dec/add/sub reg2                           way to do a MOV and ADD/SUB
                                                of a constant, n.

mov acc, reg    all        xchg acc, reg        Use XCHG for smaller code
                                                when one of the registers
                                                final value can be ignored.
                                                Note that acc = AL, AX or EAX.

mov mem, 1      Pent       lea bx, mem          Displacement/immediate does
                           mov [bx], 1          not pair. LEA/MOV can be used
                                                if other code can be placed
                                                inbetween to prevent AGI's.
                           mov ax, 1            MOV/MOV may be easier to pair.
                           mov mem, ax

mov [bx+2], 1   Pent       mov ax, 1            Better pairing because
                           mov [bx+2], ax       displacement/immediate
                                                instructions do not pair.
                           lea bx, [bx+2]
                           mov [bx], 1

movsb           486+       mov al, [si]         MOVS is faster and
                           inc si               smaller to move a single

                           mov [di], al         byte, word or dword
                           inc di               on the 8088-386.
                                                On the 486+ the MOV/INC
                                                method is faster.
                                                NOTE: REP MOVS is always
                                                faster to move a large block.

movsw           486+       mov ax, [si]         see MOVSB

                           add si, 2
                           mov [di], ax
                           add di, 2

movsd           486+       mov eax, [esi]       see MOVSB
                           add esi, 4
                           mov [edi], eax
                           add edi, 4

movzx r16, rm8  486+       xor bx, bx           MOVZX is faster and
                           mov bl, al           smaller on the 386.

                                                On the 486+ XOR/MOV

movzx r32, rm8  486+       xor ebx, ebx         is faster. Possible
                           mov bl, al           pairing on the Pentium.
                                                (source can be reg or mem)

movzx r32, rm16 486+       xor ebx, ebx         disadvantage: modifies flags
                           mov bx, ax

mul n           8088+      shl ax, cl           Use shifts or ADDs instead of

                                                multiply when n is a power of
                                                2.

mul n           Pent       add ax, ax           ADD is better than single
                                                shift because it pairs better.

mul             32-bit     lea                  Use LEA to multiply by
                                                2, 3, 4, 5, 7, 8, 9

                           lea eax, [eax+eax*4] (ex: multiply EAX * 5)
                                                LEA is better than SHL on the
                                                Pentium because it pairs in
                                                both pipes, SHL pairs only in
                                                the U pipe.

or reg, reg     Pent       test reg, reg        Better pairing because

                                                OR writes to register.
                                                (This is for src = dest.)

pop mem         486+       pop reg              Faster on 486+
                           mov mem, reg         Better pairing on Pentium

push mem        486+       mov  reg, mem        Faster on 486
                           push reg             Better pairing on Pentium

pushf           486+       rcr reg, 1           To save only the carry flag
                                                use a rotate (RCR or RCL)
                              or                into a register. RCR and RCL
                                                are pairiable (U pipe only)

                           rcl reg, 1           and take 1 cycle. PUSHF is
                                                slow and not pairable.

popf            486+       rcl reg, 1           To restore only the carry
                                                flag.
                                                See PUSHF.
                              or
                           rcr reg, 1

rep scasb       Pent       loop1:               REP SCAS is faster and
                             mov al, [di]       smaller on 8088-486.
                             inc di             Expanded code is faster

                             cmp al, reg2       on Pentium due to pairing.
                             je  exit
                             dec cx
                             jnz loop1
                           exit:

shl reg, 1      Pent       add reg, reg         ADD pairs better. SHL
                                                only pairs in the U pipe.

stosb           486+       mov [di], al         STOS is faster and smaller

                           inc di               on the 8088-286, and the same
                                                speed on the 386. On the 486+

stosw           486+       mov [di], ax         the MOV/INC is slightly
                           add di, 2            faster.

stosd           486+       mov [edi], eax       REP STOS is faster on 8088-
                           add edi, 4           386.

                                                MOV/INC or MOV/ADD is faster
                                                on the 486+
                                                Note: use LEA SI, [SI+n]
                                                to advance LEA without
                                                changing the flags.

xchg            all                             Use xchg acc, reg to do a

                                                1 byte MOV when one register
                                                can be ignored.

xchg reg1, reg2 Pent       push reg1            pushes and pops are 1 cycle
                           push reg2            faster on Pentium due to
                           pop  reg1            pairing.
                           pop  reg2
                                                disadvantage: uses stack

                Pent       mov  reg3, reg1      Faster and better pairing
                           mov  reg1, reg2      if reg3 is available.
                           mov  reg2, reg3

xlatb           486+       mov bh, 0            XLAT is faster and smaller
                           mov bl, al           on 8088-386. MOV's are faster
                           mov al, [bx]         on 486+. Best to rearrange

                                                instructions to prevent AGI's

xlatb           486+       xor ebx, ebx         and get pairing on Pentium.
                           mov bl, al           Force high part of BX/EBX
                           mov al, [ebx]        to zero outside of loop.
                                                disadvantage: modifies flags


Command Line Tools

ML.EXE Options
LINK Options
LIB Options
EDITBIN Options
DUMPBIN Options


DUMPBIN Options

usage: DUMPBIN [options] [files]

Options
/ALL
/ARCH
/ARCHIVEMEMBERS
/DEPENDENTS
/DIRECTIVES
/DISASM
/EXPORTS
/FPO
/HEADERS
/IMPORTS
/LINENUMBERS
/LINKERMEMBER[:{1|2}]
/LOADCONFIG
/OUT:filename
/PDATA
/RAWDATA[:{NONE|BYTES|SHORTS|LONGS}[,#]]
/RELOCATIONS
/SECTION:name
/SUMMARY
/SYMBOLS
The DUMPBIN command line options are listed below. Some of the output each option provides is also listed.

/ALL Displays all available information except code disassembly. Use the /DISASM option to display disassembly. You can use /RAWDATA:NONE with the /ALL option to omit the raw binary details of the file.

Because the /ALL option is simply a combination of all the other options, an example is not needed.

/ARCHIVEMEMBERS Displays minimal information about member objects in a library.
The size of the output file depends on the number of object modules in the library. The following is part of the output from the Scrnsave.lib file:
Archive member name at 582: /0        ..\..\common\retail\scrnsave.obj
2FF359CC time/date Thu Jun 29 18:56:28 1995
         uid
         gid
  100666 mode
    214A size
correct header end

/DISASM Displays disassembly of code sections, using symbols if present in the file.
The following is part of the disassembly code from the Lib.exe file:
00401000: 8B 44 24 08        mov         eax,dword ptr [esp+8]
00401004: 68 00 20 40 00     push        402000h
00401009: 8B 4C 24 08        mov         ecx,dword ptr [esp+8]
0040100D: 50                 push        eax
0040100E: 51                 push        ecx
0040100F: E8 0C 00 00 00     call        00401020
00401014: 33 C0              xor         eax,eax
00401016: C3                 ret
00401017: CC                 int         3

/EXPORTS Displays all definitions exported from an executable file or DLL.
MFC40.DLL produces the following export information:

Section contains the following Exports for MFC40.DLL
          0 characteristics
   30733286 time date stamp Wed Oct 04 18:19:02 1995
       0.00 version
          1 ordinal base
       5782 number of functions
          4 number of names

ordinal hint   name

      2    0   DllCanUnloadNow  (00096182)
      1    1   DllGetClassObject  (0009611E)
      3    2   DllRegisterServer  (000961DB)
      4    3   DllUnregisterServer  (00096242)

/FPO Displays frame pointer optimization (FPO) records.
One of the MFC libraries, Nafxis.lib, provided us with some examples of frame pointer optimization records:
FPO Data (1)
                                       Use Has  Frame
 Address  Proc Size   Locals   Prolog  BP  SEH  Type   Params
00000000          9        0        0   N   N    fpo        0

FPO Data (1)
                                       Use Has  Frame
 Address  Proc Size   Locals   Prolog  BP  SEH  Type   Params
00000000         11        0        0   N   N    fpo        C

FPO Data (1)
                                       Use Has  Frame
 Address  Proc Size   Locals   Prolog  BP  SEH  Type   Params
00000000          3        0        0   N   N    fpo        0

/HEADERS Displays the file header and the header for each section. When used with a library, it displays the header for each member object.
This information was displayed from the Resource Compiler, Rc.exe:
FILE HEADER VALUES
     14C machine (i386)
       6 number of sections
306F7A22 time date stamp Sun Oct 01 22:35:30 1995
       0 file pointer to symbol table
     1D1 number of symbols
      E0 size of optional header
     302 characteristics
            Executable
            32 bit word machine
            Debug information stripped

OPTIONAL HEADER VALUES
     10B magic #
    2.60 linker version
    1E00 size of code
    1E00 size of initialized data
       0 size of uninitialized data
    1144 address of entry point
    1000 base of code
    3000 base of data
         ----- new -----
 2BB0000 image base
    1000 section alignment
     200 file alignment
       3 subsystem (Windows CUI)
    4.00 operating system version
    4.00 image version
    3.50 subsystem version
    8000 size of image
     400 size of headers
    62C8 checksum
  100000 size of stack reserve
    1000 size of stack commit
  100000 size of heap reserve
    1000 size of heap commit
       0 [       0] address [size] of Export Directory
    5000 [      3C] address [size] of Import Directory
    6000 [     394] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
       0 [       0] address [size] of Security Directory
    7000 [     21C] address [size] of Base Relocation Directory
    3030 [      38] address [size] of Debug Directory
       0 [       0] address [size] of Description Directory
       0 [       0] address [size] of Special Directory
       0 [       0] address [size] of Thread Storage Directory
       0 [       0] address [size] of Load Configuration Directory
     268 [      44] address [size] of Bound Import Directory
    50A0 [      64] address [size] of Import Address Table Directory
       0 [       0] address [size] of Reserved Directory
       0 [       0] address [size] of Reserved Directory
       0 [       0] address [size] of Reserved Directory

SECTION HEADER #1
   .text name
    1D24 virtual size
    1000 virtual address
    1E00 size of raw data
     400 file pointer to raw data
       0 file pointer to relocation table
    3C20 file pointer to line numbers
       0 number of relocations
     37E number of line numbers
60000020 flags
         Code
         (no align specified)
         Execute Read

/IMPORTS Displays all definitions imported to an executable file or DLL.
The output displayed here is similar to the /EXPORTS output.

/LINENUMBERS Displays COFF line numbers. Line numbers exist in an object file if it was compiled with the Program Database (/Zi), C7 Compatible (/Z7), or Line Numbers Only (/Zd) switches. An executable file or DLL contains COFF line numbers if it was linked with the Generate Debug Info (/DEBUG) and COFF Format (/DEBUGTYPE:COFF) options.
An application generated using AppWizard displays line information data such as the following:
LINENUMBERS #1
   1E90   13     1ECD   13     1EF7   13     1F16   13     1F31   15
   1F46   15     1F61   24     1F9A   27     1FD0   2A     2001   2B

/LINKERMEMBER[:{1|2}] Displays public symbols defined in a library. Specify the 1 argument to display symbols in object order, along with their offsets. Specify the 2 argument to display offsets and index numbers of objects, and then list the symbols in alphabetical order, along with the object index for each. To get both outputs, specify /LINKERMEMBER without the number argument.
Winmmm.lib, the Windows Multimedia library, was used to get the following sample of DUMPBIN output.
Archive member name at 8: /
2FB537E1 time/date Sat May 13 15:51:13 1995
         uid
         gid
       0 mode
    2864 size
correct header end

    391 public symbols

     556C _CloseDriver@12
     58A0 _DefDriverProc@20
     5BDC _DriverCallback@28
     5F1C _DrvGetModuleHandle@4
     626A _GetDriverModuleHandle@4
     65C4 _NotifyCallbackData@20
     6914 _OpenDriver@12
     6C44 _PlaySound@12
     6F70 _PlaySoundA@12
     72A0 _PlaySoundW@12
/OUT:filename Specifies a filename for the output. By default, DUMPBIN displays the information to standard output.

/RAWDATA[:{BYTES|SHORTS|LONGS|NONE}[,number]] Displays the raw contents of each section in the file. The arguments control the format of the display, as shown below:
Argument    Result

BYTES      The default. Contents are displayed in hexadecimal bytes,
           and also as ASCII characters if they have a printed
           representation.
SHORTS     Contents are displayed as hexadecimal words.
LONGS      Contents are displayed as hexadecimal longwords.
NONE       Raw data is suppressed. This argument is useful to control
           the output of /ALL.
number     Displayed lines are set to a width that holds <number> values
           per line.
The information generated with this option is quite large, this is a small sample of output from an AppWizard application using the LONGS format:
RAW DATA #1
00000000  53EC8B55 00A15756 | E9004058 00000000      U[ASCII 239]_SVW[ASCII
237].|X@._...._
00000010  C95B5E5F EC8B55C3 | 5304EC83 4D895756      _^[++U[ASCII
239]_|[ASCII 226]_.SVW[ASCII 235]M_
00000020  3058B8FC 00E90040 | 5F000000 C3C95B5E      n+X0@._.|..._^[++_
/RELOCATIONS Displays any relocations in the object or image.
Below is a small portion of the relocation output obtained from an AppWizard application:
BASE RELOCATIONS #6

    1000 virtual address,       B0 SizeOfBlock
       7 HIGHLOW
      22 HIGHLOW
      36 HIGHLOW
      67 HIGHLOW
      89 HIGHLOW
/SECTION:section Restricts the output to information on the specified section.

/SUMMARY Displays minimal information about sections, including total size. This option is the default if no other option is specified.
Microsoft (R) COFF Binary File Dumper Version 3.00.5270
Copyright (C) Microsoft Corp 1992-1995. All rights reserved.

Dump of file tracer.exe

File Type: EXECUTABLE IMAGE

     Summary

        1000 .data
        1000 .idata
        1000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text
/SYMBOLS Displays the COFF symbol table. Symbol tables exist in all object files. A COFF symbol table appears in an image file only if it is linked with the Generate Debug Info and COFF Format options under Debug Info on the Debug category for the linker (or the /DEBUG and /DEBUGTYPE:COFF options on the command line).
An AppWizard application was used to obtain the following example:
COFF SYMBOL TABLE
000 000065D0 SECT5  notype       Static       | .rsrc$02
001 00000011 DEBUG  notype       Filename     | .file
 C:\code\test\testView.cpp
004 000041A0 SECT3  notype       Static       | $SG23289
005 00004018 SECT3  notype       Static       | _$S189$S23301
006 00004168 SECT3  notype       Static       | _THIS_FILE$S23282
007 00001E90 SECT1  notype       Static       | .text
 Section length  2DE, #relocs   27, #linenums   22
009 00001EE2 SECT1  notype ()    Static       | _$E188
00A 00001EF7 SECT1  notype ()    Static       | _$E187
 tag index 0000002E size 0000001F lines 000012DF next function 00000033
00C 000042AC SECT3  notype       Static       | __init_CTestView$S23291
00D 00003998 SECT2  notype       Static       | $T23440
00E 00003978 SECT2  notype       Static       | $T23438
00F 000039C0 SECT2  notype       Static       | $T23447
010 000039A0 SECT2  notype       Static       | $T23446
011 00000021 DEBUG  notype       Filename     | .file


EDITBIN Options

usage: EDITBIN [options] [files]

Options
/BIND[:PATH=path]
/HEAP:reserve[,commit]
/LARGEADDRESSAWARE[:NO]
/NOLOGO
/REBASE[:[BASE=address][,BASEFILE][,DOWN]]
/RELEASE
/SECTION:name[=newname][,[[!]{cdeikomprsuw}][a{1248ptsx}]]
/STACK:reserve[,commit]
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}[,#[.##]]
/SWAPRUN:{[!]CD|[!]NET}
/VERSION:#[.#]
/WS:[!]AGGRESSIVE


LIB Options

usage: LIB [options] [files]

Options
/CONVERT
/DEBUGTYPE:CV
/DEF[:filename]
/EXPORT:symbol
/EXTRACT:membername
/INCLUDE:symbol
/LIBPATH:dir
/LIST[:filename]
/MACHINE:{ALPHA|ARM|IX86|MIPS|MIPS16|MIPSR41XX|PPC|SH3|SH4}
/NAME:filename
/NODEFAULTLIB[:library]
/NOLOGO
/OUT:filename
/REMOVE:membername
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}[,#[.##]]
/VERBOSE


LINK Options

usage: LINK [options] [files] [@commandfile]

Options
/ALIGN:#
/BASE:{address|@filename,key}
/COMMENT:comment
/DEBUG
/DEBUGTYPE:{CV|COFF}
/DEF:filename
/DEFAULTLIB:library
/DLL
/DRIVER[:{UPONLY|WDM}]
/ENTRY:symbol
/EXETYPE:DYNAMIC
/EXPORT:symbol
/FIXED[:NO]
/FORCE[:{MULTIPLE|UNRESOLVED}]
/GPSIZE:#
/HEAP:reserve[,commit]
/IMPLIB:filename
/INCLUDE:symbol
/INCREMENTAL:{YES|NO}
/LARGEADDRESSAWARE[:NO]
/LIBPATH:dir
/MACHINE:{ALPHA|ARM|IX86|MIPS|MIPS16|MIPSR41XX|PPC|SH3|SH4}
/MAP[:filename]
/MAPINFO:{EXPORTS|FIXUPS|LINES}
/MERGE:from=to
/NODEFAULTLIB[:library]
/NOENTRY
/NOLOGO
/OPT:{ICF[,iterations]|NOICF|NOREF|NOWIN98|REF|WIN98}
/ORDER:@filename
/OUT:filename
/PDB:{filename|NONE}
/PDBTYPE:{CON[SOLIDATE]|SEPT[YPES]}
/PROFILE
/RELEASE
/SECTION:name,[E][R][W][S][D][K][L][P][X]
/STACK:reserve[,commit]
/STUB:filename
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}[,#[.##]]
/SWAPRUN:{CD|NET}
/VERBOSE[:LIB]
/VERSION:#[.#]
/VXD
/WARN[:warninglevel]
/WINDOWSCE:{CONVERT|EMULATION}
/WS:AGGRESSIVE


ML.EXE Options

ML.EXE 6.14 Options

Options
ML [ /options ] filelist [ /link linkoptions ]
/AT Enable tiny model (.COM file)
/Bl<linker> Use alternate linker
/c Assemble without linking
/Cp Preserve case of user identifiers
/Cu Map all identifiers to upper case
/Cx Preserve case in publics, externs
/coff generate COFF format object file
/D<name>[=text] Define text macro
/EP Output preprocessed listing to stdout
/F <hex> Set stack size (bytes)
/Fe<file> Name executable
/Fl[file] Generate listing
/Fm[file] Generate map
/Fo<file> Name object file
/FPi Generate 80x87 emulator encoding
/Fr[file] Generate limited browser info
/FR[file] Generate full browser info
/G<c|d|z> Use Pascal, C, or Stdcall calls
/H<number> Set max external name length
/I<name> Add include path
/link <linker options and libraries>
/nologo Suppress copyright message
/Sa Maximize source listing
/Sc Generate timings in listing
/Sf Generate first pass listing
/Sl<width> Set line width
/Sn Suppress symbol-table listing
/Sp<length> Set page length
/Ss<string> Set subtitle
/St<string> Set title
/Sx List false conditionals
/Ta<file> Assemble non-.ASM file
/w Same as /W0 /WX
/WX Treat warnings as errors
/W<number> Set warning level
/X Ignore INCLUDE environment path
/Zd Add line number debug info
/Zf Make all symbols public
/Zi Add symbolic debug info
/Zm Enable MASM 5.10 compatibility
/Zp[n] Set structure alignment
/Zs Perform syntax check only


[ELSE]IF

Syntax: [ELSE]IF expression

[ELSE]IFE expression

Description
IF causes assembly of a block of statements if expression is true (nonzero). IFE causes assembly of a block of statements if expression is false (zero).

The <expression> must resolve to a constant and contain no forward references.


[ELSE]IFB

Syntax: [ELSE]IFB expression

[ELSE]IFNB expression

Description
IFB causes assembly of a block of statements if <expression> is blank. IFNB causes assembly of a block of statements if <expression> is not blank. The <expression> field is any name, number, or expression; typically, it is the name of a parameter of a macro.

Within a macro, a parameter name is replaced by an empty string if you call the macro without giving a corresponding argument. IFB and IFNB let you define default behavior when an argument is missing, but the :REQ and :=default MACRO parameters are preferred.


[ELSE]IFDEF

Syntax: [ELSE]IFDEF name

[ELSE]IFNDEF name

Description
IFDEF causes assembly of a block of statements if <name> is a previously defined symbol. IFNDEF causes assembly of a block of statements if name has not been defined.

You can define symbols on the command line or in the Macro Assembler Global Options dialog box.

Use of this feature with the IFDEF and IFNDEF directives lets you control which statements are assembled from the command line.


[ELSE]IFDIF[I]

Syntax: [ELSE]IFDIF[I] textitem1, textitem2

[ELSE]IFIDN[I] textitem1, textitem2

Description
Causes assembly of a block of statements depending on whether two textitems are different or identical. IFDIF assembles the block if <textitem1> and <textitem2> are different. IFIDN assembles the block if they are the same. IFDIFI and IFIDNI do the same actions but are not case sensitive.

The <textitem1> and <textitem2> parameters are text items.


MACRO

Syntax: name MACRO [parameter[:tag]] [,parameter[:tag]]...]
  [LOCAL varlist]
  statements
  [EXITM [textitem]]
ENDM

Description
Marks the beginning of a macro definition called <name> and takes optional parameters. The assembler generates the statements in the macro block each time the macro is called in source code. Macro procedures and macro functions can be nested up to 40 levels. Text macros may be nested up to 20 levels.

Macro procedures can be redefined at any time. The new definition affects any subsequent calls to this macro. Macro functions can only be redefined, if they have not been called yet.

Example
mymacro MACRO value:REQ, reg:=<AX>, options:VARARG
  LOCAL returnval
  -
  -
  -
  EXITM returnval
ENDM

Parameter Description
name A unique symbol name. It can appear later in source code, to call the macro.

parameter A valid symbol name. Each parameter can appear in the statements and is replaced by the corresponding item in the argument list whenever the macro is called.
:
tag Either :REQ, :=default, or :VARARG. :REQ causes an assembler error if the parameter is given a blank argument. :=default causes <parameter> to be assigned <default> if given a null argument. :VARARG allows a variable number of arguments to be passed as a comma-separated list to <parameter>. If :VARARG is used, it must be applied only to the last parameter of the MACRO directive.

statements Any valid assembler statements.

value Optional return value for macro function.


ENDM

Syntax: ENDM

Description
Terminates macro and iterative blocks.


EXITM

Syntax: EXITM [textitem]

Description
Terminates expansion of the current macro or repeat block and begins assembly of the next statement outside the block. If the EXITM directive is encountered in a nested macro block, the assembler returns to expanding the previous block level.

The <textitem> parameter is a text item that is returned to the calling statement. The <textitem> field is valid only with an EXITM directive at the end of a MACRO block.


FOR

Syntax: FOR parameter[:REQ|:=default], <argument [,argument]...>
  statements
ENDM

Description
Repeats <statements> once for each argument specified. The current argument replaces <parameter> in each iteration. IRP is a synonym for FOR and is included for compatibility with previous versions of the assembler.

Parameter Description
parameter A valid symbol name. If parameter appears in statements, it is replaced by a different argument in each iteration.

:REQ Optional tag for <parameter> causing an assembler error if <parameter> is given a blank argument.

:=default Optional tag for <parameter> causing <parameter> to be assigned <default> if given a blank argument.

argument Text, symbol, string, or numeric constant. Separate multiple iterations with commas. Angle brackets are required if a string <argument> includes spaces or commas. Leading spaces of string arguments are ignored.

statements Any valid assembler statements.


FORC

Syntax: FORC parameter, <string>
  statements
ENDM

Description
Repeats <statements> once for each character in the string. The character replaces <parameter> in each repetition. IRPC is a synonym for FORC and is included for compatibility with previous versions of the assembler.

Parameter Description
parameter A valid symbol name. If <parameter> appears in statements, then it is replaced by a different character each iteration.

string A literal string or a symbol defined with a string equate. All spaces are counted as characters. Angle brackets are required.

statements Any valid assembler statements.


GOTO

Syntax: GOTO macrolabel

Description
Causes assembler to skip to <macrolabel>. The GOTO directive is only allowed inside a MACRO, FOR, FORC, REPEAT, or WHILE block. The <macrolabel> is only visible within the block.

Example
MACRO Instruments
IFNDEF Cymbal
GOTO Crash
ENDIF
-
-
-
:Crash
.ERR <Undefined symbol.>
-
-
-
ENDM


REPEAT

Syntax: REPEAT expression
  statements
ENDM

Description
Assembles a block of statements <expression> times. REPT is a synonym for REPEAT and is included for compatibility with previous versions of the assembler.

The <expression> parameter must evaluate to a numeric constant. This constant is evaluated during the first pass. The <statements> are any valid assembler statements.


WHILE

Syntax: WHILE expression
statements
ENDM

Description
Marks a block of statements to be assembled repeatedly until <expression> is false (zero). The <expression> is a constant expression whose value is computed at assembly time.


IF

Syntax: IF cond expression
  ifstatements
[ELSEIF] cond expression
  elseifstatements
  -
  -
  -
[ELSE]
  elsestatements
ENDIF

Description
The IF block format can be used to create a source file that will generate a variety of programs, depending on constants or environment variables. For example, you can create a single source file that generates code for different memory models and operating environments. IF blocks can be nested up to 20 levels but cannot span include files or structure, union, or macro definitions.

The statements following the ELSE directive are assembled only if the preceding IF directive was found to be false (zero). Only one ELSE statement is allowed in each IF block, although there can be several ELSEIF statements.

IFcond is one of the conditional assembly directives beginning with "IF" (such as IF, IFE, and IFB). There is an optional ELSEIFcond corresponding to each IFcond.

The <ifstatements>, <elseifstatements>, and <elsestatements> are each a series of one or more assembly-code statements. The respective conditions determine which block is assembled, if any. The ELSE and ELSEIF blocks are optional.


Literal text

Syntax: <text>

Description
Treats <text> as a single literal string.

Angle brackets are often used in macro calls and with the FOR directive to ensure that values in a parameter list are treated as a single parameter. For example,

MyMacro <one, two, three> ;Passes one argument to  ; MyMacro
MyMacro one, two, three ;Passes three arguments to ; MyMacro

The assembler removes one set of angle brackets each time it inserts an argument into a macro expansion.

The <text> is any name, number, or expression. It can contain commas, spaces, tabs, or semicolons. The exclamation point (!) is an escape character that allows you to include special characters such as the semicolon, ampersand, and quotation marks.


Macro local

Syntax: LOCAL localname [,localname]...

Description
Declares a label or symbol for local use within a macro or iterative block. The assembler generates a different internal name for the symbol each time it expands the macro. The LOCAL directive allows you to call a macro that contains local jump statements and variable definitions without generating the same label each time the macro is expanded.

The <localname> parameter is the name of a label or symbol inside the macro. Inside the macro expansion, <localname> takes precedence over a global label or symbol with the same name.


PUSHCONTEXT

Syntax: PUSHCONTEXT context

POPCONTEXT context

Description
PUSHCONTEXT stores the context information indicated in <context>.
POPCONTEXT restores the context information indicated in <context>.
You can nest PUSHCONTEXT directives up to 10 levels.

You can use these directives to save and restore the state of the assembler in include files and procedures.

<context> Items Saved

ASSUMES   Register assumptions
RADIX     Current default radix
LISTING   Listing and cref flags
CPU       CPU and coprocessor directives
ALL       All of the above


&parameter&

The ampersand character "&"

Syntax: &parameter&

Description
Operator used within a macro or a repeat block; enables parameter substitution for <parameter>. Two parameters can be joined to form one symbol. You can join any number of parameters with the ampersand operator.

You can also use this operator to force parameter substitution in a quoted string. For this reason, if you want an ampersand to be included in a string, you must use the string escape character (!) before the &.

Use ampersands (&) only around macro parameters, in quoted strings, and inside angle brackets (<>). Each parameter to be substituted must have one ampersand on the left and right. If an ampersand is adjacent to white space, it can be omitted as long as one ampersand is next to each parameter to be substituted.

Example:
Guard MACRO Prisonernum:REQ, Prisonername:=Anonymous
ECHO <Number &Prisonernum has arrived at &@Time.>
EXITM Prisonernum&&Prisonername
ENDM

Badge Guard 2


Relational Operators

Syntax: expression1 EQ expression2

expression1 NE expression2

expression1 GT expression2

expression1 LT expression2

expression1 GE expression2

expression1 LE expression2

Description
The EQ, NE, GT, LT, GE, and LE relational operators determine if two constant expressions or data labels (in the same segment) are equal, not equal, greater than, less than, greater than or equal, or less than or equal to each other. The comparison returns true (-1) or false (0).

These operators work only with assembler symbols and constants; they cannot be used to evaluate registers or memory locations. Use comparison run-time operators with the .IF, .ELSEIF, .WHILE, and .UNTIL directives.


VARARG (Macro)

VARARG

VARARG (Macro)

The VARARG attribute allows you to pass a variable number of arguments to a macro. The macro parameter will be passed a comma-separated list of values (or a blank if no values are given) when called. You can apply the VARARG attribute only to the last parameter in a macro definition.

You can use the FOR directive to handle macro parameters with the VARARG attribute. The following macro function calculates the number of arguments in a VARARG parameter:

@ArgCount MACRO parmlist:VARARG
  LOCAL count
  count = 0
  FOR parm, <parmlist>
    count = count + 1 ; Count the parameters
  ENDM
  EXITM count
ENDM

This example button links to a macro that allows you to access an argument by its number.


Nested macros

You can separate macro arguments with white space or with commas. This is the same as using OPTION OLDMACROS.

The assembler uses the following rules to handle ampersands:

1. If a sequence of ampersands is found, the first ampersand is removed.

2. If a macro parameter is found, it is replaced by the actual parameter string.

3. Inside quoted strings and text literals, the string is scanned from left to right for ampersands. For each ampersand:

* If the ampersand is preceded or followed by a parameter, the parameter is substituted and the ampersand removed.

* If the ampersand is preceded by a previously substituted parameter, the ampersand is removed.

* In all other cases, the ampersand is ignored.

The assembler performs parameter substitution at each level of nesting. Therefore, you must add an extra ampersand before or after a macro parameter for each level of MACRO nesting or FOR/FORC/REPEAT/WHILE nesting.


Macro function reverse ordering

;* @ArgRev - Macro function returns a reversed order version of a
;* VARARG list.
;*
;* Shows: Operators - <> ! %
;* String directive - SUBSTR
;* Predefined function - @SizeStr
;*
;* Params: arglist - arguments to be reversed

@ArgRev MACRO arglist
  LOCAL txt, arg
  txt TEXTEQU <>
    % FOR arg, arglist
      txt CATSTR <arg>, <!,>, txt
    ENDM
  txt SUBSTR txt, 1, @SizeStr( %txt ) - 1
  txt CATSTR <!<>, txt, <!>>
  EXITM txt
ENDM


Macro Function ArgI

;* @ArgI - Macro function returns an argument specified by number
;* from a VARARG list.
;*
;* Shows: Directives - FOR LOCAL EXITM
;* TEXTEQU =
;* Operator - EQ
;*
;* Params: index - one-based number of the argument to be returned
;* arglist - argument list

@ArgI MACRO index:REQ, arglist:VARARG
  LOCAL count, retstr
  count = 0
    FOR arg, <arglist>
      count = count + 1
    IF count EQ index
  retstr TEXTEQU <arg>
  ENDIF
  ENDM
  EXITM retstr
ENDM


CATSTR

Syntax: @CatStr(string[, string...])

name CATSTR [textitem[, textitem...]]

Description
The @CatStr macro function concatenates one or more text items. The result can be used anywhere a text item is appropriate. The @CatStr function will not expand macros or expressions unless you use the expression operator (%).

The CATSTR directive concatenates strings and assigns the result to <name>. These two lines are equivalent:

language TEXTEQU @CatStr (<Quick>, <Pascal>)
language CATSTR <Quick>, <Pascal>

The <name> is a unique symbolic name, <string> is a text string, and <textitem> is a text item.


INSTR

Syntax: @InStr([position], string1, string2)

name INSTR [position,] textitem1, textitem2

Description
The @InStr macro function searches for the first occurrence of <string2> inside <string1> and returns the position of the first character of the match. The search begins at <position>, if you give that parameter. The @InStr function will not expand macros or expressions unless you use the expression operator (%).

The first character is indexed as 1. @InStr returns 0 if <string1> is not found.

The INSTR directive performs the same function as @InStr but assigns the result to <name>. These two lines are equivalent:

develop TEXTEQU @InStr (2, <MikeBobMichaelJim>, <Mi>)
develop INSTR 2, <MikeBobMichaelJim>, <Mi> ;develop is now 8

Parameter Description
name Name of the resulting constant.
position Starting character position of the search (default 1). Must be a positive integer.
string1 String being searched; any text.
string2 String to search for; any text.
textitem1 String being searched; any text item.
textitem2 String to search for; any text item.


SIZESTR

Syntax: @SizeStr(string)

name SIZESTR textitem

Description
The @SizeStr macro function returns the length of a text item in characters. The @SizeStr function will not expand macros or expressions unless you use the expression operator (%). A zero indicates a null (empty) string.

The SIZESTR directive performs the same function but assigns the result to <name>. These two lines are equivalent:

namelength TEXTEQU @SizeStr(<Denise>)
namelength SIZESTR <Denise>
;namelength is 6

The <name> is a unique symbolic name, <string> is a string, and <textitem> must be a text item.


SUBSTR

Syntax: @SubStr(string, start [,length])

name SUBSTR textitem, start [,length]

Description
The @SubStr macro function extracts specified characters from a text item. If <length> is not given, the function will return all characters to the right of (and including) the character pointed to by <start>. The @SubStr function will not expand macros or expressions unless you use the expression operator (%).

The SUBSTR directive performs the same function but assigns the result to <name>. These two lines are equivalent:

country TEXTEQU @SUBSTR (<AndorraMonacoLuxembourg>,8,6)
country SUBSTR <AndorraMonacoLuxembourg>,8,6
;country is <Monaco>

Parameter Description
name A unique symbolic name.
string A string to extract characters from.
textitem A text item to extract characters from.
start Starting position of substring; the first character is idexed as 1. Must be a positive integer constant.
length Number of characters to extract. Must be a positive integer constant.


.IF

Syntax: .IF condition
  ifstatements
[.ELSEIF] condition
  elseifstatements
[.ELSE]
  elsestatements
.ENDIF

For "condition" see Comparison run-time operators

Description
Used for clear coding of common control-flow blocks. Generates comparison and conditional jump instructions so that if <condition> is true, the processor executes the instructions following .IF until the next .ELSEIF, .ELSE, or .ENDIF. .IF statements can be nested.

The .ELSEIF statement is used to create a code block that is executed if the preceding .IF and .ELSEIF conditions are false, and the current .ELSEIF condition is true. There can be several .ELSEIF blocks within a .IF block. The .ELSEIF statement performs the same function as a .IF inside a .ELSE but does not create another nesting level of .IFs.

.ELSE specifies an alternate code block if the matching .IF and previous .ELSEIF expressions are false.

.ENDIF closes the current .IF, .ELSEIF, or .ELSE code block. The assembler optimizes to get the best possible code. For example,

.IF ax==0
performs the comparison with:
or ax,ax
which is more efficient than:
cmp ax, 0


ALIGN

Syntax: ALIGN [number]

Description
ALIGN aligns the next variable or instruction on an offset address that is a multiple of [expression]. The [number] parameter must be a power of 2 [1,2,4,8,...] less than or equal to the alignment of the current segment. If [number] is omitted, the alignment is determined by the align field of the preceding SEGMENT directive.

In a segment containing no instructions, the assembler pads each skipped byte with nulls [00h]. In a code segment, the assembler inserts a no-operation sequence [not necessarily NOP instructions] to fill the gap.

This directive is useful for optimizing data and instruction fetches on processors with 16 or 32 bit data paths.

EVEN is a synonym for ALIGN 2.


ASSUME

Syntax: ASSUME segregister:seglocation [, segregister:seglocation]...

ASSUME dataregister:qualifiedtype
[, dataregister:qualifiedtype]...

ASSUME register:ERROR [, register:ERROR]...

ASSUME [register:]NOTHING [, register:NOTHING]...

Description
A general-purpose directive that allows the assembler to determine offsets, select the correct segment register, and verify certain register use assumptions at assembly.

The "ASSUME segregister:seglocation" syntax is used to inform the assembler of the current value of <segregister>. The assembler uses this information to calculate offsets correctly and to guard against segment selection errors. This directive does not generate code to change the value of <segregister>. The ASSUME directive is not necessary for the CS register, since CS is assumed to the current segment or group automatically. The <seglocation> can be any segment or group name, or an equivalent expression.

The "ASSUME dataregister:type" syntax informs the assembler that <dataregister> is subject to the constraints of <type>. If an assumed register is used incorrectly, the assembler generates an error. The <type> parameter must be the same size as <dataregister>.

ASSUME bx:WORD mov ax, [bx]            ; Error--cannot dereference non-pointer
ASSUME bx:PTR WORD mov [bx], 10h       ;
Assumes operand size is WORD mov [bx], al ;Error--cannot move byte into word memory
ASSUME al:WORD                         ; Error--al is only byte-sized
ASSUME bx:BYTE                         ; Error--bx is word-sized

The ASSUME directive can include ERROR, FLAT, or register:type. MASM 6.1 issues a warning when you specify ASSUME values for CS other than the current segment or group.

The "ASSUME register:ERROR" syntax causes the assembler to generate an error if <register> is later used explictly or implicitly. The OPATTR, .TYPE, and TYPE directives do not cause errors when referring to registers assumed to ERROR.

The "ASSUME register:NOTHING" syntax causes the assembler to remove all assumptions about <register>. ASSUME NOTHING removes all assumptions about all registers.

Use an ASSUME statement each time you load a known value into a segment register. Although not required, the ASSUME directive helps the assembler safeguard against segment selection errors and determine offsets. You may need to use instructions to initialize segment registers properly at run time.

If you use the ASSUME directive to set assumptions about a data register, it will override any assumptions for its subregisters. For example, ASSUME EDX:DGROUP will override assumptions for DL, DH, and DX.

Parameter Description
seg register CS, DS, ES, FS, GS, or SS. The assembler automatically maintains assumptions for the CS segment register.

seg location A segment address, another segment register, a group, or FLAT. You can find the segment address of a label by using the SEG operator. FLAT is the label of the single FLAT segment.

data register Any byte, word, or 32-bit register.

qualified type Any qualified type that will fit in <dataregister>.

register Any segment or data register.


COMMENT

Syntax:

COMMENT delimiter [text]
  [text]
[text] delimiter [text]

Description
Ignores all text between delimiters or on the same line as a delimiter. The two comment delimiters can be on the same or different physical lines.

In the following code segment, the text inside the asterisks and the MOV instruction are ignored:

COMMENT * This text is ignored
          by the assembler *  mov ax, 10h

Parameter Description
delimiter First nonblank character following the COMMENT directive
text All text up to and including the line containing the next occurrence of the delimiter.


Character_negation

Syntax: !character

Description
Treats <character> as a literal character rather than as an operator or a symbol. Used with special characters (<, >, ", ', %, ;, and comma) when the usual assembly language meaning of the character must be suppressed. A double exclamation point (!!) is treated as a single exclamation point. The escape character does not apply to strings in quotation marks or to backslashes at the end of a line.

For example:

<I!'m afraid I can!'t do that!!> = I'm afraid I can't do that!

<20!% !> 15!%> = 20% > 15%


Comparison run-time operators

Operator Meaning
== Equal
!= Not equal
>  Greater than
>= Greater than or equal to
<  Less than
<= Less than or equal to
&  Bit test (format: expression & bitnumber)
!  Logical NOT
&& Logical AND
|| Logical OR
CARRY? Carry bit set
OVERFLOW? Overflow bit set
PARITY? Parity bit set
SIGN? Sign bit set
ZERO? Zero bit set

The comparison run-time operators are used to make comparisons between variables, registers, and constants as the program is being executed. Use these operators to give conditions for conditional-control directives (.IF, .UNTIL, .WHILE). These operators can be combined with other run- time operators and parentheses to form complex conditions.

The conditional-control directives (.IF, .UNTIL, .WHILE) can also check the state of processor flags. The CARRY?, OVERFLOW?, PARITY?, SIGN?, and ZERO? flags can be used directly in a C-style expression.

For example:

.IF !PARITY? || ( AX == 0 )
  ;Execute body of block if parity
  ;flag is clear or if the AX
  ;register is zero
.ENDIF

Note: The expression is evaluated from left to right, so in this example, the state of the parity flag is checked before the AX comparison.


DUP

Syntax: count DUP (initialvalue [,initialvalue]...)

Description
Specifies <count> declarations of <initialvalue>. You can define arrays, buffers, and other data structures consisting of multiple data objects of the same size with the DUP operator. The <initialvalue> parameters must be inside parentheses. This operator can be used with data definition directives.

The <count> parameter is the number of declarations of <initialvalue>. This parameter cannot be negative or forward-referenced. The <initialvalue> parameter is either the undefined data symbol (?), a string, a constant expression, or another DUP operator. The value or values of <initialvalue> are evaluated once before duplication. Separate multiple initial values with commas.


Data types

  Syntax:   [name] [S]BYTE initializer  [, initializer]...

            [name] [S]WORD initializer  [, initializer]...

            [name] [S]DWORD initializer [, initializer]...

            [name] FWORD initializer    [, initializer]...

            [name] QWORD initializer    [, initializer]...

            [name] TBYTE initializer    [, initializer]...

            [name] REAL4 initializer    [, initializer]...

            [name] REAL8 initializer    [, initializer]...

            [name] REAL10 initializer   [, initializer]...

Description
                            Integer
    Type    Abbr  Size      Range        Types Allowed
  +-------+-----+---------+------------+----------------------------------+
  | BYTE  | DB  | 1 byte  | -128 to    | Character, String                |
  |       |     |         | +255       |                                  |
  +-------+-----+---------+------------+----------------------------------+
  | WORD  | DW  | 2 bytes | -32,768 to | 16-bit near ptr, 2 characters,   |
  |       |     |         | +65,535    | double-byte character            |
  +-------+-----+---------+------------+----------------------------------+
  | DWORD | DD  | 4 bytes | -2Gig to   | 16-bit far ptr, 32-bit near ptr, |
  |       |     |         | +4Gig-1    | 32-bit long word                 |
  +-------+-----+---------+------------+----------------------------------+
  | FWORD | DF  | 6 bytes |    --      | 32-bit far pointer               |
  +-------+-----+---------+------------+----------------------------------+
  | QWORD | DQ  | 8 bytes |    --      | 64-bit long word                 |
  +-------+-----+---------+------------+----------------------------------+
  | TBYTE | DT  |10 bytes |    --      | BCD, 10-byte binary numbers      |
  +-------+-----+---------+------------+----------------------------------+
  +-------+-----+---------+------------+----------------------------------+
  | REAL4 | DD  | 4 bytes |    --      | Single-precision floating point  |
  +-------+-----+---------+------------+----------------------------------+
  | REAL8 | DQ  | 8 bytes |    --      | Double-precision floating point  |
  +-------+-----+---------+------------+----------------------------------+
  | REAL10| DT  |10 bytes |    --      | 10-byte floating point           |
  +-------+-----+---------+------------+----------------------------------+

These directives allocate and optionally initialize one or more bytes of global data. The S prefix indicates signed data, but this information is used internally by the assembler for comparisons used by control-flow directives and argument passing in INVOKE statements. CodeView also uses this information to specify the data format.

The abbreviations (such as DB, DD) are limited forms of the data-declaration directives; they cannot be used as types. They are included for compatibility with previous versions of the assembler.

String initializers, available with the BYTE directive, allocate a byte for each character of the string. The characters are stored with the leftmost character in the lowest memory location so that BYTE "WASHINGTON would be assembled to

57 41 53 48 49 4E 47 54 4F 4E "WASHINGTON"

Character initializers, however, are stored with the leftmost character in the highest memory location. They are also limited to the current expression size so that under the default OPTION EXPR32

DWORD "WASH"

would be assembled to

48 53 41 57 "HSAW"

and under OPTION EXPR16

WORD "WA"

would be assembled to

41 57 "AW"

Use the REAL4, REAL8, and REAL10 data types for floating-point data. They inform CodeView that the data is in floating-point format and cause the assembler to perform more stringent type checking.

Parameter Description
name Symbol name assigned to the variable. If no name is assigned, the memory space is allocated, but the starting address of the variable has no symbolic name.
initializer A type shown in the table above, constant integer expression, ?, or DUP expression. Separate multiple values with commas or use the DUP operator.


ECHO

Syntax: ECHO message

Description
Displays message during assembly. The message is usually output to the screen, but you can redirect it to a file or another device. This directive can help show which statements were assembled. %OUT is a synonym for ECHO and is included for compatibility.

The <message> is any line of ASCII characters up to but not including any comment on the line. If angle brackets are used to enclose <message>, the angle brackets are displayed. To perform macro substitution, put the macro substitution operator (%) at the beginning of the line. Use a separate ECHO directive for each line.

To output the time and date of assembly, insert this line in your source code:

% ECHO Assembled on @Date at @Time


END

Syntax: END [address]

Description
Marks the end of a source file and optionally indicates the program load address. The optional <address> is a label or expression identifying where program execution begins. You can define <address> only once in a program, usually in the main module.

You cannot specify <address> if you have used the .STARTUP directive, which automatically sets a start address. If you are linking with a high-level language, the start address is typically set by that language's compiler.

END also closes the last segment in the source file.


ENDS

Syntax: name ENDS

Description
Marks the end of a segment or a structure definition previously started with SEGMENT, STRUCT, or UNION. To end a simplified segment (such as one started with .DATA), use the line

@CurSeg ENDS ;End current segment

A single .STACK statement opens and closes the stack segment, so you should not include an additional ENDS statement.


EQU

Syntax: EQU TEXTEQU

 Syntax: name EQU expression

name EQU <text>
name TEXTEQU textmacro
name TEXTEQU %expression

Description
The EQU directive assigns <expression> or <text> to <name>. Angle brackets indicate that <text> should not be evaluated as an expression.

EQU evaluates the numeric value of <expression> and assigns the resulting constant value to <name>. Unlike =, EQU does not allow numeric equates to be redefined. If <expression> cannot be evaluated, EQU treats <expression> as text.

The TEXTEQU directive acts like the EQU directive with text equates but performs macro substitution at assembly and does not require angle brackets. The TEXTEQU directive will also resolve the value of an expression preceded by a percent sign (%). The EQU directive does not perform macro substitution or expression evaluation for strings.

Text equates are limited to 255 characters. Text equates can be redefined to another value but not to a different type of symbol.

Parameter Description
name Symbolic name for <expression> or <text>

expression Variable or constant numeric expression (not a memory expression)

text String enclosed in angle brackets (<>)

textmacro A text macro (such as @Date) or a string enclosed in angle brackets (<>).

expression An expression preceded by a %.

Example
MASM EQU 5.1 + 0.9     ; Evaluates to 6.0
Msft EQU <Microsoft>   ; String equate
libpath TEXTEQU @Environ(<LIB>) ; Text Macro Equate
endstr TEXTEQU %(endadr-staradr); String equate to numeric value


EXTERNDEF

Syntax: EXTERNDEF [langtype] name:qualifiedtype
[, [langtype] name:qualifiedtype]...

EXTERN [langtype] name[(altID)]:qualifiedtype
[, [langtype] name[(altID)]:qualifiedtype]...

Description
The EXTERNDEF directive tells the assembler that one or more variables, symbols, data structures, or labels are defined in other modules. The behavior of the EXTERNDEF directive is determined by its context:

* If <name> is used in the current module but is not defined, <name> is made external. * If <name> is defined in the current module, it is made PUBLIC. * If <name> is neither used nor defined, the directive is ignored.

The EXTERNDEF directive allows you to put global data declarations in an include file without forcing the linker to pull in unneeded modules. Usually, you define <name> in one module and put the EXTERNDEF directive in a file that is included in all program modules. The PROTO directive automatically generates an EXTERNDEF for its related procedure.

EXTERN is a less flexible version of EXTERNDEF. It declares <name> as external whether or not it is used in the module. EXTRN is a synonym for EXTERN and is included for compatibility with previous versions of the assembler.

With the EXTERN directive, <name> can be followed by (altID), which allows the linker to select an alternate resolution for <name>. This is useful when creating library files.

Parameter Description
langtype A language type appropriate to <name>.

name A unique global symbolic name. Case mapping is overridden by OPTION CASEMAP.

qualifiedtype The qualified type to be given to <name>. Can also be ABS, which causes <name> to be imported as a constant. Does not have to match type given to <name> in original definition.

altID A unique global symbolic name to use as an alternate for <name>. Must be of the same type as <name>. The <altID> parameter cannot be declared as a <name> with an altID in an EXTERN statement in this or any other module.


Flat memory model

The flat memory model creates a program that contains one 32-bit segment for program data and program code. The code generated with the flat-model option will run only on 80386/486 processors. A .386 or .486 processor directive must precede the .MODEL directive that specifies the flat memory model.

This memory model causes the assembler to produce files with the .EXE extension.

All segment registers are automatically set to the same value with this memory model. The defaults in flat-model programs are NEAR code addressing and NEAR data addressing. The PROC distance is NEAR under the flat-model option. @CodeSize is 0, @DataSize is 0, and @Model is 7.

The FS and GS segment registers are not needed for flat-model programs. The .MODEL FLAT statement automatically generates this assumption:

ASSUME cs:FLAT, ds:FLAT, ss:FLAT, es:FLAT, fs:ERROR, gs:ERROR

When defining segments with the SEGMENT directive, you should use this ASSUME in your code.


HIGH

HIGH LOW

Syntax: HIGH expression
LOW expression

Description
The HIGH operator returns the high-order (most significant) byte of [expression] in two's-complement form. The LOW operator returns the low-order (least significant) byte of [expression] in two's- complement form. The [expression] must resolve to a constant or an OFFSET expression.


HIGHWORD

HIGHWORD LOWWORD

Syntax: HIGHWORD expression
LOWWORD expression

Description
The HIGHWORD operator returns the high-order (most significant) word of <expression> in two's-complement form. The LOWWORD operator returns the low-order (least significant) word of <expression> in two's- complement form. The <expression> must resolve to a constant or an OFFSET expression.


INCLUDE

Syntax: INCLUDE filename

INCLUDE <filename>

Description
Inserts source code from <filename> into the current source file during assembly. If <filename> does not include a fully-specified path, the assembler searches the directory of the current file, the /I command-line include path or the PWB include path, and then the INCLUDE environment variable. Nested INCLUDE directives are allowed.

The <filename> parameter is an existing file containing valid assembly-language statements and directives. No default file extension is assumed. Angle brackets are required if the filename or path includes a backslash, semicolon, greater-than, less-than, single quotation marks, or double quotation marks.


INCLUDELIB

Syntax: INCLUDELIB libraryname

INCLUDELIB <libraryname>

Description
Informs the linker that the current module should be linked with the <libraryname>. If <path> is not given, the linker searches the current working directory, directories given in the ML or LINK library field, and then the LIB environment variable from the TOOLS.INI file.

The <libraryname> parameter is an existing file containing code in LIB format. If no extension is specified, the default extension .LIB is assumed. Angle brackets are required if the libraryname or path includes a backslash, semicolon, greater-than, less-than, single quotation marks, or double quotation marks.


invoke

Syntax: INVOKE expression [,arguments]

Description
Automates the call interface to stack-based procedures. Handles all pushing of parameters onto the stack. Cleans up the stack when the procedure returns.

The <invokelist> is passed to the procedure according to the types given in that procedure's prototype. If necessary, the assembler will generate code to convert the elements of <invokelist> to the types specified in the prototype.

Parameter Description
expression Expression yielding address or label of procedure to be called. Must resolve to a valid address and cannot include any forward references.

arguments Sequential list of parameters passed. Can be register::register (for a register pair), expression, or ADDR label. ADDR label passes the address of <label> (segment and offset if DWORD, segment only if WORD) to the procedure.


LABEL

Syntax: name LABEL qualifiedtype

Description
Creates a new label of a given type at a specified location by assigning the current location-counter value and the given type to <name>. The <qualifiedtype> parameter determines the type of data or call distance for the label. This directive does not allocate data.

Parameter Description
name Symbol assigned to the label.
qualifiedtype Any qualified type.


LENGTHOF

Size operators

LENGTHOF variable

SIZEOF variable

SIZEOF type

LENGTH expression

SIZE expression

Description

The LENGTHOF operator returns the number of data items allocated for <variable>. The SIZEOF operator returns the total number of bytes allocated for <variable> or the size of <type> in bytes. For variables, SIZEOF is equal to the value of LENGTHOF times the number of bytes in each element.

The LENGTH and SIZE operators are allowed for compatibility with previous versions of the assembler. When applied to a data label, the LENGTH operator returns the number of elements created by the DUP operator; otherwise it returns 1. When applied to a data label, the SIZE operator returns the number of bytes allocated by the first initializer at the <variable> label.

The LENGTHOF and SIZEOF operators in MASM 6.1 handle arrays much more consistently. These operators return the number of data items and the number of bytes in an initializer.


LOCAL

Syntax: LOCAL name [[count]][:qualifiedtype] [, name [[count]] [:qualifiedtype]]...

Description
Generates code to create one or more stack (automatic) variables, which can be accessed only within the current procedure. The assembler uses the same method used by high-level languages to create local variables.

The <name> parameter is the name of the variable, and <count> is an optional expression (which must appear in square brackets) indicating the number of elements to allocate. The <qualifiedtype> parameter is any qualified type appropriate to <name>. The default <qualifiedtype> is WORD in a 16-bit segment and DWORD in a 32-bit segment.

Once declared in a LOCAL statement, local variables can be referred to by name. The assembler translates references to these variables into references to their actual location on the stack using the BP indirect addressing mode.

The assembler will generate an error if you have already defined <name> as a label.

Example
LOCAL array[20]:BYTE


LROFFSET

Syntax: LROFFSET expression

Description
Similar to OFFSET, but causes the offset to be resolved by the loader at run time. LROFFSET is usually applied to the offset of a function pointer. This run-time resolution allows Microsoft Windows to relocate code segments in real mode.

The <expression> is any label, variable, or other direct memory operand.

Example
INVOKE CreateRoutine, LROFFSET MyFunc, 0


Line continuation

Line Continuation
  Syntax: text \
text

Description
Enables an assembly-language statement to continue on the next line, ignoring the line break. You can join any number of physical lines with this method. A backslash occurring inside a comment or string is not considered to be a line-continuation character. Logical lines cannot exceed a total of 512 characters.

Comments can appear to the right of the \. A backslash is not required on a line ending with a comma.


Local code labels

Syntax: [instruction] @F
.
.
.
@@: [statement]
.
.
.
[instruction] @B

Description
The @@: label defines a local code label, which is in effect until the next instance of @@:. The @F and @B operands can be used in conditional and unconditional jump statements to jump to the next and previous @@: label respectively.

The @@: label is useful for defining a nearby jump point where a full label is not appropriate.

Example
cmp ax, 18h
jg @F
-            ; Less than or equal
-
-
@@:          ; Greater than

mov cx, 640  ; Set count

@@:
-            ; Loop statements
-
-
loop @B      ; Loop back


Location Counter $

Syntax: $

Description
Equates to the current value of the location counter (current offset address). Equivalent to THIS NEAR.

Example
title BYTE "Space Mutants II"
level WORD 0
hiscore BYTE 20 DUP (?)
tablelen EQU $-title ;tablelen = 38

In compatibility mode, the current address operator ($) applied to a structure returns the offset of the first byte of the structure. When OPTION M510 is not enabled, $ returns the offset of the current field in the structure.


Logical operators

Syntax: expression1 AND expression2

expression1 OR expression2

expression1 XOR expression2

NOT expression

expression SHL count

expression SHR count

Description
These operators perform logical manipulations of constant integer expressions. They return expressions of the size determined by the current expression size. Use the LOW and LOWWORD operators to return expressions of smaller sizes.

These operators should not be confused with their instruction counterparts. Operators cannot act on registers or memory.

Operand Description
expression Any constant integer expression in any valid radix.
count The number of bits to be shifted. Must be a constant positive integer. Bits shifted in are always 0.


MASK

Syntax: MASK record

MASK recordfieldname

Description
Returns a bit mask for the bit positions in a record or record field. A bit in the mask contains a 1 if that bit corresponds to a field bit. All other bits contain 0.

The <record> parameter is the name of any record. The <recordfieldname> parameter is the name of any field in a record.


Macro expression

Syntax: %expression

Description
Computes the value of <expression> and treats it as a text string. Use in macro calls when you need to pass the result of an expression rather than the actual expression to a macro. The <expression> can also be a text macro or a macro function.

When placed at the beginning of the line, % causes the calculation and substitution of all text macros on that line, including those inside angle brackets (<>). Macro function calls inside angle brackets (<>) are not expanded unless preceded by a %.


Memory model

Your choice of a memory model determines how memory is set up for program code and data. The following table shows attributes of the different memory models. Select a memory model for more information.

         Code      Data      Segment  Data and Code
              Distance  Distance  Width    Combined?
             +---------+---------+--------+-------------+
     Tiny    | NEAR    | NEAR    | 16-bit | Yes         |

             +---------+---------+--------+-------------+
     Small   | NEAR    | NEAR    | 16-bit | No          |
             +---------+---------+--------+-------------+
     Compact | NEAR    | FAR     | 16-bit | No          |
             +---------+---------+--------+-------------+
     Medium  | FAR     | NEAR    | 16-bit | No          |
             +---------+---------+--------+-------------+
     Large   | FAR     | FAR     | 16-bit | No          |
             +---------+---------+--------+-------------+

     Huge    | FAR     | FAR     | 16-bit | No          |
             +---------+---------+--------+-------------+
     Flat    | NEAR    | NEAR    | 32-bit | Yes         |
             +---------+---------+--------+-------------+

The OPTION SEGMENT and SEGMENT directives can override the default segment width.


Name Assignment

Syntax: name = expression

Description
Creates or redefines a constant symbol by assigning the numeric value of [expression] to [name]. This equate can be used in subsequent statements as a symbolic constant and can be redefined at any time.

The [name] field must be either a unique name or one previously defined with =. The [expression] fieldis any valid constant expression. Resolved at definition by the assembler.


OFFSET

Syntax: OFFSET expression

Description
Returns offset address of <expression> (usually a variable). The value returned by the OFFSET operator is an immediate operand. OFFSET can be applied to any immediate or memory expression except a register or segment.

The offset returned is relative to either the current group or segment. If there is both a current group and a current segment, the offset will have a group-relative default offset. This default can be changed with the M510 and OFFSET: options.

The OFFSET operator can accept an expression specifying a segment. In this case, the OFFSET operator returns the offset of the last byte of the given segment, relative to that segment's group. This value reflects the size of the given segment when the OFFSET operator is assembled.

The <expression> is any label, variable, segment, or other direct memory operand.


OPATTR

Syntax: OPATTR expression

.TYPE expression

Description
The OPATTR operator returns a one-word constant defining the mode and scope of expression. If <expression> is not valid or is forward- referenced, OPATTR returns a 0. If <expression> is valid, a nonrelocatable word is returned. The .TYPE operator returns only the low byte (bits 0-7) of the OPATTR operator and is included for compatibility with previous versions of the assembler.

Bit Set If
Position <expression>

0 References a code label
1 Is a memory expression or has a relocatable data
label
2 Is an immediate expression
3 Uses direct memory addressing
4 Is a register expression
5 References no undefined symbols and is without error
6 Is an SS-relative memory expression
7 References an external label
8-10 Language type:

Bits Language

000 No language type
001 C
010 SYSCALL
011 STDCALL
100 Pascal
101 FORTRAN
110 Basic

All other bits (11-15) are undefined and reserved for future expansion.


OPTION CASEMAP

Syntax: OPTION CASEMAP:maptype

Description
Controls the mapping of characters to uppercase. The <maptype> parameter can be ALL, NONE, or NOTPUBLIC, which correspond to the /Cu, /Cp, and /Cx command-line options. You can use this option only once per source file. The current language type, if any, will override <maptype>.

CASEMAP:NOTPUBLIC is the default. The CASEMAP option is set to ALL with the M510 option.


OPTION DOTNAME

Syntax: OPTION DOTNAME

OPTION NODOTNAME

Description
The DOTNAME option enables the use of the period (.) as the leading character in variable, label, macro, struct, union, and member names. NODOTNAME is the default. The DOTNAME option is enabled with the M510 option, since previous versions of the assembler recognized names with period prefixes.

The DOTNAME option does not have any effect on any of the reserved words. The use of the period in names is discouraged, as it can be confused with the field offset and structure operators.

If you don't want to use this directive in your source code, rename the identifiers whose names begin with a period.


OPTION EMULATOR

Syntax: OPTION EMULATOR
OPTION NOEMULATOR

Description
Controls how floating-point instructions are generated. NOEMULATOR, the default, generates the coprocessor instructions directly. EMULATOR generates instructions as well as special fixup records for the linker so that the floating-point emulator can be used. This option is definable only once per source file.

To use this option, you must link your assembly-language module with an emulator library from a Microsoft high-level language.

OPTION EMULATOR is equivalent to the /FPi command-line option.


OPTION EXPR16

Syntax: OPTION EXPR16

Description
The EXPR32 option selects 32-bit expressions and arithmetic. The EXPR16 option selects 16-bit expressions and arithmetic. The default is EXPR32. The expression word size cannot be changed once it has been explicitly set.

These options do not affect the processor type, segment size, or registers used.

Under OPTION M510, EXPR16 is the default unless the module contains a .386 or greater processor-selection directive.

MASM 5.1 treats expressions as 16-bit words if you do not specify .386 or .386P directives. MASM 6.1 by default treats expressions as 32-bit words regardless of the CPU type. You can force MASM 6.1 to use the smaller expression size with the OPTION EXPR16 statement.

Unless your MASM 5.1 code specifies .386 or .386P, OPTION M510 also sets 16-bit expression size. You can selectively disable this by following OPTION M510 with the OPTION EXPR32 directive, which sets the size back to 32 bits. You cannot have both OPTION EXPR32 and OPTION EXPR16 in your program.

It may not be easy to determine the effect of changing from 16-bit inter- nal expression size to 32-bit size. In most cases, the 32-bit word size does not affect the MASM 5.1 code. However, problems may arise because of differences in intermediate values during evaluation of expressions. You can compare the files for differences by generating listing files with the /Fl and /Sa command-line options with and without OPTION EXPR16


OPTION LANGUAGE

Syntax: OPTION LANGUAGE:langtype

Description
Specifies the default language type to be used with many directives. The most recent OPTION LANGUAGE: or .MODEL directive determines the current language type. The <langtype> parameter is any language type.


OPTION LJMP

Syntax: OPTION LJMP

OPTION NOLJMP

Description
The LJMP option enables automatic conditional-jump lengthening. LJMP is the default.

Enabling LJMP allows the assembler to generate code that emulates a conditional jump of greater than -128 to +127 bytes. If the jump is within this range, no special code is generated. It does not affect unconditional jumps or the control-flow directives.

The assembler will generate an A6003 warning for a lengthened jump so that you can identify it for later optimization.


OPTION NOKEYWORD

Syntax: OPTION NOKEYWORD:<keywordlist>

Description
Disables the recognition of the reserved words in <keywordlist> for the current module. The listed keywords can then be used as user-defined symbols. Keywords disabled with this directive cannot be reenabled. The <keywordlist> is a space-delimited list of reserved words; literal operands and predefined symbols are not allowed. The list of keywords must be enclosed in angle brackets (<>).

You can use this option to disable privileged instruction names or obsolete synonyms so they are free to be used as labels and variables. For example:

OPTION NOKEYWORD: <STR EXTRN IRPC>
STR BYTE 10 DUP (?)

MASM 6.1 has several new keywords that MASM 5.1 does not recognize as reserved. To resolve any conflicts, you can rename any offending symbols in your code, or selectively disable keywords with the OPTION NOKEYWORD directive.

The second option lets you retain the offending symbol names in your code by forcing MASM 6.1 to not recognize them as keywords. For example,

OPTION NOKEYWORD:<INVOKE STRUCT>

removes the keywords INVOKE and STRUCT from the assembler's list of reserved words. However, you cannot then use the keywords in their intended function, since the assembler will no longer recognize them.


OPTION NOSIGNEXTEND

Syntax: OPTION NOSIGNEXTEND

Description
The NOSIGNEXTEND option disables the generation of the sign- extended form (83h) of the AND, OR, and XOR instructions. The NEC V25 and V35 microprocessors do not support this opcode.


OPTION OFFSET

Syntax: OPTION OFFSET:offsettype

Description
Controls whether the OFFSET operator returns offsets relative to the current segment or group. OPTION OFFSET:GROUP causes OFFSET to return a group-relative offset if the label is in a segment that is part of a group. OPTION OFFSET:SEGMENT causes OFFSET to return a segment-relative offset. OPTION OFFSET:GROUP is the default.

The FLAT option causes fixups to be relative to the FLAT group.

OPTION M510 sets OPTION OFFSET:GROUP if a .MODEL directive has been used and OPTION OFFSET:SEGMENT otherwise. With previous versions of the assembler, the OFFSET type was SEGMENT with complete segment directives and GROUP with simplified segment directives.

The <offsettype> can be GROUP, SEGMENT, or FLAT.

When programming for the 80386 or 80486, the size of an OFFSET expression can be 2 bytes for a symbol in a USE16 segment, or 4 bytes for a symbol in a USE32 or FLAT segment. With OPTION M510, you can use a 32-bit OFFSET expression in a 16-bit context. Without OPTION M510, you must use the LOWWORD operator to convert the offset size.

With no .MODEL, MASM 5.1 computes offsets from the start of the segment, whereas MASM 6.1 computes offsets from the start of the group. (With .MODEL, MASM 5.1 also computes offsets from the start of the group.)

To force MASM 6.1 to emulate 5.1 behavior, specify either OFFSET:SEGMENT or OPTION M510. Both directives cause the assembler to compute offsets relative to the segment if you do not include .MODEL.

To selectively enable MASM 6.1 behavior, place the directive OPTION OFFSET:GROUP after OPTION M510. In this case, you should ensure each OFFSET statement has a segment override where appropriate.

When not in compatibility mode, the OPTION OFFSET directive determines whether the SEG operator returns a value relative to the group or segment. With OPTION M510, SEG is always segment-relative by default, regardless of the current value of OPTION OFFSET.


OPTION PROC

Syntax: OPTION PROC:visibility

Description
Sets the default procedure visibilty. The <visibility> parameter can be PRIVATE, PUBLIC, or EXPORT. If you do not use this option, the the default visibility will be PUBLIC.

With OPTION M510, the default <visibility> with no defined language type is PRIVATE. If you specify a language type in a .MODEL or OPTION LANGUAGE statement, the default <visibility> is PUBLIC.

Without a language type, MASM 5.1 makes procedures private to the module. By default, MASM 6.1 makes procedures public. You can explicitly change the default visibility to private with either OPTION M510, OPTION PROC:PRIVATE, or OPTION PROC:EXPORT.

To selectively enable MASM 6.1 behavior, place the directive OPTION PROC:PUBLIC after OPTION M510. You can override the default by adding the PUBLIC or PRIVATE keyword to selected procedures.


OPTION PROLOGUE

Syntax: OPTION PROLOGUE:macroname

OPTION EPILOGUE:macroname

Description
PROLOGUE registers <macroname> as the macro function to be called when a prologue needs to be generated. EPILOGUE registers <macroname> as the macro procedure to be called when a RET or IRET instruction is encountered.

You can revert to the default prologue or epilogue by specifying PrologueDef or EpilogueDef as <macroname>. EPILOGUE code is generated only if the RET or IRET instruction terminating the PROC block has no operand. The RETN, RETF, and IRETF instructions do not cause the assembler to generate epilogue code.

To suppress generation of the prologue or epilogue code, give NONE as the <macroname>.

The assembler expects a macro definition of this form:

macroname MACRO procname, flags, argbytes, localbytes, <reglist>, userparms:VARARG

Parameter Description
procname Macro name for the procedure or NONE.

flags Word-size bit flag: (1=On, 0=Off)

Bits Description
0-2 Language type:
000 Not specified
001 C
010 SYSCALL
011 STDCALL
100 Pascal
101 Fortran
110 Basic
111 Reserved
3 Reserved
4 Caller restores stack
5 FAR procedure
6 PRIVATE procedure
7 EXPORT procedure
8 Epilogue caused by IRET instruction

All other bits are reserved for future use.
argbytes The total number of bytes used by PROC arguments.

localbytes The total number of bytes used by variables defined with the LOCAL directive inside the PROC block.

reglist Comma-delimited list of registers from the PROC directive USE option. This list is reversed in in the EPILOGUE directive. Angle brackets are passed.

userparms Passed the optional macroarglist from the PROC directive.


OPTION READONLY

Syntax: OPTION READONLY

OPTION NOREADONLY

Description
The READONLY option sets the READONLY attribute for subsequent code segments. Enables checking for instructions that explicitly modify segments or groups containing code. Useful for detecting self- modifying code. NOREADONLY is the default.

This option replaces the command-line /P option from previous versions of the assembler. Segments can be also be made read- only with the READONLY parameter of the SEGMENT directive.


OPTION SCOPED

Syntax: OPTION SCOPED

OPTION NOSCOPED

Description
The SCOPED option causes a label (defined with the "label:" syntax) to be local to the procedure in which it is defined. Labels defined with the LABEL directive or the "label::" syntax are not affected by this option.

Using NOSCOPED will cause all labels to be global to the module. SCOPED is the default. The NOSCOPED option is enabled with the M510 option, if the .MODEL directive is used without a language type specification. Specifying .MODEL with a language type enables OPTION SCOPED.

Without a language type, MASM 5.1 assumes code labels in procedures have no scope--that is, the labels are not local to the procedure. When not in compatibility mode, MASM 6.1 always gives scope to code labels, even without a language type.

To force MASM 5.1 behavior, specify either OPTION M510 or OPTION NOSCOPED in your code. To selectively enable MASM 6.1 behavior, place the dir- ective OPTION SCOPED after OPTION M510.

To determine which labels require change, assemble the module without the OPTION NOSCOPED directive. For each reference to a label that is not local, the assembler generates error A2006.


OPTION SEGMENT

Syntax: OPTION SEGMENT:segmentsize

Description
The SEGMENT:USE16 option selects 16-bit segments. The SEGMENT:USE32 option selects 32-bit segments. The SEGMENT:FLAT option selects the 32-bit flat segment. This option overrides the segment size set optionally set by the SEGMENT and .MODEL directives.

The default segment size is selected by the following rules:

* A .386 or higher processor selection directive selects USE32.

* A .MODEL FLAT statement selects FLAT. All other memory models select USE16.

* The OPTION SEGMENT: directive will override any other defaults.

* In all other cases, the default is USE16.


ORG

Syntax: ORG expression

ORG $+expression

Description
Sets the location counter to a specific address, given by <expression>. The assembler implements this directive by adjusting the location counter.

ORG $+expression causes the assembler add <expression> bytes to the location counter. The <expression> must evaluate to a constant without forward references.

Inside a STRUCT block, the <expression> parameter is relative to the beginning of the structure. This can be used to create structure elements that refer to bytes lower in memory than the beginning of the structure.


PROC

Syntax: label PROC [distance] [langtype] [visibility]
[<prologuearg>]
[USES reglist] [,parameter [:tag]]...
[LOCAL varlist]
statements
label ENDP

Description
Defines a procedure called <label>. To use <parameter>, you must have previously specified a language type or used the <langtype> parameter. You should use a PROTO prototype before each procedure defined with the PROC directive. This ensures proper type checking and allows you to call the procedure with the INVOKE directive.

Procedures usually end with the RET instruction. You can remove data from the stack by specifying the number of bytes as a parameter of the RET instruction.

The assembler automatically generates PROLOGUE and EPILOGUE code to pass stack arguments properly to the procedure and clean up the stack after completion of the procedure. You can override the default prologue and epilogue code with user-defined macros by using the OPTION PROLOGUE: and OPTION EPILOGUE: directives. The RETF or IRETF instructions do not cause the assembler to generate epilogue code.

Procedures can be nested if they do not have parameters, local variables or the USES parameter and do not generate a new segment or group. You can avoid having to nest procedures by using the RETN and RETF instructions.

Local variables must be declared (using the LOCAL directive) before any instructions. There can be several LOCAL statements in a procedure.

Parameter Description

label Defines name for the procedure. Follows naming convention of <langtype>.

prologuearg Arguments to pass to the prologue procedure. With the default PROLOGUE and EPILOGUE, the FORCEFRAME argument generates a stack segment, even if one is not necessary. LOADDS causes the DS register to be saved in the PROLOGUE and restored in the EPILOGUE. Parameters must be separated by commas. Angle brackets are required but not passed.

distance NEAR, FAR, NEAR16, NEAR32, FAR16, or FAR32. Indicates the call distance of this procedure. If you choose NEAR or FAR, the assembler will select 16- or 32-bit NEAR or FAR depending on the current segment size. If you do not specify this option, the assembler determines the distance from the memory model and processor type. NEAR is the default if you do not use the .MODEL directive.

langtype Any valid language type. Determines naming style and calling convention.

visibility PRIVATE, PUBLIC, or EXPORT. Determines how the procedure is made available to other modules. PUBLIC is the standard default, but the default can be reset with the OPTION PROC directive. EXPORT implies PUBLIC and FAR and informs the linker that the procedure should be placed in the export entry table.

reglist List of registers that the prologue preserves on the stack and the epilogue restores on exit. Separate multiple registers with spaces.

parameter Procedure parameter. The assembler translates argument references into a direct reference to the stack location. Separate multiple arguments with commas.

tag Either a qualified type or VARARG. VARARG allows a variable number of arguments to be passed as a comma separated list to <argument>. If VARARG is used, it must be applied to the last parameter of the PROC directive. VARARG is only allowed with the C, SYSCALL, and STDCALL language types. If <tag> is omitted, the assembler defaults to WORD in a 16-bit segment or DWORD in a 32-bit segment.

statements Assembly-language statements and directives.


PROTO

Syntax: label PROTO [distance] [langtype] [, [parameter]:tag]...

Description
Defines a prototype for a subsequent procedure. Informs the assembler about how many and what kind of arguments should be expected in a procedure definition. This allows the assembler to perform type checking on arguments.

If you define a prototype for all stack-based procedures defined with the PROC directive, you can place procedure prototypes in a separate include file. This is recommended when using procedures in a library file.

Parameter Description
label Defines name for the procedure. Must exactly match <label> in PROC definition.

distance NEAR, FAR, NEAR16, NEAR32, FAR16, or FAR32. Indicates the call distance of this procedure. If you choose NEAR or FAR, the assembler will select 16- or 32-bit NEAR and FAR depending on the processor directive in effect. If you do not specify this option, the assembler determines the distance from the memory model and processor type. NEAR is the default if you do not use the .MODEL directive.

langtype Any valid language type. Determines naming style and calling convention.

parameter Procedure parameter. The assembler translates argument references into a direct reference to the stack location. Separate multiple arguments with commas.

tag Either a qualified type or VARARG. VARARG allows a variable number of arguments to be passed as a comma separated list to <argument>. If VARARG is used, it must be applied to the last parameter of the PROC directive. VARARG is only allowed with the C, SYSCALL, and STDCALL language types.


PTR

Syntax: qualifiedtype PTR expression
PTR qualifiedtype

Description
The first syntax treats <expression> as having the specified type. Type casting can be used with forward references or unlabeled addresses to specify a reference size, type, or distance.

The second syntax is used in defining qualified types.

The PTR keyword can also appear in qualified types to indicate that the type is a pointer variable.

The <qualifiedtype> can be any qualified type. The <expression> can be any valid expression. If <qualifiedtype> is a distance, <expression> cannot be a memory expresssion or a data label.

You can use a constant as the left operand to PTR in compatibility mode. Otherwise, you must use a type expression. With OPTION M510, a constant must have a value of 1 (BYTE), 2 (WORD), 4 (DWORD), 6 (FWORD), 8 (QWORD) or 10 (TBYTE). The assembler treats the constant as the parenthesized type. Note that the TYPE operator yields a type expression, but the SIZE operator yields a constant.

; With OPTION M510

    MyData  DW      0

    mov     WORD PTR [bx], 10           ; Legal
    mov     (TYPE MyData) PTR [bx], 10  ; Legal
    mov     (SIZE MyData) PTR [bx], 10  ; Legal
    mov     2 ptr [bx], 10              ; Legal

; Without OPTION M510

    MyData  WORD    0

    mov     WORD PTR [bx], 10           ; Legal
    mov     (TYPE MyData) PTR [bx], 10  ; Legal
;    mov     (SIZE MyData) PTR [bx], 10  ; Illegal
;    mov     2 PTR [bx], 10              ; Illegal
Example
mov        ax, (MyStruct PTR [bx]).Username
fld        TBYTE PTR MaxConvolution
INVOKE     MyRoutine, PTR TempValue

Under MASM 5.1, applying the PTR operator to a data initializer de- termines the size of the data displayed by CodeView. You can still use PTR in this manner in MASM 6.1, but it does not affect CodeView typing. Defining pointers with the TYPEDEF directive allows CodeView to generate correct information.


PUBLIC

Syntax: PUBLIC [langtype] name [,[langtype] name]...

Description
Makes one or more variables available to other modules in the program. PUBLIC names can be forward referenced.

The following can be made PUBLIC:

* NEAR and FAR code labels and procedures
* Data created with user-defined types, BYTE, WORD, and other types
* Data created with user-defined structures, unions, and records
* Labels created with the LABEL directive
* Symbolic constants created with EQU or =

The PUBLIC directive is normally used with the EXTERN directive. The EXTERNDEF and COMM directives allow more flexibility in global data declaration than the PUBLIC and EXTERN directives. One use is illustrated below.

                  +----------------------------------+
                  |                                  |
     +-USER.ASM---+-----------+        +-TOOLS.ASM---+----------+
     |                        |        |                        |
     | EXTERN global:WORD     |        |         PUBLIC  Global |
     |                        |        | Global  WORD    5      |
     +------------------------+        +------------------------+

Parameter Description

langtype Any language type. Used to control what format label names are sent to the linker.
name The name of a variable, label, or numeric equate defined within the current source file.


PURGE

Syntax: PURGE macroname [, macroname]...

Description
Deletes one or more currently defined macros from memory. Use this directive if your system does not have enough memory to keep all the macros needed for a source file in memory at the same time. The macro skeleton will remain, but it will not expand.

A macro can remove itself if PURGE is on the last line of the macro. Redefining a macro automatically purges the previous definition. Calling a purged macro is legal, but the macro will act like a blank macro.


RECORD

Syntax: recordname RECORD field [, field]...

Description
Declares a record template of one or more specified bit fields but does not allocate storage for the template. Separate multiple fields with a comma.

Records can be used as constants or expressions. They are treated as a BYTE or WORD with 16-bit expressions and as a BYTE, WORD, or DWORD with 32-bit expressions. The sum of the widths for all fields must not exceed the expression width.

Once a record template is declared, you can use it to define record variables or constants, in which each field not initialized assumes the default value. Records are defined with the following syntaxes:

[name1] recordname {[initializer1] [, initializer2]...}
[name1] recordname <[initializer1] [, initializer2]...>

Use of <recordname> is similar to the other variable definition directives (such as BYTE and WORD). Curly braces or angle brackets are required even if no initializers are given.

If a record constant appears as part of an expression in a control flow directive (such as .IF or .WHILE), you must use curly braces instead of angle brackets to enclose the fields.

The assembler will treat the name of a record field without the MASK or WIDTH operators as the bit number of the first bit of the record field.

Parameter Description

recordname A unique symbolic name.

field Each field is in the form

fieldname:width[= expression]

where <width> is a constant giving the width of the field (in bits) and <expression> optionally sets an initial or default value.


RADIX SPECIFIERS
Name          Base   Specifier  Digits

Binary           2   Y or B     0 1
Octal            8   Q or O     0 1 2 3 4 5 6 7
Decimal         10   T or D     0 1 2 3 4 5 6 7 8 9
Hexadecimal     16   H          0 1 2 3 4 5 6 7 8 9 A B C D E F
Floating- point 10   R          0 1 2 3 4 5 6 7 8 9 . E + -

To indicate the radix of a constant, place the specifier at the end of the number. Specifiers and hexadecimal digits can be uppercase or lowercase.

Hexadecimal numbers must always start with a decimal digit (0-9). If the first digit is one of the letters A to F, prefix the number with a leading 0 to distinguish it from a symbolic name.

If the current default radix, specified by the .RADIX directive, is 10 or less, B and D are treated as radix overrides. B and D are treated as hexadecimal digits if the default radix is above 11 or above 13, respectively.

Floating-point constants may be used as initializers only with the REAL4, REAL8, REAL10, DWORD, QWORD, and TBYTE directives. Floating- point constants can be represented with an optional exponent or a decimal point.

Example

INVOKE MyRoutine, 01001010Y, 43H, 75, 0AFH
mole REAL4 6.023E+23
pi REAL8 3.1415927
Xenon REAL10 54R


SHORT

Syntax: SHORT label

Description
Forces <label> type to SHORT. Normally, the assembler selects short jumps and branches when possible, but SHORT can be used to generate an error if a short jump to <label> is not possible. It disables any automatic conditional-jump lengthening (OPTION LJMP).

Short labels can be used in JMP instructions when the distance is less than 128 bytes from the start of the next instruction. This saves a byte of memory and reduces the number of clock cycles used.


STRUCT

Syntax: name STRUCT [alignment] [, NONUNIQUE]
  fielddeclarations
name ENDS

Description
Declares a structure as a new data type. STRUC is a synonym for STRUCT and is included for compatibility.

Once a structure name is declared, you can use it to define variables in which each field not initialized assumes the default value:

  [name] structname <[initializer [, initializer]...]>
    or
  [name] structname { \
  [initializer] \
  [, initializer]... \
  }
    or
  [name] structname constant DUP ({[initializer[, initializer]...]})

Curly braces or angle brackets are required even if no initializers are given. The DUP operator can be used to make duplicate initializations. Structures may be nested.

You must refer to structure members in the format structurename.membername or with a pointer to a structure followed by the .membername tag. You can use multiple sequential membernames to specify elements of nested structures.

The NONUNIQUE parameter requies elements of the structure to be accessed only by their fully specified names.

The ORG directive has a special meaning inside a STRUCT block.

Parameter Description
name A unique symbolic name for the structure.

alignment 1, 2, or 4. Byte boundary to align structure fields. The default is 1.

fielddeclarations Any valid data definitions (using BYTE, WORD, etc.) with initial values. Can also be another previously defined structure or a user-defined type. Field names do not need to be unique; you can reuse the same name in multiple structures. Some other directives are allowed in this field; see the BNF Appendix in the MASM Programmer's Guide.

initializer Data initializer for structure field.


THIS

Syntax: THIS qualifiedtype

Description
Returns an operand of <qualifiedtype> with offset and segment values equal to the current location-counter value. THIS can be used with EQU or = to create labels and variables. THIS NEAR is equivalent to $.

These two lines are equivalent:

tag1 EQU THIS BYTE
tag1 LABEL BYTE

The <qualifiedtype> can be any qualified type.


TYPE

Syntax: TYPE expression

Description
The TYPE operator returns a value and size and distance attributes appropriate to <expression>. You can use the constant returned by TYPE directly or use the attributes returned by TYPE. For example, you can use the returned attribute to specify a type for PTR.

<expression> Returns

Variable Number of bytes allocated for each element
Structure Total number of bytes in the structure
Constant 0
Code label Distance
Register Size of register in bytes


TYPEDEF

Syntax: name TYPEDEF qualifiedtype

name TYPEDEF PROTO prototypelist

Description
Defines a new type or creates a synonym for an already defined type. The TYPEDEF directive associates <name> with a type, and, once defined, the symbol can be used anywhere a type can be used or as a data declaration directive. The <qualifiedtype> parameter can specify a pointer to a qualified type. The TYPEDEF PROTO syntax defines a prototype type.

Once a type is defined, you can use it to define variables. Use is similar to the other variable definition directives (like BYTE and WORD).

Parameter Description
qualifiedtype Any qualified type. Can include a type previously defined by a TYPEDEF directive, but recursive definitions are not allowed.
prototypelist List of parameters for procedure prototype. Uses the same syntax as the PROTO directive.


TYPEDEF Directive

Description

Use TYPEDEF to

* Define types for procedure arguments in PROC, PROTO, and INVOKE statements.

* Define types used in high-level expressions such as .IF, WHILE, and .REPEAT.

* Define pointer types so that CodeView can give appropriate information about the pointer.

* Define the types for procedure arguments in procedure prototypes.

Typical TYPEDEFS

CHAR TYPEDEF BYTE                ; Rename an existing type
PCHAR TYPEDEF PTR CHAR           ; Create a pointer type
PWORD TYPEDEF PTR WORD           ; Create a pointer type
PPWORD TYPEDEF PTR PWORD         ; Create a complex pointer type
PMYSTRUCT TYPEDEF PTR MYSTRUCT   ; Create pointer type to structure or union
PPROTO TYPEDEF PROTO \
NEAR C arg1:byte arg2:word       ; Define proc prototype
PFUNCT TYPEDEF PTR PPROTO        ; Define pointer to proc
                                 ; prototype
Typical uses of TYPEDEFs:

user CHAR "Jill"                 ; Use new type as initializer
Puser PCHAR user                 ; Initialize a pointer
task PROC myvar:PMYSTRUCT        ; Pass pointer to structure
EXTERNDEF ppw:PPWORD             ; Define external with user type
proctbl PFUNC Up, Down, Home     ; Initialize procedure table
-
-
-
INVOKE proctbl[bx], pos          ; Call procedure from table


UNION

Syntax: name UNION [alignment] [, NONUNIQUE]
  fielddeclarations
[name] ENDS

Description
Declares a union as a new data type. Allows the same memory locations to be overlapped with different types. Identical to STRUCT except that each member has a 0 offset. The size of the union is the size of the largest member of the union.

Unions can be used to store one type of data in some circumstances and another type in a different situation. Unions also allow you to store data as one data type and then read it as another. Unions are initialized by using the union name as a data declaration directive. You only need to initialize a union for one data type.

You must refer to union members by their member names. The LABEL directive allows you to refer to the entire union as a unit.

The first-level definition of a union must include the <name> label preceding the ENDS. In nested unions, terminate the block with a ENDS statement without the <name> label.

The <alignment> field determines the byte alignment of any structures. This field can be 1, 2, or 4. The default is 1, unless overridden by the /Zp command-line option or the ALIGN or EVEN directives.

The NONUNIQUE parameter allows elements of the union to be accessed only by their fully specified names.

Some directives are allowed in the <fielddeclarations> field; see the BNF Appendix in the MASM Programmer's Guide.

Example
EXTENDCHAR UNION
  ascii BYTE ?           ; Define a union of byte and
  kanji WORD ?           ; word
EXTENDCHAR ENDS

 initial EXTENDCHAR <J>   ; Create a union variable
mov al, initial.ascii    ; Move byte-length data
mov bx, initial.kanji    ; Move word-length data


USES

Syntax: USES reglist

Description
An optional keyword used with PROC. Generates code to push the value of registers that should be preserved (and that will be altered by your procedure) on the stack and pop them off when the procedure returns.

The <reglist> parameter is a list of one or more registers. Separate multiple registers with spaces.


VARARG (Proc)

VARARG

VARARG (Proc)

The VARARG attribute allows you to pass a variable number of arguments to a procedure. The VARARG parameter receives a near pointer to an array of WORD elements (DWORD if a far address is passed). You can apply the VARARG attribute only to the last parameter in a procedure definition. You can only use VARARG in procedures when the C, SYSCALL, or STDCALL language types are in effect.

addup PROTO NEAR C, parmcount:WORD, parmvalues:VARARG

    invoke addup, 3, 5, 2, 4

    addup PROC NEAR C, parmcount:WORD, parmvalues:VARARG
    xor ax, ax
    xor bx, bx
    mov cx, parmcount

    .REPEAT
      add ax, parmvalues[bx]
      inc bx
      inc bx
    .UNTILCXZ

    ret

 addup ENDP


WIDTH

Syntax: WIDTH {recordfieldname|record}

Description
Returns width (in bits) allocated for a record or record field.

The <recordfieldname> is the name of any field defined in any record. The <record> is the name of any defined record.


;text

Normal and macro end of line comments

Syntax:

;  comment text
;; macro comment text

Description
The single semicolon treats <text> to the end of the line as a comment. The double semicolon treats <text> to the end of the line as a macro comment. In a listing file, macro comments appear with the macro definition, not with the macro expansion.

Comments must follow all other fields in a statement line.


Alternate Quotes

            "text"
            'text'

Description
Treats <text> as a string. You can use single or double quotation marks, but the quotation marks on both sides of <text> must be identical. A string can be up to 255 characters long and must be on a single physical line. You can use a quotation mark inside a string by repeating it twice in a row ("" or ''). The left-hand single quotation mark (`) is not allowed as a delimiter.

Example
quote1      BYTE     "This was called by 'int 23h'"
quote2      BYTE     'This was called by "int 23h"'
quote3      BYTE     "Use the ""ASSUME"" directive"
quote4      BYTE     'Use the ''ASSUME'' directive'


.BREAK

Syntax: .BREAK [.IF condition]

Description

Terminates the nearest enclosing .WHILE or .REPEAT directive. If
the .IF condition is present, the loop is terminated only if the
value of <condition> is true.


.CODE

Syntax: .CODE [name]

Description

Starts a code segment (with segment name <name>, if given) and ends the previous segment, if any. Aligns the segment on a 2-byte boundary (.8086, .186, .286) or a 4-byte boundary (.386, .486). The .MODEL directive must precede this directive.

Segment name <name> is an optional parameter that overrides the default segment name. If <name> is not specified, the assembler generates a segment called _TEXT (tiny, small, compact, and flat models) or <modulename>_TEXT (medium, large, and huge models).


.CONST

Syntax: .CONST

Description

Starts a constant data segment (called CONST in DGROUP) and ends the previous segment, if any. For consistency with other languages, this segment should contain all strings, real numbers, and other constant data accessed by a high-level language. The CONST segment has the READONLY attribute.

The .MODEL directive must precede this directive.


.CONTINUE

Syntax: .CONTINUE [.IF condition]

Description

Skips to the code that evaluates the loop condition of the nearest enclosing loop. If the .IF condition clause is present, the skip will occur only if the value of <condition> is true.

This directive is valid only within a .REPEAT or .WHILE block.


.CREF

Syntax: .CREF

.NOCREF [name[, name]...]

Description
The .CREF directive enables collection of information for all symbols. These symbols will appear in the symbol table at the end of a listing file. If you generate a source-browser file with the /FR or /Fr command-line option, the browser will be able to access cross-reference information for these symbols. This directive is in effect by default.

The .NOCREF directive turns off cross-referencing for all symbols. Any references to symbols while .NOCREF is in effect are omitted from the cross-reference listing. If the <name> parameter is given with this directive, only the cross-reference information for the symbols specified by <name> is omitted.

.XCREF is a synonym for .NOCREF and is provided for compatibility with previous versions of the assembler.


.DATA

Syntax: .DATA

.DATA?

Description

The .DATA directive starts the initialized data segment (with segment name _DATA) and ends the previous segment, if any. The .DATA segment should contain all global data that have initial values.

The .DATA? directive starts the uninitialized data segment (with segment name _BSS) and ends the previous segment, if any. Place all uninitialized data in the .DATA? segment.

Although uninitialized data can be placed in the .DATA segment by declaring data with the ? operator, use the .DATA? directive to minimize the size of the .EXE file and to maximize compatibility with other languages.

The .MODEL directive must precede these directives. It generates a GROUP statement that places _DATA and _BSS in DGROUP.


Data Initialisation

  Syntax:   ?

Description

Used as an initializer in data declarations; indicates a value that the assembler allocates but does not initialize. Can be used alone or with DUP, as in the following examples:

Extension  WORD     ?           ; Allocate 1 uninitialized word
Initials   BYTE     ?,?,?       ; Allocate 3 uninitialized bytes
Fullname   BYTE     20 DUP (?)  ; Allocate 20 uninitialized bytes

To minimize the size of executable files, use the .DATA? or .FARDATA? directives to define an undefined data segment. Put undefined data in these segments.

The assembler treats the ? initializer as either zero or as an unspecified value. In compatibility mode, however, the assembler always treats the ? initializer as zero unless it is used with the DUP operator. In this case the assembler allocates space, but does not initialize it with any value.


.ERR

Syntax: .ERR [message]

Description
Generates an A2052 error message when assembled. Generally, this directive occurs in a conditional-assembly block and is used to indicate some error condition discovered at assembly time. This directive can be useful for verifying that the program assembled correctly and that user-defined bounds were not exceeded.

If <message> is given, it will be displayed with the standard assembler error messages. The <message> parameter is any text item


.ERRB

Syntax: .ERRB <textitem> [,message]

.ERRNB <textitem> [,message]

Description

The .ERRB directive generates an A2057 error if <textitem> is blank. The .ERRNB directive generates an A2058 error if <textitem> is not blank.

These directives are usually used within macro definitions; a macro parameter is replaced by an empty string if you call the macro and do not give a corresponding argument. These directives let you write macros that generate an assembly-time error if the wrong number of arguments is used in the macro call. However, the :REQ parameter attribute or the variable argument feature often provides the same functionality in a more straightforward way.

Parameter Description

textitem Item to be tested, any text item.

message Programmer-supplied error message, any text item.


.ERRDEF

Syntax: .ERRDEF name [,message]

.ERRNDEF name [,message]

Description
The .ERRDEF directive generates an A2056 error message if <name> is a previously defined symbol. The .ERRNDEF directive generates an A2055 error message if <name> has not been previously defined.

One of the most common uses of the .ERRNDEF directive is to ensure that a symbol has been defined before you attempt to use it. This situation can occur if the source code depends on the command-line /D option or the Macro Assembler Global Options dialog box to define a symbol.

If <message> is given, it will be displayed with the standard assembler error messages. The <message> parameter is any text item.


.ERRDIF

Syntax: .ERRDIF[I] <textitem1>, <textitem2> [,message]

.ERRIDN[I] <textitem1>, <textitem2> [,message]

Description
The .ERRDIF directive generates an A2060 error if <textitem1> and <textitem2> are different. .ERRIDN generates an A2059 error if the arguments are identical. These directives are commonly used inside macros to test for bad values passed as parameters. The .ERRDIFI and .ERRIDNI directives act the same as the .ERRDIF and .ERRIDN directives but perform case-insensitive comparisons.

The <textitem1> and <textitem2> parameters are text items.

If <message> is given, it will be displayed with the standard assembler error messages. The <message> parameter is any text item.


.ERRE

Syntax: .ERRE expression [,message]

.ERRNZ expression [,message]

Description
Tests value of <expression> and generates an error depending on the resulting value. The .ERRE directive generates an A2053 error if <expression> evaluates to false (zero). .ERRNZ generates an A2054 error if <expression> evaluates to true (nonzero). If <message> is given, it will be displayed with the standard assembler error message.

Parameter Description

expression Expression that evaluates to true, false, or a numeric constant. The expression cannot contain forward references.

message Programmer-supplied error message, any text item.


.LIST

Syntax: .LIST

Description
Enables listing of all source statements to the .LST file. The .LST file must first be enabled with a PWB MASM option or the /Fl command-line option. This directive is in effect by default.


.LISTALL

Syntax: .LISTALL

Description
Enables listing of all statements to the .LST file. The .LST file must first be enabled with a PWB MASM option or the /Fl command-line option. This directive is equivalent to the combination of the .LIST, .LISTIF, and .LISTMACROALL directives.


.LISTIF

Syntax: .LISTIF

Description
Enables listing of all statements in conditional blocks, even those in false blocks. This directive is in effect by default. The .LFCOND directive is a synonym of .LISTIF and is included for compatibility with previous versions of the assembler.


.LISTMACRO

Syntax: .LISTMACRO

Description
Enables an assembly listing file that includes macro expansion statements that generate code or data. Comments, equates, and segment definitions are not listed. This directive is in effect by default. The .LFCOND directive is a synonym of .LISTMACRO and is included for compatibility with previous versions of the assembler.


.LISTMACROALL

Syntax: .LISTMACROALL

Description
Enables listing of all source statements in a macro expansion, including normal comments but excluding macro comments. The .LALL directive is a synonym of .LISTMACROALL and is included for compatibility with previous versions of the assembler.


.MODEL

Syntax: .MODEL memorymodel [,langtype] [,ostype] [,stackoption]

Description
Initializes the program memory model. Must be placed at the beginning of the source file before any other simplified segment directive. Generates ASSUME and GROUP statements used by the specified memory model. Also creates the predefined equates for the various simplified segments. The .MODEL directive can occur only once in a program.

If you use the langtype argument with .MODEL, nested procedures are not allowed.

Parameter Description
Mmemory model TINY, SMALL, COMPACT, MEDIUM, LARGE, HUGE, or FLAT. If you are writing an assembler routine for a high-level language, this option should match the memory model used by the compiler or interpreter. FLAT is valid only in .386 or .486 mode. You must use the /AT command-line option or /TINY linker option to assemble tiny-model programs.

langtype Any language type. Instructs the assembler to follow the naming, calling, and return conventions for the indicated language. This affects the PUBLIC, EXTERN, PROC, PROTO, and INVOKE directives.

ostype OS_DOS is the only option currently supported and is the default.

stackoption NEARSTACK (if SS equals DS) or FARSTACK (if SS is not equal to DS). NEARSTACK is the default. The stack is not part of DGROUP with the FARSTACK option. This affects the code generated by the .STARTUP directive.


.MODEL directive

.MODEL directive

Description
If the .MODEL directive is preceded by the .386 or .486 directive (or their privileged counterparts), the assembler uses 32-bit segments. If the .386 or .486 directive follows the .MODEL directive, the default 16-bit segments are used. The flat memory model uses 32-bit segments and must be preceded by a .386 or .486 directive.

32-bit segments are available only on the 80386/486 processors.


.NOLIST

Syntax: .NOLIST

Description
Suppresses program listing. Use in conjunction with .LIST to prevent a particular section of a source file from being listed. The .XLIST directive is a synonym for .NOLIST and is included for compatibility with previous versions of the assembler.


.NOLISTIF

Syntax: .NOLISTIF

Description
Turns off the listing of the lines in subsequent conditional blocks whose condition is false. The .SFCOND directive is a synonym for .NOLISTIF and is included for compatibility with previous versions of the assembler.


.NOLISTMACRO

Syntax: .NOLISTMACRO

Description
Suppresses listing of macro expansions in a listing file. Macro calls are listed, but the source code generated by the call is not. The .SALL directive is a synonym for .NOLISTMACRO and is included for compatibility with previous versions of the assembler.


.RADIX

Syntax: .RADIX expression

Description
Sets the default radix (base) for integer constants to the value of <expression>. The default radix at the start of assembly is 10.

The .RADIX directive does not affect floating-point constants or numbers that have explicit radix overrride tags:

Tag Base
H hexadecimal
O or Q octal
T decimal
Y binary
R floating point

With a radix of 10 or below, you can use the characters B (b) and D (d) as the radix override characters for base 2 and base 10, respectively.

The <expression> must evaluate to a decimal number in the range 2 to 16 and cannot contain forward references.

If the current radix in your code is greater than 10 decimal, MASM 6.1 allows the radix specifiers B (binary) and D (decimal) only in compatibility mode. You must change B to Y for binary, and D to T for decimal, since both B and D are legitimate hexadecimal values, making numbers such as 12D ambiguous. If you want to keep B and D as radix specifiers when the current radix is greater than 10, you must specify OPTION M510.


.TFCOND

Syntax: .TFCOND

Description
Toggles the state of the assembler between .LISTIF and .NOLISTIF, determining whether or not false conditional blocks are included in assembler listings.