home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft_Programmers_Library.7z / MPL / masm / masmpgmr.txt < prev    next >
Encoding:
Text File  |  2013-11-08  |  1.8 MB  |  46,684 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1.  Microsoft  Macro Assembler - Programmer's Guide
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  ────────────────────────────────────────────────────────────────────────────
  11.               Microsoft (R) Macro Assembler - Programmer's Guide
  12.  
  13.                                  Version 6.0
  14.  ────────────────────────────────────────────────────────────────────────────
  15.  
  16.  
  17.                For MS (R) OS/2 and MS-DOS (R) Operating Systems
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  Microsoft Corporation
  27.  
  28.  Information in this document is subject to change without notice and does
  29.  not represent a commitment on the part of Microsoft Corporation. The
  30.  software described in this document is furnished under a license agreement
  31.  or nondisclosure agreement. The software may be used or copied only in
  32.  accordance with the terms of the agreement. It is against the law to copy
  33.  the software on any medium except as specifically allowed in the license or
  34.  nondisclosure agreement. No part of this manual may be reproduced or
  35.  transmitted in any form or by any means, electronic or mechanical, including
  36.  photocopying and recording, for any purpose without the express written
  37.  permission of Microsoft.
  38.  RESTRICTED RIGHTS: Use, duplication, or disclosure by the U.S. Government is
  39.  subject to restrictions as set forth in subparagraph (c)(1)(ii) of the
  40.  Rights in Technical Data and Computer Software clause at DFARS 252.227-7013
  41.  or subparagraphs (c)(1) and (2) of Commercial Computer Software
  42.  ─Restricted Rights at 48 CFR 52.227-19, as applicable.
  43.  Contractor/Manufacturer is Microsoft Corporation, One Microsoft Way,
  44.  Redmond, WA  98052-6399.
  45.  
  46.  
  47.  (C) Copyright Microsoft Corporation, 1991. All rights reserved.
  48.  
  49.  Printed in the United States of America.
  50.  
  51.  
  52.  Microsoft, MS, MS-DOS, CodeView, QuickC,
  53.  and XENIX are registered trademarks and Making it all make sense,
  54.  Microsoft QuickBasic, QuickPascal, and Windows are trademarks of Microsoft
  55.  Corporation.
  56.  
  57.  U.S. Patent No. 4,955,066
  58.  
  59.  Hercules is a registered trademark of Hercules Computer
  60.  Technology.
  61.  
  62.  IBM is a registered trademark of International Business
  63.  Machines Corporation.
  64.  
  65.  Intel is a registered trademark of Intel Corporation.
  66.  
  67.  NEC and V25 are registered trademarks and V35 is a trademark
  68.  of NEC Corporation.
  69.  
  70.  Document No. LN06556-0291
  71.  
  72.  10 9 8 7 6 5 4 3 2 1
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  Introduction
  81.       New and Extended Features in MASM 6.0
  82.              New MASM Language Features
  83.              ML and MASM Command Lines
  84.              Compatibility with Earlier Versions of MASM
  85.       Scope and Organization of this Book
  86.       Books for Further Reading
  87.       Document Conventions
  88.       Getting Assistance and Reporting Problems
  89.  
  90.  Chapter 1  Understanding Global Concepts
  91.  
  92.       1.1   The Processing Environment
  93.              1.1.1    8086-Based Processors
  94.              1.1.2    Operating Systems
  95.              1.1.3    Segmented Architecture
  96.              1.1.4    Segment Protection
  97.              1.1.5    Segmented Addressing
  98.              1.1.6    Segment Arithmetic
  99.       1.2   Language Components of MASM
  100.              1.2.1    Reserved Words
  101.              1.2.2    Identifiers
  102.              1.2.3    Predefined Symbols
  103.              1.2.4    Integer Constants and Constant Expressions
  104.              1.2.5    Operators
  105.              1.2.6    Data Types
  106.              1.2.7    Registers
  107.              1.2.8    Statements
  108.       1.3   The Assembly Process
  109.              1.3.1    Generating and Running Executable Programs
  110.              1.3.2    Using the OPTION Directive
  111.              1.3.3    Conditional Directives
  112.       1.4   Related Topics in Online Help
  113.  
  114.  Chapter 2  Organizing MASM Segments
  115.  
  116.       2.1   Overview of Memory Segments
  117.       2.2   Using Simplified Segment Directives
  118.              2.2.1    Defining Basic Attributes with .MODEL
  119.              2.2.2    Specifying a Processor and Coprocessor
  120.              2.2.3    Creating a Stack
  121.              2.2.4    Creating Data Segments
  122.              2.2.5    Creating Code Segments
  123.              2.2.6    Starting and Ending Code with .STARTUP and .EXIT
  124.       2.3   Using Full Segment Definitions
  125.              2.3.1    Defining Segments with the SEGMENT Directive
  126.              2.3.2    Controlling the Segment Order
  127.              2.3.3    Setting the ASSUME Directive for Segment Registers
  128.              2.3.4    Defining Segment Groups
  129.       2.4   Related Topics in Online Help
  130.  
  131.  Chapter 3  Using Addresses and Pointers
  132.  
  133.       3.1   Programming Segmented Addresses
  134.              3.1.1    Initializing Default Segment Registers
  135.              3.1.2    Near and Far Addresses
  136.       3.2   Specifying Addressing Modes
  137.              3.2.1    Register Operands
  138.              3.2.2    Immediate Operands
  139.              3.2.3    Direct Memory Operands
  140.              3.2.4    Indirect Memory Operands
  141.       3.3   Accessing Data with Pointers and Addresses
  142.              3.3.1    Defining Pointer Types with TYPEDEF
  143.              3.3.2    Defining Register Types with ASSUME
  144.              3.3.3    Basic Pointer and Address Operations
  145.       3.4   Related Topics in Online Help
  146.  
  147.  Chapter 4  Defining and Using Integers
  148.  
  149.       4.1   Declaring Integer Variables
  150.              4.1.1    Allocating Memory for Integer Variables
  151.              4.1.2    Data Initialization
  152.       4.2   Integer Operations
  153.              4.2.1    Moving and Loading Integers
  154.              4.2.2    Pushing and Popping Stack Integers
  155.              4.2.3    Adding and Subtracting Integers
  156.              4.2.4    Multiplying and Dividing Integers
  157.       4.3   Manipulating Integers at the Bit Level
  158.              4.3.1    Logical Operations
  159.              4.3.2    Shifting and Rotating Bits
  160.              4.3.3    Multiplying and Dividing with Shift Instructions
  161.       4.4   Related Topics in Online Help
  162.  
  163.  Chapter 5  Defining and Using Complex Data Types
  164.  
  165.       5.1   Arrays and Strings
  166.              5.1.1    Declaring and Referencing Arrays
  167.              5.1.2    Declaring and Initializing Strings
  168.              5.1.3    Processing Arrays and Strings
  169.       5.2   Structures and Unions
  170.              5.2.1    Declaring Structure and Union Types
  171.              5.2.2    Defining Structure and Union Variables
  172.              5.2.3    Referencing Structures, Unions, and Fields
  173.              5.2.4    Nested Structures and Unions
  174.       5.3   Records
  175.              5.3.1    Declaring Record Types
  176.              5.3.2    Defining Record Variables
  177.              5.3.3    Record Operators
  178.       5.4   Related Topics in Online Help
  179.  
  180.  Chapter 6  Using Floating-Point and Binary Coded Decimal Numbers
  181.  
  182.       6.1   Using Floating-Point Numbers
  183.              6.1.1    Declaring Floating-Point Variables and Constants
  184.              6.1.2    Storing Numbers in Floating-Point Format
  185.       6.2   Using a Math Coprocessor
  186.              6.2.1    Coprocessor Architecture
  187.              6.2.2    Instruction and Operand Formats
  188.              6.2.3    Coordinating Memory Access
  189.              6.2.4    Using Coprocessor Instructions
  190.       6.3   Using Emulator Libraries
  191.       6.4   Using Binary Coded Decimal Numbers
  192.              6.4.1    Defining BCD Constants and Variables
  193.              6.4.2    Calculating with BCDs
  194.       6.5   Related Topics in Online Help
  195.  
  196.  Chapter 7  Controlling Program Flow
  197.  
  198.       7.1   Jumps
  199.              7.1.1    Unconditional Jumps
  200.              7.1.2    Conditional Jumps
  201.       7.2   Loops
  202.              7.2.1    Loop-Generating Directives
  203.              7.2.2    Writing Loop Conditions
  204.       7.3   Procedures
  205.              7.3.1    Defining Procedures
  206.              7.3.2    Passing Arguments on the Stack
  207.              7.3.3    Declaring Parameters with the PROC Directive
  208.              7.3.4    Using Local Variables
  209.              7.3.5    Creating Local Variables Automatically
  210.              7.3.6    Declaring Procedure Prototypes
  211.              7.3.7    Calling Procedures with INVOKE
  212.              7.3.8    Generating Prologue and Epilogue Code
  213.       7.4   DOS Interrupts
  214.              7.4.1    Calling DOS and ROM-BIOS Interrupts
  215.              7.4.2    Replacing or Redefining Interrupt Routines
  216.       7.5   Related Topics in Online Help
  217.  
  218.  Chapter 8  Sharing Data and Procedures among Modules and Libraries
  219.  
  220.       8.1   Selecting Data-Sharing Methods
  221.       8.2   Sharing Symbols with Include Files
  222.              8.2.1    Organizing Modules
  223.              8.2.2    Declaring Symbols Public and External
  224.              8.2.3    Positioning External Declarations
  225.       8.3   Using Alternatives to Include Files
  226.              8.3.1    PUBLIC and EXTERN
  227.              8.3.2    Other Alternatives
  228.       8.4   Developing Libraries
  229.              8.4.1    Associating Libraries with Modules
  230.              8.4.2    Using EXTERN with Library Routines
  231.       8.5   Related Topics in Online Help
  232.  
  233.  Chapter 9  Using Macros
  234.  
  235.       9.1   Text Macros
  236.       9.2   Macro Procedures
  237.              9.2.1    Creating Macro Procedures
  238.              9.2.2    Passing Arguments to Macros
  239.              9.2.3    Specifying Required and Default Parameters
  240.              9.2.4    Defining Local Symbols in Macros
  241.       9.3   Assembly Time Variables and Macro Operators
  242.              9.3.1    Text Delimiters (< >) and the Literal-Character
  243.                          Operator (!)
  244.              9.3.2    Expansion Operator (%)
  245.              9.3.3    Substitution Operator (&)
  246.       9.4   Defining Repeat Blocks with Loop Directives
  247.              9.4.1    REPEAT Loops
  248.              9.4.2    WHILE Loops
  249.              9.4.3    FOR Loops and Variable-Length Parameters
  250.              9.4.4    FORC Loops
  251.       9.5   String Directives and Predefined Functions
  252.       9.6   Returning Values with Macro Functions
  253.       9.7   Advanced Macro Techniques
  254.              9.7.1    Nesting Macro Definitions
  255.              9.7.2    Testing for Argument Type and Environment
  256.              9.7.3    Using Recursive Macros
  257.       9.8   Related Topics in Online Help
  258.  
  259.  Chapter 10  Managing Projects with NMAKE
  260.  
  261.       10.1  Overview of NMAKE
  262.       10.2  Running NMAKE
  263.       10.3  NMAKE Description Files
  264.              10.3.1    Description Blocks
  265.              10.3.2    Pseudotargets
  266.              10.3.3    Comments
  267.              10.3.4    Macros
  268.              10.3.5    Inference Rules
  269.              10.3.6    Directives
  270.              10.3.7    Preprocessing Directives
  271.              10.3.8    Extracting Filename Components
  272.       10.4  Command-Line Options
  273.       10.5  NMAKE Command File
  274.       10.6  The TOOLS.INI File
  275.       10.7  Inline Files
  276.       10.8  Sequence of NMAKE Operations
  277.       10.9  A Sample NMAKE Description File
  278.       10.10 Differences between NMAKE and MAKE
  279.       10.11 Using NMK
  280.       10.12 Using Exit Codes with NMAKE
  281.       10.13 Related Topics in Online Help
  282.  
  283.  Chapter 11  Creating Help Files with HELPMAKE
  284.  
  285.       11.1  Structure and Contents of a Help Database
  286.              11.1.1    Contents of a Help File
  287.              11.1.2    Help File Formats
  288.       11.2  Invoking HELPMAKE
  289.       11.3  HELPMAKE Options
  290.              11.3.1    Options for Encoding
  291.              11.3.2    Options for Decoding
  292.              11.3.3    Options for Help
  293.       11.4  Creating a Help Database
  294.       11.5  Help Text Conventions
  295.              11.5.1    Structure of the Help Text File
  296.              11.5.2    Local Contexts
  297.              11.5.3    Context Prefixes
  298.              11.5.4    Hyperlinks
  299.       11.6  Using Help Database Formats
  300.              11.6.1    QuickHelp Format
  301.              11.6.2    Rich Text Format
  302.              11.6.3    Minimally Formatted ASCII Format
  303.       11.7  Related Topics in Online Help
  304.  
  305.  Chapter 12  Linking Object Files with LINK
  306.  
  307.       12.1  Overview
  308.       12.2  LINK Output Files
  309.       12.3  LINK Syntax and Input
  310.              12.3.1    The objfiles Field
  311.              12.3.2    The exefile Field
  312.              12.3.3    The mapfile Field
  313.              12.3.4    The libraries Field
  314.              12.3.5    The deffile Field
  315.              12.3.6    Examples
  316.       12.4  Running LINK
  317.              12.4.1    Specifying Input with LINK Prompts
  318.              12.4.2    Specifying Input in a Response File
  319.       12.5  LINK Options
  320.              12.5.1    Specifying Options
  321.              12.5.2    The /ALIGN Option
  322.              12.5.3    The /BATCH Option
  323.              12.5.4    The /CO Option
  324.              12.5.5    The /CPARM Option
  325.              12.5.6    The /DOSSEG Option
  326.              12.5.7    The /DSALLOC Option
  327.              12.5.8    The /EXEPACK Option
  328.              12.5.9    The /FARCALL Option
  329.              12.5.10   The /HELP Option
  330.              12.5.11   The /HIGH Option
  331.              12.5.12   The /INCR Option
  332.              12.5.13   The /INFO Option
  333.              12.5.14   The /LINE Option
  334.              12.5.15   The /MAP Option
  335.              12.5.16   The /NOD Option
  336.              12.5.17   The /NOE Option
  337.              12.5.18   The /NOFARCALL Option
  338.              12.5.19   The /NOGROUP Option
  339.              12.5.20   The /NOI Option
  340.              12.5.21   The /NOLOGO Option
  341.              12.5.22   The /NONULLS Option
  342.              12.5.23   The /NOPACKC Option
  343.              12.5.24   The /OV Option
  344.              12.5.25   The /PACKC Option
  345.              12.5.26   The /PACKD Option
  346.              12.5.27   The /PADC Option
  347.              12.5.28   The /PADD Option
  348.              12.5.29   The /PAUSE Option
  349.              12.5.30   The /PM Option
  350.              12.5.31   The /Q Option
  351.              12.5.32   The /SEG Option
  352.              12.5.33   The /STACK Option
  353.              12.5.34   The /TINY Option
  354.              12.5.35   The /W Option
  355.              12.5.36   The /? Option
  356.       12.6  Setting Options with the LINK Environment Variable
  357.              12.6.1    Setting the LINK Environment Variable
  358.              12.6.2    Behavior of the LINK Environment Variable
  359.              12.6.3    Clearing the LINK Environment Variable
  360.       12.7  Using Overlays under DOS
  361.              12.7.1    Restrictions on Overlays
  362.              12.7.2    Specifying Overlays
  363.              12.7.3    How Overlays Work
  364.              12.7.4    Overlay Interrupts
  365.       12.8  Linker Operation under DOS
  366.              12.8.1    Segment Alignment
  367.              12.8.2    Frame Number
  368.              12.8.3    Segment Order
  369.              12.8.4    Combined Segments
  370.              12.8.5    Groups
  371.              12.8.6    Fixups
  372.       12.9  LINK Temporary Files
  373.       12.10 LINK Exit Codes
  374.       12.11 Related Topics in Online Help
  375.  
  376.  Chapter 13  Module-Definition Files
  377.  
  378.       13.1  Overview
  379.       13.2  Module Statements
  380.              13.2.1    Syntax Rules
  381.              13.2.2    Reserved Words
  382.       13.3  The NAME Statement
  383.       13.4  The LIBRARY Statement
  384.       13.5  The DESCRIPTION Statement
  385.       13.6  The STUB Statement
  386.       13.7  The EXETYPE Statement
  387.       13.8  The PROTMODE Statement
  388.       13.9  The REALMODE Statement
  389.       13.10 The STACKSIZE Statement
  390.       13.11 The HEAPSIZE Statement
  391.       13.12 The CODE Statement
  392.       13.13 The DATA Statement
  393.       13.14 The SEGMENTS Statement
  394.       13.15 CODE, DATA, and SEGMENTS Attributes
  395.       13.16 The OLD Statement
  396.       13.17 The EXPORTS Statement
  397.       13.18 The IMPORTS Statement
  398.       13.19 Related Topics in Online Help
  399.  
  400.  Chapter 14  Customizing the Microsoft Programmer's WorkBench
  401.  
  402.       14.1  Setting Switches
  403.              14.1.1    Changing Current Assignments and Switch Settings
  404.              14.1.2    Editing the TOOLS.INI Initialization File
  405.       14.2  Assigning Functions to Keystrokes
  406.       14.3  Writing Macros
  407.              14.3.1    Macro Syntax
  408.              14.3.2    Macro Responses
  409.              14.3.3    Macro Arguments
  410.              14.3.4    Macro Conditionals
  411.              14.3.5    Recording Macros
  412.              14.3.6    Temporary Macros
  413.       14.4  Related Topics in Online Help
  414.  
  415.  Chapter 15  Debugging Assembly-Language Programs with CodeView
  416.  
  417.       15.1  Understanding Windows in CodeView
  418.       15.2  Overview of Debugging Techniques
  419.       15.3  Viewing and Modifying Program Data
  420.              15.3.1    Displaying Variables in the Watch Window
  421.              15.3.2    Displaying Expressions in the Watch Window
  422.              15.3.3    Displaying Local Variables
  423.              15.3.4    Using Pointers to Display Arrays and Strings
  424.              15.3.5    Displaying Structures
  425.              15.3.6    Using Quick Watch
  426.              15.3.7    Displaying Memory
  427.              15.3.8    Displaying the Processor Registers
  428.              15.3.9    Modifying the Values of Variables, Memory,
  429.                           and Registers
  430.       15.4  Controlling Execution
  431.              15.4.1    Continuous Execution
  432.              15.4.2    Single-Stepping
  433.              15.4.3    Changing the Program Display Mode
  434.       15.5  Replaying a Debug Session
  435.       15.6  Advanced CodeView Techniques
  436.       15.7  CodeView Command-Line Options
  437.       15.8  Customizing CodeView with the TOOLS.INI File
  438.       15.9  Related Topics in Online Help
  439.  
  440.  Chapter 16  Converting C Header Files to MASM Include Files
  441.  
  442.       16.1  Basic H2INC Operation
  443.       16.2  H2INC Syntax and Options
  444.       16.3  Converting Data and Data Structures
  445.              16.3.1    User-Defined and Predefined Constants
  446.              16.3.2    Variables
  447.              16.3.3    Pointers
  448.              16.3.4    Structures and Unions
  449.              16.3.5    Bit Fields
  450.              16.3.6    Enumerations
  451.              16.3.7    Type Definitions
  452.       16.4  Converting Function Prototypes
  453.       16.5  Related Topics in Online Help
  454.  
  455.  Chapter 17  Writing OS/2 Applications
  456.  
  457.       17.1  OS/2 Overview
  458.       17.2  Differences between DOS and OS/2
  459.       17.3  A Sample Program
  460.       17.4  Building an OS/2 Application
  461.       17.5  Binding OS/2 MASM Programs
  462.       17.6  Register and Memory Initialization
  463.       17.7  Other OS/2 Utilities
  464.       17.8  Module-Definition Files
  465.       17.9  Related Topics in Online Help
  466.  
  467.  Chapter 18  Creating Dynamic-Link Libraries
  468.  
  469.       18.1  DLL Overview
  470.       18.2  DLL Programming Requirements
  471.              18.2.1    Separate Stack and Data Requirement
  472.              18.2.2    Floating-Point Math Requirement
  473.              18.2.3    Re-entrance Requirement
  474.              18.2.4    Segment Strategy in a DLL
  475.       18.3  Writing the DLL Code
  476.              18.3.1    Choosing Module Attributes
  477.              18.3.2    Defining Procedures and Data
  478.              18.3.3    Creating Initialization and Termination Code
  479.       18.4  Building the DLL
  480.              18.4.1    Writing the Module-Definition File
  481.              18.4.2    Generating an Import Library with IMPLIB
  482.              18.4.3    Creating and Using the DLL
  483.       18.5  Related Topics in Online Help
  484.  
  485.  Chapter 19  Writing Memory-Resident Software
  486.  
  487.       19.1  Terminate-and-Stay-Resident Programs
  488.              19.1.1    Structure of a TSR
  489.              19.1.2    Passive TSRs
  490.              19.1.3    Active TSRs
  491.       19.2  Interrupt Handlers in Active TSRs
  492.              19.2.1    Auditing Hardware Events for TSR Requests
  493.              19.2.2    Monitoring System Status
  494.              19.2.3    Determining Whether to Invoke the TSR
  495.       19.3  Example of a Simple TSR: ALARM
  496.       19.4  Using DOS in Active TSRs
  497.              19.4.1    Understanding DOS Stacks
  498.              19.4.2    Determining DOS Activity
  499.              19.4.3    Interrupting DOS Functions
  500.              19.4.4    Monitoring the Critical Error Flag
  501.       19.5  Preventing Interference
  502.              19.5.1    Trapping Errors
  503.              19.5.2    Preserving an Existing Condition
  504.              19.5.3    Preserving Existing Data
  505.       19.6  Communicating through the Multiplex Interrupt
  506.              19.6.1    The Multiplex Handler
  507.              19.6.2    Using the Multiplex Interrupt Under DOS Version 2.x
  508.       19.7  Deinstalling TSRs
  509.       19.8  Example of an Advanced TSR: SNAP
  510.              19.8.1    Building SNAP.EXE
  511.              19.8.2    Outline of SNAP
  512.       19.9  Related Topics in Online Help
  513.  
  514.  Chapter 20  Mixed-Language Programming
  515.  
  516.       20.1  Naming and Calling Conventions
  517.              20.1.1    Naming Conventions
  518.              20.1.2    The C Calling Convention
  519.              20.1.3    The Pascal Calling Convention
  520.              20.1.4    The Standard Calling Convention
  521.       20.2  Writing the Assembly-Language Procedure
  522.       20.3  The MASM/High-Level-Language Interface
  523.              20.3.1    The C/MASM Interface
  524.              20.3.2    The FORTRAN/MASM Interface
  525.              20.3.3    The Basic/MASM Interface
  526.              20.3.4    The Pascal/MASM Interface
  527.              20.3.5    The QuickPascal/MASM Interface
  528.       20.4  Related Topics in Online Help
  529.  
  530.  Appendix A  Differences between MASM 6.0 and 5.1
  531.  
  532.       A.1   New Features of Version 6.0
  533.              A.1.1    The Assembler, Environment, and Utilities
  534.              A.1.2    Segment Management
  535.              A.1.3    Data Types
  536.              A.1.4    Procedures, Loops, and Jumps
  537.              A.1.5    Simplifying Multiple-Module Projects
  538.              A.1.6    Expanded State Control
  539.              A.1.7    New Processor Instructions
  540.              A.1.8    Renamed Directives
  541.              A.1.9    Macro Enhancements
  542.              A.1.10   MASM 6.0 Programming Practices
  543.       A.2   Compatibility between MASM 5.1 and 6.0
  544.              A.2.1    Rewriting Code for Compatibility
  545.              A.2.2    Using the OPTION Directive
  546.              A.2.3    Changes to Instruction Encodings
  547.  
  548.  Appendix B  BNF Grammar
  549.  
  550.  
  551.  Appendix C  Generating and Reading Assembly Listings
  552.  
  553.       C.1   Generating Listing Files
  554.              C.1.1    Generating a First Pass Listing
  555.              C.1.2    Controlling the Contents of the Listing File
  556.              C.1.3    Controlling Listing Information on Macros
  557.              C.1.4    Controlling the Page Format
  558.              C.1.5    Precedence of Command-Line Options and Listing
  559.                Directives
  560.       C.2   Reading the Listing File
  561.              C.2.1    Code Generated
  562.              C.2.2    Error Messages
  563.              C.2.3    Symbols and Abbreviations
  564.              C.2.4    Reading Tables in a Listing File
  565.  
  566.  Appendix D  MASM Reserved Words
  567.  
  568.       D.1   Operands and Symbols
  569.              D.1.1    Special Operands for the 80386/486
  570.              D.1.2    Predefined Symbols
  571.       D.2   Registers
  572.       D.3   Operators and Directives
  573.       D.4   Processor Instructions
  574.              D.4.1    8086/8088 Processor Instructions
  575.              D.4.2    80186 Processor Instructions
  576.              D.4.3    80286 Processor Instructions
  577.              D.4.4    80286 and 80386 Privileged-Mode Instructions
  578.              D.4.5    80386 Processor Instructions
  579.              D.4.6    80486 Processor Instructions
  580.              D.4.7    Instruction Prefixes
  581.       D.5   Coprocessor Instructions
  582.              D.5.1    8087 Coprocessor Instructions
  583.              D.5.2    80287 Privileged-Mode Instruction
  584.              D.5.3    80387 Instructions
  585.  
  586.  Appendix E  Default Segment Names
  587.  
  588.  
  589.  Appendix F  Error Messages
  590.  
  591.       F.1   BIND Error Messages
  592.       F.2   CodeView Error Messages
  593.       F.3   EXEHDR Error Messages
  594.       F.4   HELPMAKE Error Messages
  595.              F.4.1    HELPMAKE Fatal Errors
  596.              F.4.2    HELPMAKE Errors
  597.              F.4.3    HELPMAKE Warnings
  598.       F.5   H2INC Error Messages
  599.              F.5.1    H2INC Fatal Errors
  600.              F.5.2    H2INC Compilation Errors
  601.              F.5.3    H2INC Warnings
  602.       F.6   IMPLIB Error Messages
  603.              F.6.1    IMPLIB Fatal Errors
  604.              F.6.2    IMPLIB Errors
  605.       F.7   LIB Error Messages
  606.              F.7.1    LIB Fatal Errors
  607.              F.7.2    LIB Errors
  608.              F.7.3    LIB Warnings
  609.       F.8   LINK Error Messages
  610.              F.8.1    LINK Fatal Errors
  611.              F.8.2    LINK Errors
  612.              F.8.3    LINK Warnings
  613.       F.9   ML Error Messages
  614.              F.9.1    ML Fatal Errors
  615.              F.9.2    ML Errors
  616.              F.9.3    ML Warnings
  617.       F.10  NMAKE Error Messages
  618.              F.10.1   NMAKE Fatal Errors
  619.              F.10.2   NMAKE Errors
  620.              F.10.3   NMAKE Warnings
  621.       F.11  PWB.COM Error Messages
  622.       F.12  PWBRMAKE Error Messages
  623.              F.12.1   PWBRMAKE Fatal Errors
  624.              F.12.2   PWBRMAKE Warnings
  625.  
  626.  Glossary
  627.  
  628.  
  629.  Index
  630.  
  631.  
  632.  
  633.  
  634.  Introduction
  635.  ────────────────────────────────────────────────────────────────────────────
  636.  
  637.  The Microsoft (R) Macro Assembler Programmer's Guide provides the
  638.  information you need to write and debug assembly-language programs with the
  639.  Microsoft Macro Assembler (MASM), version 6.0. This book documents enhanced
  640.  features of the language and the programming environment for MASM 6.0. It
  641.  also describes new features that take advantage of the capabilities of the
  642.  80386/486 processors.
  643.  
  644.  The Programmer's Guide is written for experienced programmers who know
  645.  assembly language and are familiar with an assembler. The book does not
  646.  teach the basics of assembly language; it does explain Microsoft-specific
  647.  features. If you want to learn or review the basics of assembly language,
  648.  refer to "Books for Further Reading" later in this introduction.
  649.  
  650.  The documentation for MASM 6.0 is an integrated set, comprehensive and
  651.  cohesive. This book emphasizes writing efficient code with the new and
  652.  advanced features of MASM. Installing and Using the Professional Development
  653.  System explains not only how to set up MASM 6.0 but also how to use the
  654.  extensive online reference system, the Microsoft Advisor.
  655.  
  656.  Installing and Using also introduces the integrated environment called the
  657.  Programmer's WorkBench (PWB) and shows how to manage development projects
  658.  with it. The Microsoft Macro Assembler Reference provides a full listing of
  659.  all MASM instructions, directives, statements, and operators, and it serves
  660.  as a quick reference to utility commands.
  661.  
  662.  For more information on these same topics, see the online Microsoft Advisor,
  663.  which is a complete reference to Macro Assembler language topics, to the
  664.  utilities, and to PWB. You should be able to find most of the information
  665.  you need in the Microsoft Advisor. The printed documents give more in-depth
  666.  and background information.
  667.  
  668.  
  669.  New and Extended Features in MASM 6.0
  670.  
  671.  Version 6.0 of MASM differs from version 5.1 in many ways, from optional
  672.  extensions to features that replace or modify previous assembler behavior.
  673.  
  674.  MASM 6.0 includes the Programmer's WorkBench, an integrated software
  675.  development environment, and the CodeView (R) source-level debugger. From
  676.  within PWB you can edit, build, debug, or run a program, and you can perform
  677.  most of these operations with either menu selections or keyboard commands.
  678.  You can also customize PWB to suit your individual programming and editing
  679.  requirements and preferences.
  680.  
  681.  
  682.  New MASM Language Features
  683.  
  684.  MASM 6.0 includes a number of new features, described in the list below,
  685.  designed to make programming more efficient and intuitive and to increase
  686.  your productivity. For example, MASM's new high-level-language features mean
  687.  that you can get the speed of assembly language with the ease of high-level
  688.  languages. You can also maintain your programs more easily.
  689.  
  690.  
  691.    ■   MASM 6.0 has many enhancements related to types. You can now use the
  692.        same type specifiers in initializations as in other contexts (BYTE
  693.        instead of DB). You can also define your own types, including pointer
  694.        types, with the new TYPEDEF directive. See Chapter 3, "Using Addresses
  695.        and Pointers," and Chapter 4, "Defining and Using Integers."
  696.  
  697.    ■   The syntax for defining and using structures and records has been
  698.        enhanced. You can also define unions with the new UNION directive. See
  699.        Chapter 5, "Defining and Using Complex Data Types."
  700.  
  701.    ■   MASM now generates complete CodeView information for all types. See
  702.        Chapter 3, "Using Addresses and Pointers," and Chapter 4, "Defining
  703.        and Using Integers."
  704.  
  705.    ■   New control-flow directives let you use high-level-language constructs
  706.        such as loops and if-then-else blocks defined with .REPEAT and .UNTIL
  707.        (or .UNTILCXZ); .WHILE and .ENDW; and .IF, .ELSE, and .ELSEIF. The
  708.        assembler generates the appropriate code to implement the control
  709.        structure. See Chapter 7, "Controlling Program Flow."
  710.  
  711.    ■   MASM now has more powerful features for defining and calling
  712.        procedures. The extended PROC syntax for generating stack frames has
  713.        been enhanced in version 6.0. You can also use the PROTO directive to
  714.        prototype a procedure, which you can then call with the INVOKE
  715.        directive. INVOKE automatically generates code to pass arguments
  716.        (converting them to a related type, if appropriate) and make the call
  717.        according to the specified calling convention. See Chapter 7,
  718.        "Controlling Program Flow."
  719.  
  720.    ■   MASM optimizes jumps by automatically determining the most efficient
  721.        coding for a jump and then generating the appropriate code. See
  722.        Chapter 7, "Controlling Program Flow."
  723.  
  724.    ■   Maintaining multiple-module programs is easier in MASM 6.0. The
  725.        EXTERNDEF and PROTO directives make it easy to maintain all global
  726.        definitions in include files shared by all the source modules of a
  727.        project. See Chapter 8, "Sharing Data and Procedures among Modules and
  728.        Libraries."
  729.  
  730.  
  731.  The assembler has many new macro features that make complex macros clearer
  732.  and easier to write:
  733.  
  734.  
  735.    ■   You can specify default values for macro arguments or mark arguments
  736.        as required. And with the VARARG keyword, one parameter can accept a
  737.        variable number of arguments.
  738.  
  739.    ■   You can implement loops inside of macros in various ways. For example,
  740.        the new WHILE directive expands the statements in a macro body while
  741.        an expression is not zero.
  742.  
  743.    ■   You can define macro functions, which return text macros. Several
  744.        predefined text macros are also provided for processing strings. Macro
  745.        operators and other features related to processing text macros and
  746.        macro arguments have been enhanced. For more information on all these
  747.        macro features, see Chapter 9, "Using Macros."
  748.  
  749.  
  750.  Finally, MASM 6.0 has improved customizable capabilities:
  751.  
  752.  
  753.    ■   With the new .STARTUP and .EXIT directives you can automatically
  754.        generate appropriate start-up and exit code for DOS or OS/2 modules.
  755.        See Chapter 2, "Organizing MASM Segments."
  756.  
  757.    ■   MASM 6.0 supports flat memory model, available with OS/2 version 2.0.
  758.        In flat model, segments can be as large as 4 gigabytes instead of 64K
  759.        (kilobytes). Offsets are 32 bits instead of 16 bits. See Chapter 2,
  760.        "Organizing MASM Segments."
  761.  
  762.    ■   The program H2INC.EXE converts C include files to MASM include files
  763.        and translates data structures and declarations. See Chapter 16,
  764.        "Converting C Header Files to MASM Include Files."
  765.  
  766.  
  767.  MASM 6.0 includes many other minor new features as well as extended support
  768.  for features of earlier versions of MASM. These features are listed in
  769.  Appendix A, "Differences between MASM 6.0 and 5.1," with cross-references to
  770.  the chapters where they are discussed in detail.
  771.  
  772.  
  773.  ML and MASM Command Lines
  774.  
  775.  MASM 6.0 provides a new command-line driver, ML, which is more powerful and
  776.  flexible than the previous driver (MASM). ML assembles and links with one
  777.  command. The old MASM driver command syntax is still supported, however, to
  778.  support existing batch files and makefiles that use MASM command lines.
  779.  
  780.  ────────────────────────────────────────────────────────────────────────────
  781.  NOTE
  782.  
  783.  The name MASM has traditionally been used to refer to the Microsoft Macro
  784.  Assembler. It is used in that context throughout this book. But MASM also
  785.  refers to MASM.EXE, which has been replaced by ML.EXE. In MASM 6.0, the
  786.  MASM.EXE file is a small utility that translates command-line options to
  787.  those accepted by ML.EXE, and then calls ML.EXE. The distinction between
  788.  ML.EXE and MASM.EXE is made whenever necessary. Otherwise, MASM refers to
  789.  the assembler and its features.
  790.  ────────────────────────────────────────────────────────────────────────────
  791.  
  792.  
  793.  Compatibility with Earlier Versions of MASM
  794.  
  795.  In many cases, MASM 5.1 code will assemble without modification under MASM
  796.  6.0. However, MASM 6.0 provides a new OPTION directive that lets you
  797.  selectively modify the assembly process. In particular, you can use the M510
  798.  argument with OPTION or the /Zm command-line option to set most features to
  799.  be compatible with version 5.1 code.
  800.  
  801.  See Appendix A, "Differences between MASM 6.0 and 5.1," for information
  802.  about obsolete features that will not assemble correctly under MASM 6.0. The
  803.  appendix also discusses how to update code to use the new features.
  804.  
  805.  
  806.  Scope and Organization of this Book
  807.  
  808.  The Programmer's Guide describes how to get the most out of the Microsoft
  809.  Macro Assembler 6.0 and the Programmer's WorkBench. The book is arranged by
  810.  topic, with each topic answering a question or solving a problem. The last
  811.  section in each chapter lists topics in the online reference system that
  812.  provide additional information.
  813.  
  814.  The Programmer's Guide is divided into three parts:
  815.  
  816.  Part 1, "Programming in Assembly Language," explains how to program
  817.  efficiently using both the new and old features of MASM. It reviews the
  818.  basic components of assembly language and also describes the new and
  819.  enhanced features.
  820.  
  821.  Part 2, "Improving Programmer Productivity," introduces the utility programs
  822.  included with MASM 6.0. These programs can help you program more quickly and
  823.  efficiently. For example, the chapters in Part 2 show you how to
  824.  automatically update your project (Chapter 10), use program lists as input
  825.  (Chapter 11), use the Microsoft linker (LINK) (Chapter 12), write
  826.  module-definition files (Chapter 13), customize PWB to suit your programming
  827.  style (Chapter 14), use the CodeView debugger to record and play back a
  828.  debugging session (Chapter 15), and easily port data structures from C
  829.  programs to MASM programs (Chapter 16).
  830.  
  831.  Part 3, "Advanced Topics," covers specialized areas. It describes how to
  832.  write programs to run under OS/2 (Chapter 17) and how to build dynamic-link
  833.  libraries (Chapter 18). Chapter 19 shows how to write a
  834.  terminate-and-stay-resident (TSR) program. Chapter 20, on mixed-language
  835.  programming, defines the calling conventions and equivalent data types that
  836.  allow MASM to call and be called by C, FORTRAN, Basic, and Pascal.
  837.  
  838.  In addition, six appendixes and a glossary detail the features of MASM 6.0.
  839.  Of particular interest are Appendix A, "Differences between MASM 6.0 and
  840.  5.1," and Appendix B, "BNF Grammar." Appendix A lists the new features of
  841.  MASM 6.0 and also explains how to update MASM 5.1 code. The BNF grammar, or
  842.  Backus-Naur Form for grammar notation, lets you determine the exact syntax
  843.  for any MASM language component. It clearly defines recursive definitions
  844.  and shows all the available options for any placeholder. Other appendixes
  845.  cover assembly listings, reserved words, default segment names, and error
  846.  messages.
  847.  
  848.  
  849.  Books for Further Reading
  850.  
  851.  The following books may help you learn to program in assembly language or
  852.  write specialized programs. These books are listed only for your
  853.  convenience. Microsoft makes no specific recommendations concerning any of
  854.  these books.
  855.  
  856.  
  857.  Books about Programming in Assembly Language
  858.  
  859.  Abrash, Michael, Zen of Assembly Language.
  860.      Glenview, IL: Scott, Foresman and Co., 1990.
  861.  
  862.  Duntemann, Jeff, Assembly Language from Square One: For the PC AT and
  863.  Compatibles.
  864.      Glenview, IL: Scott, Foresman and Co., 1990.
  865.  
  866.  Fernandez, Judi N., and Ashley, Ruth, Assembly Language Programming for the
  867.  80386.
  868.      New York: McGraw-Hill, 1990.
  869.  
  870.  Miller, Alan R., DOS Assembly Language Programming.
  871.      San Francisco: SYBEX, 1988.
  872.  
  873.  Scanlon, Leo J., 80286 Assembly Language Programming on MS-DOS Computers.
  874.      New York: Brady Communications, 1986.
  875.  
  876.  Turley, James L., Advanced 80386 Programming Techniques.
  877.      Berkeley, CA: Osborne McGraw-Hill, 1988.
  878.  
  879.  
  880.  Books about DOS and BIOS
  881.  
  882.  "Article 11." MS-DOS Encyclopedia.
  883.      Redmond, WA: Microsoft Press, 1988. Contains information about
  884.  terminate-and-stay-resident programs.
  885.  
  886.  Duncan, Ray, Advanced MS-DOS.
  887.      2nd ed. Redmond, WA: Microsoft Press, 1988.
  888.  
  889.  Jourdain, Robert, Programmer's Problem Solver for the IBM PC, XT and AT.
  890.      New York: Brady Communications, 1986.
  891.  
  892.  Microsoft MS-DOS Programmer's Reference.
  893.      Redmond, WA: Microsoft Press, 1986-87.
  894.  
  895.  Norton, Peter and Wilton, Richard, The New Peter Norton Programmer's Guide
  896.  to the IBM PC and PS/2.
  897.      Redmond, WA: Microsoft Press, 1988.
  898.  
  899.  Wilton, Richard, Programmer's Guide to PC & PS/2 Video Systems.
  900.      Redmond, WA: Microsoft Press, 1987.
  901.  
  902.  
  903.  Books about OS/2
  904.  
  905.  Duncan, Ray, Advanced OS/2 Programming.
  906.      Redmond, WA: Microsoft Press, 1989.
  907.  
  908.  ───, Essential OS/2 Functions.
  909.      Redmond, WA: Microsoft Press, 1989.
  910.  
  911.  Letwin, Gordon, Inside OS/2.
  912.      Redmond, WA: Microsoft Press, 1989.
  913.  
  914.  OS/2 Programmer's Reference.
  915.      4 vols. Redmond, WA: Microsoft Press, 1989.
  916.  
  917.  
  918.  Books about Other Topics
  919.  
  920.  Nelson, Ross P., The 80386 Book.
  921.      Redmond, WA: Microsoft Press, 1988.
  922.  
  923.  Startz, Richard, 8087/80287/80387 for the IBM PC and Compatibles.
  924.      Bowie, MD: Robert J. Brady Co., 1988.
  925.  
  926.  Writing ROMable Code in Microsoft C.
  927.      Costa Mesa, CA: SSI Corporation.
  928.  
  929.  
  930.  Document Conventions
  931.  
  932.  The following document conventions are used throughout this manual:
  933.  
  934.  Example of                        Description
  935.  Convention
  936.  ────────────────────────────────────────────────────────────────────────────
  937.  SAMPLE2.ASM                       Uppercase letters indicate file names,
  938.                                    segment names, registers, and terms used
  939.                                    at the command level.
  940.  
  941.  .MODEL                            Boldface type indicates
  942.                                    assembly-language directives,
  943.                                    instructions, type specifiers, and
  944.                                    predefined macros, as well as keywords
  945.                                    in other programming languages.
  946.  
  947.  placeholders                      Italic letters indicate placeholders for
  948.                                    information you must supply, such as a
  949.                                    file name. Italics are also occasionally
  950.                                    used for emphasis in the text.
  951.  
  952.  target                            This font is used to indicate example
  953.                                    programs, user input, and screen output.
  954.  
  955.  ;                                 A semicolon in the first column of an
  956.                                    example signals illegal code. A
  957.                                    semicolon also marks a comment.
  958.  
  959.  SHIFT                             Small capital letters signify names of
  960.                                    keys on the keyboard. Notice that a plus
  961.                                    (+) indicates a combination of keys. For
  962.                                    example, CTRL+E means to hold down the
  963.                                    CTRL key while pressing the E key.
  964.  
  965.  «argument»                        Items inside double square brackets are
  966.                                    optional.
  967.  
  968.  {register|memory}                 Braces and a vertical bar indicate a
  969.                                    choice between two or more items. You
  970.                                    must choose one of the items unless
  971.                                    double square brackets surround the
  972.                                    braces.
  973.  
  974.  Repeating elements...             A horizontal ellipsis (...) following an
  975.                                    item indicates that more items having
  976.                                    the same form may appear.
  977.  
  978.  Program                           A vertical ellipsis tells you that part
  979.  .                                 of a program has been intentionally
  980.  .                                 omitted.
  981.  .
  982.  Fragment
  983.  
  984.  
  985.  Getting Assistance and Reporting Problems
  986.  
  987.  If you need help or think you have discovered a problem in the software,
  988.  please provide the following information to help us locate the problem:
  989.  
  990.  
  991.    ■   The version of DOS or OS/2 that you are running
  992.  
  993.    ■   Your system configuration: the type of machine you are using, its
  994.        total memory, and its total free memory at assembler execution time,
  995.        as well as any other information you think might be useful
  996.  
  997.    ■   The assembly command line used, or the link command line if the
  998.        problem occurred during linking
  999.  
  1000.    ■   Any object files or libraries you linked with if the problem occurred
  1001.        at link time
  1002.  
  1003.  
  1004.  If your program is very large, please try to reduce its size to the smallest
  1005.  possible program that still produces the problem.
  1006.  
  1007.  Use the Product Assistance Request form at the back of this book to send
  1008.  this information to Microsoft. If you have comments or suggestions regarding
  1009.  any of the books accompanying this product, please indicate them on the
  1010.  Document Feedback Card at the back of this book.
  1011.  
  1012.  If you are not a registered Macro Assembler owner, you should fill out and
  1013.  return the Registration Card. This enables Microsoft to keep you informed of
  1014.  updates and other information about the assembler.
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  Chapter 1  Understanding Global Concepts
  1022.  ────────────────────────────────────────────────────────────────────────────
  1023.  
  1024.  With the development of the Microsoft Macro Assembler (MASM) version 6.0,
  1025.  you now have more options available to you for approaching a programming
  1026.  task. This chapter explains the general concepts of programming in assembly
  1027.  language, beginning with the environment and reviewing the components you
  1028.  need to work in the assembler environment. Even if you are familiar with
  1029.  previous versions of MASM, you should examine this chapter for information
  1030.  on new terms and features.
  1031.  
  1032.  The first section of the chapter takes a look at the available processors
  1033.  and operating systems and how they work together. It also discusses the
  1034.  relationship of segmented architecture to assembly programming and the
  1035.  differences it makes for programming in OS/2 rather than in DOS.
  1036.  
  1037.  The second section describes some of the language components of MASM that
  1038.  are common to most programs, such as reserved words, constant expressions,
  1039.  operators, and registers. The rest of this book assumes that you understand
  1040.  the information presented in this section.
  1041.  
  1042.  The last section summarizes the assembly process, from assembling a program
  1043.  through running it. You can affect this process by the way you develop your
  1044.  code. Finally, this section explores how you can change the assembly process
  1045.  with the OPTION directive and conditional assembly.
  1046.  
  1047.  ────────────────────────────────────────────────────────────────────────────
  1048.  NOTE
  1049.  
  1050.  This manual does not cover information specific to programming for Microsoft
  1051.  Windows(tm). For information on this, see the Microsoft Windows Software
  1052.  Development Kit.
  1053.  ────────────────────────────────────────────────────────────────────────────
  1054.  
  1055.  
  1056.  1.1  The Processing Environment
  1057.  
  1058.  The processing environment for MASM 6.0 includes the processor on which your
  1059.  programs run, the operating system your programs will use, and the aspects
  1060.  of the segmented architecture that influence the choice of programming
  1061.  models. This section summarizes these elements of the environment and how
  1062.  they affect your programming choices.
  1063.  
  1064.  
  1065.  1.1.1  8086-Based Processors
  1066.  
  1067.  The 8086 "family" of processors uses segments to control data and code. The
  1068.  later 8086-based processors have larger instruction sets and more memory
  1069.  capacity, but they still use the same segmented architecture. Knowing the
  1070.  differences between the various 8086-based processors can help you select
  1071.  the target processor for your programs.
  1072.  
  1073.  The instruction set of the 8086 processor is upwardly compatible with its
  1074.  successors. To write code that runs on the widest number of machines, select
  1075.  the 8086 instruction set. By choosing to use the instruction set of a more
  1076.  advanced processor, you increase the capabilities and efficiency of your
  1077.  program, but you also reduce the number of systems on which the program can
  1078.  run.
  1079.  
  1080.  Table 1.1 lists modes, memory, and segment size of processors on which your
  1081.  application may need to run. Each processor is discussed in more detail
  1082.  below.
  1083.  
  1084.  Table 1.1  8086 Family of Processors
  1085.  
  1086. ╓┌────────────┌───────────────────┌──────────────────┌───────────────────────╖
  1087.               Available           Addressable        Segment
  1088.  Processor    Modes               Memory             Size
  1089.  ────────────────────────────────────────────────────────────────────────────
  1090.  8086/8088    Real                1 megabyte         16 bit
  1091.  
  1092.  80186/80188  Real                1 megabyte         16 bit
  1093.  
  1094.               Available           Addressable        Segment
  1095.  Processor    Modes               Memory             Size
  1096.  ────────────────────────────────────────────────────────────────────────────
  1097. 
  1098.  80286        Real and Protected  16 megabytes       16 bit
  1099.  
  1100.  80386        Real and Protected  4 gigabytes        16 or 32 bit
  1101.  
  1102.  80486        Real and Protected  4 gigabytes        16 or 32 bit
  1103.  
  1104.  ────────────────────────────────────────────────────────────────────────────
  1105.  
  1106.  
  1107.  
  1108.  Processor Modes - Real mode allows only one process to run at a time. The
  1109.  DOS operating system runs in real mode. The OS/2 operating system can
  1110.  execute programs written for DOS, but is designed to provide capabilities
  1111.  available only in protected mode. In protected mode, more than one process
  1112.  can be active at any one time. Memory accessed by these different processes
  1113.  is protected from access by another process.
  1114.  
  1115.  Protected-mode addresses do not correspond directly to physical memory.
  1116.  Under protected-mode operating systems, the processor allocates and manages
  1117.  memory dynamically. Additional privileged instructions initialize protected
  1118.  mode and control multiple processes. Section 1.1.2 provides more information
  1119.  on operating systems.
  1120.  
  1121.  8086 and 8088 - The 8086 is faster than the 8088 because of its 16-bit data
  1122.  bus; the 8088 has only an 8-bit data bus. The 16-bit data bus allows you to
  1123.  use EVEN and ALIGN on an 8086 processor to word-align data and thus improve
  1124.  data-handling efficiency. Memory addresses on the 8086 and 8088 refer to
  1125.  actual physical addresses.
  1126.  
  1127.  80186 and 80188 - These two processors are identical to the 8086 and 8088
  1128.  except that new instructions have been added and several old instructions
  1129.  have been optimized. These processors run significantly faster than the
  1130.  8086.
  1131.  
  1132.  80286 - The 80286 processor adds some instructions to control protected
  1133.  mode, and it runs faster. It also provides the optional protected mode that
  1134.  can be used by the operating system to allow multiple processes to run at
  1135.  the same time. The 80286 is the minimum for running 16-bit versions of OS/2.
  1136.  
  1137.  80386 - Unlike its predecessors, the 80386 processor can handle both 16-bit
  1138.  and 32-bit data. It is fully software-compatible with the 80286. It
  1139.  implements many new hardware-level features, including virtual paged memory,
  1140.  multiple virtual 8086 processes, addressing of up to four gigabytes of
  1141.  memory, and specialized debugging registers.
  1142.  
  1143.  Under DOS, the 80836 supports all the instructions of the 80286 as well as
  1144.  several additional ones. It also allows limited use of 32-bit registers and
  1145.  addressing modes. The 80386 operates at faster processor speeds than the
  1146.  80286 and is the minimum for running 32-bit versions of OS/2 and other
  1147.  32-bit operating systems.
  1148.  
  1149.  80486 - The 80486 processor is an enhanced version of the 80386, with
  1150.  instruction "pipelining" that executes many instructions two to three times
  1151.  faster. It incorporates an enhanced version of the 80387 coprocessor, as
  1152.  well as an 8K (kilobyte) memory cache. The 80486 includes several new
  1153.  instructions and is fully compatible with 80386 software.
  1154.  
  1155.  8087, 80287, and 80387 - These math coprocessors work concurrently with the
  1156.  8086 family of processors. Performing floating-point calculations with math
  1157.  coprocessors is up to 100 times faster than emulating the calculations with
  1158.  integer instructions. Although there are technical and performance
  1159.  differences among the three coprocessors, the main difference to the
  1160.  applications programmer is that the 80287 and 80387 can operate in protected
  1161.  mode. The 80387 also has several new instructions. The 80486 does not use
  1162.  any of these coprocessors; its floating-point processor is built in and is
  1163.  functionally equivalent to the 80387.
  1164.  
  1165.  
  1166.  1.1.2  Operating Systems
  1167.  
  1168.  With MASM, you can create programs that run under DOS, Windows, or OS/2─or
  1169.  all three, in some cases. For example, ML.EXE can produce executable files
  1170.  that run in any of the target environments, regardless of the programmer's
  1171.  environment. For information on building programs for different
  1172.  environments, see "Building and Running Programs" in PWB's online help.
  1173.  
  1174.  DOS and OS/2 provide different processing modes. DOS uses the single-process
  1175.  real mode. OS/2 uses the multiple-process protected mode. While OS/2 can
  1176.  also run in real mode, this book assumes it is being used in protected mode.
  1177.  
  1178.  
  1179.  DOS and OS/2 differ primarily in system access methods, size of addressable
  1180.  memory, and segment selection. Table 1.2 summarizes these differences.
  1181.  
  1182.  Table 1.2  The DOS and OS/2 Operating Systems
  1183.  
  1184.                          Available               Contents
  1185.  Operating   System      Active      Addressabl  of Segment  Word Length
  1186.  System      Access      Processes   e Memory
  1187.                                                  Register
  1188.  ─────────────────────────────────────────────────────────────────────────────
  1189.  DOS (and    Direct to   One         1 megabyte  Actual      16 bit
  1190.  OS/2 1.x    hardware                            address
  1191.  real mode)
  1192.  
  1193.  OS/2 1.x    Operating   Multiple    16          Segment     16 bit
  1194.  protected   system                  megabytes   selectors
  1195.  mode        call
  1196.  
  1197.  OS/2 2.x    Operating   Multiple    4           Segment     32 bit
  1198.              system                  gigabytes   selectors
  1199.              call
  1200.  
  1201.  ─────────────────────────────────────────────────────────────────────────────
  1202.  
  1203.  
  1204.  DOS - In real-mode programming, you can access system functions by calling
  1205.  DOS, calling the basic input/output system (BIOS), or directly addressing
  1206.  hardware. Access is through DOS interrupt 21h.
  1207.  
  1208.  Protected-mode programs cannot directly access hardware ports.
  1209.  
  1210.  OS/2 1.x - As you can see in Table 1.2, protected mode allows for much
  1211.  larger data structures than real mode, since the addressable memory is
  1212.  extended to 16 megabytes. In protected mode, segment registers contain
  1213.  segment selectors rather than actual segment values. These selectors cannot
  1214.  be calculated by the program; they must be obtained by calling the operating
  1215.  system. Programs that attempt to calculate segment values or to address
  1216.  memory directly do not work.
  1217.  
  1218.  Note that protected-mode operating systems such as XENIX (R) and OS/2
  1219.  provide system functions for memory and hardware accesses that would be
  1220.  prohibited with direct processor commands. This software interface permits
  1221.  access without the possibility of corrupting memory or crashing the system.
  1222.  
  1223.  
  1224.  Protected mode uses privilege levels to maintain system integrity and
  1225.  security. Programs cannot access data or code that is in a higher privilege
  1226.  level. Some instructions that directly access ports or clear interrupts
  1227.  (such as CLI, STI, IN,  and OUT) are available at privilege levels normally
  1228.  used only by systems programmers.
  1229.  
  1230.  OS/2 protected mode enforces the separation of segment values. The segments
  1231.  have selectors that have no relationship to the offset. The operating system
  1232.  combines the segment and offset so that your programs can address up to 16
  1233.  megabytes of virtual memory in a 16-bit system.
  1234.  
  1235.  OS/2 2.x and flat model eliminate segments.
  1236.  
  1237.  OS/2 2.x - OS/2 2.x uses an unsegmented architecture. (See Section 1.1.3.)
  1238.  It creates a "flat model" in which the entire address space is within one
  1239.  32-bit segment. Section 2.2.1, "Defining Basic Attributes with .MODEL,"
  1240.  explains how to use the flat model. In a 32-bit system, you can access up to
  1241.  four gigabytes of virtual memory. (The term "virtual memory" means that if
  1242.  the programs running under OS/2 request more memory than is physically
  1243.  available, part of the memory is temporarily swapped out to disk.) Since
  1244.  code, data, and stack are in the same segment, the value of segment
  1245.  registers never needs to change. Internal mechanisms of OS/2 2.x implement
  1246.  protection at a lower level.
  1247.  
  1248.  
  1249.  1.1.3  Segmented Architecture
  1250.  
  1251.  The 8086 processors differ from many other microprocessors in that they use
  1252.  a segmented architecture: that is, each address is represented in two
  1253.  parts─a segment and an offset. Segmented addresses affect many aspects of
  1254.  assemblylanguage programming, especially addresses and pointers.
  1255.  
  1256.  Only 64K of data can be addressed by a 16-bit segment address.
  1257.  
  1258.  Segmented architecture was originally designed to enable a 16-bit processor
  1259.  to access an address space larger than 64K. (Section 1.1.5, "Segmented
  1260.  Addressing," explains how the processor uses both the segment and offset to
  1261.  create addresses larger than 64K.) DOS is an example of an operating system
  1262.  that uses segmented architecture on a 16-bit processor.
  1263.  
  1264.  With the advent of protected-mode processors such as the 80286, segmented
  1265.  architecture gained a second purpose. Segments can separate different blocks
  1266.  of code and data to protect them from undesirable interactions. OS/2 1.x is
  1267.  an operating system that takes advantage of the protection features of the
  1268.  16-bit segments on the 80286.
  1269.  
  1270.  Segmented architecture went through another significant change with the
  1271.  release of 32-bit processors, starting with the 80386. These processors are
  1272.  backward compatible with the older 16-bit processors, but they also offer a
  1273.  32-bit mode that minimizes the memory limitations of a 16-bit segmented
  1274.  architecture. Both offer paging to maintain segment protection. XENIX 386 is
  1275.  an example of a 32-bit segmented operating system using segment protection.
  1276.  
  1277.  
  1278.  OS/2 2.x takes advantage of the 32-bit processors to allow a nonsegmented
  1279.  memory configuration. The processor still uses 32-bit segments, but from the
  1280.  user's viewpoint, there is only one segment. The flat memory model used by
  1281.  OS/2 2.x places code and data in a single segment. See Section 2.2.1,
  1282.  "Defining Basic Attributes with .MODEL," for more information about the flat
  1283.  memory model.
  1284.  
  1285.  
  1286.  1.1.4  Segment Protection
  1287.  
  1288.  Segmented architecture is an important part of the OS/2 memory-protection
  1289.  scheme. In a "multitasking" operating system where numerous programs can run
  1290.  simultaneously, programs must not access the code and data of another
  1291.  process without permission.
  1292.  
  1293.  In DOS, the data and code segments are usually allocated adjacent to each
  1294.  other, as shown in Figure 1.1. In OS/2, the data and code segments may be
  1295.  anywhere in memory. The programmer knows nothing about their location and
  1296.  has no control over it. The segments may even be moved to a new memory
  1297.  location or swapped to disk while the program is running.
  1298.  
  1299.  (This figure may be found in the printed book.)
  1300.  
  1301.  Segment protection prevents a bug in one program from corrupting another
  1302.  program.
  1303.  
  1304.  Segment protection makes software development easier and more reliable in
  1305.  OS/2 than in DOS because, in OS/2, any illegal access is detected
  1306.  immediately. The operating system intercepts illegal memory accesses,
  1307.  terminates the program, and displays a message. This makes the bug easier to
  1308.  track down and fix.
  1309.  
  1310.  In DOS, an illegal access is not detected and may not cause an error until
  1311.  later, when another part of the program attempts to use the corrupted
  1312.  memory.
  1313.  
  1314.  
  1315.  1.1.5  Segmented Addressing
  1316.  
  1317.  Segmented addressing is the internal mechanism that combines a segment value
  1318.  and an offset value to create an address. The two parts of an address are
  1319.  represented as
  1320.  
  1321.    segment:offset
  1322.  
  1323.  The segment portion is always a 16-bit value. The offset portion is a 16-bit
  1324.  value in 16-bit mode or a 32-bit value in 32-bit mode.
  1325.  
  1326.  In real mode, the segment value is a physical address that has an arithmetic
  1327.  relationship to the offset value. The segment and offset together create a
  1328.  20-bit physical address (explained in the next section). Although 20-bit
  1329.  addresses can access up to one megabyte of memory, the operating system on
  1330.  IBM (R) PCs and compatibles uses part of this memory, leaving 640K of memory
  1331.  for programs.
  1332.  
  1333.  
  1334.  1.1.6  Segment Arithmetic
  1335.  
  1336.  Manipulating segment and offset addresses directly in real-mode programming
  1337.  is called "segment arithmetic." Programs that perform segment arithmetic are
  1338.  not portable to protected-mode operating systems, where addresses do not
  1339.  correspond to a known segment and offset.
  1340.  
  1341.  The segment selects a region of memory; the offset selects the byte within
  1342.  that region.
  1343.  
  1344.  To perform segment arithmetic successfully, it helps to understand how the
  1345.  processor combines a 16-bit segment and a 16-bit offset to form a 20-bit
  1346.  linear address. In effect, the segment selects a 64K region of memory, and
  1347.  the offset selects the byte within that region. Here's how it works:
  1348.  
  1349.  
  1350.    1.  The processor shifts the segment address to the left by four binary
  1351.        places, producing a 20-bit address ending in four zeros. This
  1352.        operation has the effect of multiplying the segment address by 16.
  1353.  
  1354.    2.  The processor adds this 20-bit segment address to the 16-bit offset
  1355.        address. The offset address is not shifted.
  1356.  
  1357.    3.  The processor uses the resulting 20-bit address, often called the
  1358.        "physical address," to access an actual location in the one-megabyte
  1359.        address space.
  1360.  
  1361.  
  1362.  Figure 1.2 illustrates this process.
  1363.  
  1364.  (This figure may be found in the printed book.)
  1365.  
  1366.  A 20-bit physical address may actually be specified by 4,096 equivalent
  1367.  segment:offset addresses. For example, the 20-bit physical address 0F800 is
  1368.  equivalent to 0000:F800, 0F00:0800, or 0F80:0000.
  1369.  
  1370.  You may need to convert two segmented addresses with different segments to
  1371.  segmented addresses with the same segment to write TSRs (see Chapter 19), to
  1372.  write code to handle huge arrays, or to determine the size of an area of
  1373.  memory.
  1374.  
  1375.  
  1376.  1.2  Language Components of MASM
  1377.  
  1378.  Programming with MASM requires that you understand the MASM concepts of
  1379.  reserved words, identifiers, predefined symbols, constants, expressions,
  1380.  operators, data types, registers, and statements. This section defines
  1381.  important terms and provides lists that summarize these topics. See online
  1382.  help or the MASM Reference for detailed information.
  1383.  
  1384.  
  1385.  1.2.1  Reserved Words
  1386.  
  1387.  A reserved word has a special meaning fixed by the language. You can use it
  1388.  only under certain conditions. MASM's reserved words include:
  1389.  
  1390.  
  1391.    ■   Instructions, which correspond to operations the processor can execute
  1392.  
  1393.    ■   Directives, which give commands to the assembler
  1394.  
  1395.    ■   Attributes, which provide a value for a field, such as segment
  1396.        alignment
  1397.  
  1398.    ■   Operators, which are used in expressions
  1399.  
  1400.    ■   Predefined symbols, which return information to your program
  1401.  
  1402.  
  1403.  MASM reserved words are not case sensitive except for predefined symbols
  1404.  (see Section 1.2.3).
  1405.  
  1406.  Use OPTION NOKEYWORD if you want to use a reserved word in another context.
  1407.  
  1408.  
  1409.  The assembler generates an error if you use a reserved word as a variable,
  1410.  code label, or other identifier within your source code. However, if you
  1411.  need to use a reserved word for another purpose, the OPTION NOKEYWORD
  1412.  directive can selectively disable a word's status as a reserved word.
  1413.  
  1414.  For example, to remove the STR instruction, the MASK operator, and the NAME
  1415.  directive from the set of words MASM recognizes as reserved, use this
  1416.  statement in the code segment of your program prior to the first reference
  1417.  to STR, MASK, or NAME:
  1418.  
  1419.    OPTION NOKEYWORD:<STR MASK NAME>
  1420.  
  1421.  The OPTION directive is discussed in Section 1.3.2. Appendix D provides a
  1422.  complete list of MASM reserved words.
  1423.  
  1424.  
  1425.  1.2.2  Identifiers
  1426.  
  1427.  Identifiers are names of variables of a given type.
  1428.  
  1429.  An identifier is a name that you invent and attach to a definition.
  1430.  Identifiers can be symbols representing variables, constants, procedure
  1431.  names, code labels, segment names, and user-defined data types such as
  1432.  structures, unions, records, and types defined with TYPEDEF. Identifiers
  1433.  longer than 247 characters generate an error.
  1434.  
  1435.  Certain restrictions limit the names you can use for identifiers. Follow
  1436.  these rules to define a name for an identifier:
  1437.  
  1438.  
  1439.    ■   The first character of the identifier can be an alphabetic character
  1440.        (A-Z) or any of these four characters: @  _   $  ?
  1441.  
  1442.    ■   The other characters in the identifier can be any of the characters
  1443.        listed above or a decimal digit (0-9)
  1444.  
  1445.  
  1446.  Avoid starting an identifier with the at sign (@), because MASM 6.0
  1447.  predefines some special symbols starting with @ (see Section 1.2.3).
  1448.  Beginning an identifier with @ may also cause conflicts with future versions
  1449.  of the Macro Assembler.
  1450.  
  1451.  The symbol--and thus the identifier--is visible as long as it remains within
  1452.  scope. (See Section 8.2, "Sharing Symbols with Include Files," for
  1453.  additional information about visibility and scope.)
  1454.  
  1455.  
  1456.  1.2.3  Predefined Symbols
  1457.  
  1458.  Macros and conditionalassembly blocks often use predefined symbols.
  1459.  
  1460.  The assembler includes a number of predefined symbols (also called
  1461.  predefined equates). You can use these symbol names at any point in your
  1462.  code to represent the equate value. For example, the predefined equate
  1463.  @FileName represents the base name of the current file. If the current
  1464.  source file is TASK.ASM, the value of @FileName is TASK. The MASM predefined
  1465.  symbols are listed below according to the kinds of information they provide.
  1466.  Case is important only if the /Cp option is used. (See online help on ML
  1467.  command-line options for additional details.)
  1468.  
  1469.  
  1470.  Predefined Symbols for Segment Information
  1471.  
  1472. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  1473.  Symbol                            Description
  1474.  ────────────────────────────────────────────────────────────────────────────
  1475.  @code                             Provides the name of the code segment,
  1476.                                    except in tiny model when it returns
  1477.                                    DGROUP.
  1478.  
  1479.  @CodeSize                         Returns an integer representing the
  1480.                                    default code distance.
  1481.  
  1482.  @CurSeg                           Returns the name of the current segment.
  1483.  
  1484.  @data                             Expands to DGROUP except in flat model.
  1485.  
  1486.  @DataSize                         Returns an integer representing the
  1487.                                    default data distance.
  1488.  
  1489.  @fardata                          Represents the name of the segment
  1490.                                    defined by the .FARDATA directive.
  1491.  
  1492.  @fardata?                         Represents the name of the segment
  1493.  Symbol                            Description
  1494.  ────────────────────────────────────────────────────────────────────────────
  1495. @fardata?                         Represents the name of the segment
  1496.                                    defined by the .FARDATA? directive.
  1497.  
  1498.  @Model                            Returns the selected memory model.
  1499.  
  1500.  @stack                            Expands to DGROUP for near stacks or
  1501.                                    STACK for far stacks. (See Section 2.2.3,
  1502.                                    "Creating a Stack.")
  1503.  
  1504.  @WordSize                         Provides the size attribute of the
  1505.                                    current segment.
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  Predefined Symbols for Environment Information
  1511.  
  1512.  Symbol                            Description
  1513.  ────────────────────────────────────────────────────────────────────────────
  1514.  @Cpu                              Contains a bit mask specifying the
  1515.                                    processor mode.
  1516.  
  1517.  @Environ                          Returns values of environment variables.
  1518.  
  1519.  @Interface                        Contains information about the language
  1520.                                    parameters.
  1521.  
  1522.  @Version                          Represents the text equivalent of the
  1523.                                    MASM version number. In MASM 6.0, this
  1524.                                    expands to 600.
  1525.  
  1526.  
  1527.  
  1528.  Predefined Symbols for Date and Time Information
  1529.  
  1530.  Symbol            Description
  1531.  ────────────────────────────────────────────────────────────────────────────
  1532.  @Date             Supplies the current system date.
  1533.  @Time             Supplies the current system time.
  1534.  
  1535.  
  1536.  Predefined Symbols for File Information
  1537.  
  1538.  Symbol                            Description
  1539.  ────────────────────────────────────────────────────────────────────────────
  1540.  @FileCur                          Names the current file (base and suffix).
  1541.  
  1542.  @FileName                         Names the base name of the main file
  1543.                                    being assembled as it appears on the
  1544.                                    command line.
  1545.  
  1546.  @Line                             Gives the source line number in the
  1547.                                    current file.
  1548.  
  1549.  
  1550.  
  1551.  Predefined Functions for Macro String Manipulation
  1552.  
  1553.  Symbol    Description
  1554.  ────────────────────────────────────────────────────────────────────────────
  1555.  @CatStr   Returns concatenation of two strings.
  1556.  @InStr    Returns the starting position of a string within another string.
  1557.  @SizeStr  Returns the length of a given string.
  1558.  @SubStr   Returns substring from a given string.
  1559.  
  1560.  
  1561.  1.2.4  Integer Constants and Constant Expressions
  1562.  
  1563.  An integer constant is a series of one or more numerals followed by an
  1564.  optional radix specifier. For example, in these statements
  1565.  
  1566.    mov     ax, 25
  1567.            mov     ax, 0B3h
  1568.  
  1569.  the numbers  25  and  0B3h  are integer constants. The  h  appended to  0B3
  1570.  is a radix specifier. The specifiers are
  1571.  
  1572.  
  1573.    ■   y  for binary (or  b  if radix is less than or equal to 10)
  1574.  
  1575.    ■   o  or  q  for octal
  1576.  
  1577.    ■   t  for decimal (or  d  if radix is less than or equal to 10)
  1578.  
  1579.    ■   h  for hexadecimal
  1580.  
  1581.  
  1582.  The default radix is decimal.
  1583.  
  1584.  Radix specifiers can be either uppercase or lowercase letters; sample code
  1585.  in this book uses lowercase. If no radix is specified, the assembler
  1586.  interprets the integer according to the current radix. The default radix is
  1587.  decimal, but it can be changed with the .RADIX directive.
  1588.  
  1589.  Hexadecimal numbers must always start with a decimal digit (0-9). If
  1590.  necessary, add a leading zero to distinguish between symbols and hexadecimal
  1591.  numbers that start with a letter. For example,  ABCh  is interpreted as an
  1592.  identifier. The hexadecimal digits A through F can be either uppercase or
  1593.  lowercase letters. Sample code in this book uses uppercase letters.
  1594.  
  1595.  Values of integer constants and expressions are known at assembly time.
  1596.  
  1597.  Constant expressions contain integer constants and (optionally) operators
  1598.  such as shift, logical, and arithmetic operators, and can be evaluated. The
  1599.  assembler evaluates them at assembly time. (In addition to constants,
  1600.  expressions can contain labels, types, registers, and their attributes.)
  1601.  Constant expressions do not change value during program execution.
  1602.  
  1603.  Symbolic Integer Constants - You can define symbolic integer constants with
  1604.  either of the data assignment directives, EQU or the equal sign (=). These
  1605.  directives assign values to symbols during assembly, not during program
  1606.  execution. Symbols defined as integer constants can then be used in
  1607.  subsequent statements as immediate operands having the assigned value.
  1608.  Symbolic constants are often used to assign mnemonic names to constant
  1609.  values, which makes your code more readable and easier to maintain.
  1610.  
  1611.  The assembler does not allocate data storage when you use either EQU or =.
  1612.  Instead, it replaces each occurrence of the symbol with the value of the
  1613.  expression.
  1614.  
  1615.  Symbols defined with EQU cannot be redefined.
  1616.  
  1617.  The difference between EQU and = is that integers defined with the =
  1618.  directive can be changed in your source code, but those defined with EQU
  1619.  cannot. Once a symbolic integer constant has been defined with the EQU
  1620.  directive, attempting to redefine it generates an error. The syntax is
  1621.  
  1622.    symbol EQU expression
  1623.  
  1624.  The symbol must be a unique name. The expression can be an integer, a
  1625.  constant expression, a one- or two-character string constant (four-character
  1626.  on the 80386/486), or an expression that evaluates to an address. If a
  1627.  constant value used in numerous places in the source code needs to be
  1628.  changed, you modify the expression in one place rather than throughout the
  1629.  source code.
  1630.  
  1631.  The following example shows the correct use of EQU to define symbolic
  1632.  integers.
  1633.  
  1634.    column  EQU    80                ; Constant -    80
  1635.    row     EQU    25                ; Constant -    25
  1636.    screen  EQU    column * row      ; Constant  - 2000
  1637.    line    EQU    row               ; Constant -    25
  1638.  
  1639.           .DATA
  1640.  
  1641.           .CODE
  1642.           .
  1643.           .
  1644.           .
  1645.           mov     cx, column
  1646.           mov     bx, line
  1647.  
  1648.  The value of a symbol defined with the = directive can be different at
  1649.  different places in the source code. However, a constant value is assigned
  1650.  during assembly for each use, and that value does not change at run time.
  1651.  
  1652.  The syntax for the = directive is
  1653.  
  1654.  symbol = expression
  1655.  
  1656.  Size of Constants - The default word size for MASM 6.0 expressions is 32
  1657.  bits. This behavior can be modified using OPTION EXPR16 or OPTION M510. Both
  1658.  of these options set the expression word size to 16 bits, but OPTION M510
  1659.  affects other assembler behavior as well (see Appendix A).
  1660.  
  1661.  It is illegal to change the expression word size once it has been set with
  1662.  OPTION M510, OPTION EXPR16, or OPTION EXPR32, but you can repeat the same
  1663.  directive in a file. This can be useful for putting an OPTION EXPR16 in
  1664.  every include file, for example.
  1665.  
  1666.  
  1667.  1.2.5  Operators
  1668.  
  1669.  Operators are used in expressions. The value of the expression is determined
  1670.  at assembly time and does not change when the program runs.
  1671.  
  1672.  Operators should not be confused with processor instructions. The reserved
  1673.  word ADD is an instruction. The plus sign (+) is an operator. For example,
  1674.  Amount+2  is a valid use of the plus operator (+); it tells the assembler to
  1675.  add  2 to  Amount, which might be a value or an address. This operation,
  1676.  which occurs at assembly time, is different from the ADD instruction, which
  1677.  tells the processor to perform addition at run time.
  1678.  
  1679.  The assembler evaluates expressions that contain more than one operator
  1680.  according to the following rules:
  1681.  
  1682.  
  1683.    ■   Operations in parentheses are always performed before any adjacent
  1684.        operations.
  1685.  
  1686.    ■   Binary operations of highest precedence are performed first.
  1687.  
  1688.    ■   Operations of equal precedence are performed from left to right.
  1689.  
  1690.    ■   Unary operations of equal precedence are performed right to left.
  1691.  
  1692.  
  1693.  The order of precedence for all operators is listed in Table 1.3. Operators
  1694.  on the same line have equal precedence.
  1695.  
  1696.  Table 1.3  Operator Precedence
  1697.  
  1698. ╓┌───────────────────┌───────────────────────────────────────────────────────╖
  1699.  Precedence          Operators
  1700.  ────────────────────────────────────────────────────────────────────────────
  1701.  1                   ( ), [ ]
  1702.  2                   LENGTH, SIZE, WIDTH, MASK
  1703.  Precedence          Operators
  1704.  ────────────────────────────────────────────────────────────────────────────
  1705. 2                   LENGTH, SIZE, WIDTH, MASK
  1706.  3                   . (structure-field-name operator)
  1707.  4                   : (segment-override operator), PTR
  1708.  5                   LROFFSET, OFFSET, SEG, THIS, TYPE
  1709.  6                   HIGH, HIGHWORD, LOW, LOWWORD
  1710.  7                   + ,- (unary)
  1711.  8                   *, /, MOD, SHL, SHR
  1712.  9                   +, - (binary)
  1713.  10                  EQ, NE, LT, LE, GT, GE
  1714.  11                  NOT
  1715.  12                  AND
  1716.  13                  OR, XOR
  1717.  14                  OPATTR, SHORT, .TYPE
  1718.  ────────────────────────────────────────────────────────────────────────────
  1719.  
  1720.  
  1721.  
  1722.  1.2.6  Data Types
  1723.  
  1724.  A "data type" describes a set of values. A variable of a given type can have
  1725.  any of a set of values within the range specified for that type.
  1726.  
  1727.  The intrinsic types for MASM 6.0 are BYTE, SBYTE, WORD, SWORD, DWORD,
  1728.  SDWORD, FWORD, QWORD, and TBYTE. These types define integers and binary
  1729.  coded decimals (BCDs); they are discussed in Chapter 6. The signed data
  1730.  types SBYTE, SWORD, and SDWORD are new to MASM 6.0. They are useful in
  1731.  conjunction with directives such as INVOKE (for calling procedures) and .IF
  1732.  (introduced in Chapter 7). The REAL4, REAL8, and REAL10 directives can be
  1733.  used to define floating-point types. See Chapter 6.
  1734.  
  1735.  Previous versions of MASM have separate directives for types and
  1736.  initializers. For example, BYTE is a type and DB is the corresponding
  1737.  initializer. The distinction has been eliminated for MASM 6.0. Any type
  1738.  (intrinsic or user-defined) can be used as an initializer.
  1739.  
  1740.  MASM does not have specific types for arrays and strings. However, it allows
  1741.  a sequence of data units to be treated as arrays, and character (byte)
  1742.  sequences to be treated as strings. (See Section 5.1, "Arrays and Strings.")
  1743.  
  1744.  
  1745.  Types can also have attributes such as langtype and distance (NEAR and FAR).
  1746.  See Section 7.3.3, "Declaring Parameters with the PROC Directive," for
  1747.  information on these attributes.
  1748.  
  1749.  You can also define your own types with STRUCT, UNION, and RECORD. The types
  1750.  have fields that contain string or numeric data, or records that contain
  1751.  bits. These data types are similar to the user-defined data types in
  1752.  high-level languages such as C, Pascal, and FORTRAN. (See Chapter 5,
  1753.  "Defining and Using Complex Data Types.")
  1754.  
  1755.  The TYPEDEF directive defines aliases and pointer types.
  1756.  
  1757.  You can define new types, including pointer types, with the TYPEDEF
  1758.  directive, which is also new to MASM 6.0. TYPEDEF assigns a qualifiedtype
  1759.  (explained below) to a typename.
  1760.  
  1761.  ────────────────────────────────────────────────────────────────────────────
  1762.  NOTE
  1763.  
  1764.  The concept of the qualifiedtype is essential to understanding many of the
  1765.  new features in MASM 6.0, including prototypes and the .IF and INVOKE
  1766.  directives. Descriptions of these topics in later chapters refer to this
  1767.  section.
  1768.  ────────────────────────────────────────────────────────────────────────────
  1769.  
  1770.  Once assigned, the typename can be used as a data type in your program. Use
  1771.  of the qualifiedtype also allows the CodeView debugger to display
  1772.  information on the type. You cannot use a qualifiedtype as an initializer,
  1773.  but you can use a type defined with TYPEDEF.
  1774.  
  1775.  The qualifiedtype is any MASM type (such as structure types, union types,
  1776.  record types, or an intrinsic type) or can be a pointer to a type with the
  1777.  form
  1778.  
  1779.    «distance» PTR «qualifiedtype»
  1780.  
  1781.  where distance is NEAR, FAR, or any distance modifier. See Section 7.3.3,
  1782.  "Declaring Parameters with the PROC Directive," for more information on
  1783.  distance.
  1784.  
  1785.  The qualifiedtype can also be any type previously defined with TYPEDEF. For
  1786.  example, if you use TYPEDEF to create an alias for BYTE, as shown below,
  1787.  then you can use that  CHAR  type as a qualifiedtype when defining the
  1788.  pointer type  PCHAR.
  1789.  
  1790.    CHAR    TYPEDEF BYTE
  1791.    PCHAR   TYPEDEF PTR CHAR
  1792.  
  1793.  Section 3.3, "Accessing Data with Pointers and Addresses," shows how to use
  1794.  the TYPEDEF directive to define pointers.
  1795.  
  1796.  Since distance and qualifiedtype are optional syntax elements, you can use
  1797.  variables of type PTR or FAR PTR. You can also define procedure prototypes
  1798.  with qualifiedtype. See Section 7.3.6, "Declaring Procedure Prototypes," for
  1799.  more information about procedure prototypes.
  1800.  
  1801.  Several rules govern the use of qualifiedtype:
  1802.  
  1803.  
  1804.    ■   The only component of a qualifiedtype definition that can be
  1805.        forwardreferenced is a structure or union type identifier.
  1806.  
  1807.    ■   If distance is not specified, the right operand and current memory
  1808.        model determine the type of the pointer. If the operand following PTR
  1809.        is not a distance or a function prototype, the operand is a pointer of
  1810.        the default data pointer type in the current mode. Otherwise, the type
  1811.        of the pointer is the distance of the right operand.
  1812.  
  1813.    ■   If .MODEL is not specified, SMALL model (and therefore NEAR pointers)
  1814.        is the default.
  1815.  
  1816.  
  1817.  A qualifiedtype can be used in seven places:
  1818.  
  1819. ╓┌─────────────────────────────────────┌─────────────────────────────────────╖
  1820.  Use                                   Example
  1821.  ────────────────────────────────────────────────────────────────────────────
  1822.  In procedure arguments                proc1 PROC pMsg:PTR BYTE
  1823.  
  1824.  In prototype arguments                proc2 PROTO pMsg:FAR PTR WORD
  1825.  
  1826.  With local variables declared inside  LOCAL pMsg:PTR
  1827.  procedures
  1828.  
  1829.  Use                                   Example
  1830.  ────────────────────────────────────────────────────────────────────────────
  1831. 
  1832.  With the LABEL directive              TempMsg LABEL PTR WORD
  1833.  
  1834.  With the EXTERN and EXTERNDEF         EXTERN pMsg:FAR PTR BYTE
  1835.  directives                            EXTERN MyProc:PROTO
  1836.  
  1837.  With the COMM directive               COMM var1:WORD:3
  1838.  
  1839.  With the TYPEDEF directive            PPBYTE TYPEDEF PTR PBYTE PFUNC
  1840.                                        TYPEDEF PROTO MyProc
  1841.  
  1842.  
  1843.  
  1844.  Section 3.3.1 shows ways to write a TYPEDEF type for a qualifiedtype.
  1845.  Attributes such as NEAR and FAR can also be applied to a qualifiedtype.
  1846.  
  1847.  You can also determine an accurate definition for TYPEDEF and qualifiedtype
  1848.  from the BNF grammar definitions given in Appendix B. The BNF grammar
  1849.  defines each component of the syntax for any directive, showing the
  1850.  recursive properties of components such as qualifiedtype.
  1851.  
  1852.  
  1853.  1.2.7  Registers
  1854.  
  1855.  All the 8086 processors have the same base set of 16-bit registers. Some
  1856.  registers can be accessed as two separate 8-bit registers. In the 80386/486,
  1857.  most registers can also be accessed as extended 32-bit registers.
  1858.  
  1859.  Figure 1.3 shows the registers common to all the 8086-based processors. Each
  1860.  register has its own special uses and limitations.
  1861.  
  1862.  (This figure may be found in the printed book.)
  1863.  
  1864.  80386/486 Only - The 80386/486 processors use the same 8-bit and 16-bit
  1865.  registers that the rest of the 8086 family uses. All of these registers can
  1866.  be further extended to 32 bits, except segment registers, which always
  1867.  occupy 16 bits. The extended register names begin with the letter "E." For
  1868.  example, the 32-bit extension of AX is EAX. The 80386/486 processors have
  1869.  two additional segment registers, FS and GS. Figure 1.4 shows the extended
  1870.  registers of the 80386/486.
  1871.  
  1872.  (This figure may be found in the printed book.)
  1873.  
  1874.  
  1875.  1.2.7.1  Segment Registers
  1876.  
  1877.  At run time, all addresses are relative to one of four segment registers:
  1878.  CS, DS, SS, or ES. (The 80386/486 processors add two more, FS and GS.) These
  1879.  registers, their segments, and their purpose are listed below:
  1880.  
  1881.  Register and Segment              Purpose
  1882.  ────────────────────────────────────────────────────────────────────────────
  1883.  CS (Code Segment)                 Contains processor instructions and
  1884.                                    their immediate operands.
  1885.  
  1886.  DS (Data Segment)                 Normally contains data allocated by the
  1887.                                    program.
  1888.  
  1889.  SS (Stack Segment)                Creates stacks for use by PUSH, POP,
  1890.                                    CALLS,
  1891.                                    and RET.
  1892.  
  1893.  ES (Extra Segment)                References secondary data segment. Used
  1894.                                    by string instructions.
  1895.  
  1896.  FS, GS                            Provides extra segments on the
  1897.                                    80386/486.
  1898.  
  1899.  
  1900.  1.2.7.2  General-Purpose Registers
  1901.  
  1902.  Operations on registers are usually faster than operations on memory
  1903.  locations.
  1904.  
  1905.  The AX, DX, CX, BX, BP, DI, and SI registers are 16-bit general-purpose
  1906.  registers. They can be used for temporary data storage. Since the processor
  1907.  accesses registers more quickly than it can access memory, you can speed up
  1908.  execution by keeping the most frequently used data in registers.
  1909.  
  1910.  The 8086 family of processors does not perform memory-to-memory operations.
  1911.  Thus, operations on more than one variable often require the data to be
  1912.  moved into registers.
  1913.  
  1914.  Four of the general registers, AX, DX, CX, and BX, can be accessed either as
  1915.  two 8-bit registers or as a single 16-bit register. The AH, DH, CH, and BH
  1916.  registers represent the high-order 8 bits of the corresponding registers.
  1917.  Similarly, AL, DL, CL, and BL represent the low-order 8 bits of the
  1918.  registers. All the general registers can be extended to 32 bits on the
  1919.  80386/486.
  1920.  
  1921.  
  1922.  1.2.7.3  Special-Purpose Registers
  1923.  
  1924.  The 8086 family of processors has two additional registers whose values are
  1925.  changed automatically by the processor.
  1926.  
  1927.  SP (Stack Pointer) - The SP register points to the current location within
  1928.  the stack segment. Pushing a value onto the stack decreases the value of SP
  1929.  by 2; popping from the stack increases the value of SP by 2. With 32-bit
  1930.  operands on 80386/486 processors, SP is increased or decreased by 4 instead
  1931.  of 2. Call instructions store the calling address on the stack and decrease
  1932.  SP accordingly; return instructions get the stored address and increase SP.
  1933.  SP can also be manipulated as a general-purpose register with instructions
  1934.  such as ADD.
  1935.  
  1936.  Only the processor can change IP.
  1937.  
  1938.  IP (Instruction Pointer)  - The IP register always contains the address of
  1939.  the next instruction to be executed. You cannot directly access or change
  1940.  the instruction pointer. However, instructions that control program flow
  1941.  (such as calls, jumps, loops, and interrupts) automatically change the
  1942.  instruction pointer.
  1943.  
  1944.  
  1945.  1.2.7.4  Flags Register
  1946.  
  1947.  Flags reveal the status of the processor.
  1948.  
  1949.  The 16 bits in the flags register control the execution of certain
  1950.  instructions and reflect the current status of the processor. In 80386/486
  1951.  processors, the flags register is extended to 32 bits. Some bits are
  1952.  undefined, so there are actually 9 flags for real mode, 11 flags (including
  1953.  a 2-bit flag) for 80286 protected mode, 13 for the 80386, and 14 for the
  1954.  80486. The extended flags register of the 80386/486 is sometimes called
  1955.  "Eflags."
  1956.  
  1957.  Figure 1.5 shows the bits of the 32-bit flags register for the 80386/486.
  1958.  Only the lower word is used for the other 8086-family processors. The
  1959.  unmarked bits are reserved for processor use; do not modify them.
  1960.  
  1961.  (This figure may be found in the printed book.)
  1962.  
  1963.  The nine flags common to all 8086-family processors are summarized below,
  1964.  starting with the low-order flags. In these descriptions, "set" means the
  1965.  bit value is 1, and "cleared" means the bit value is 0.
  1966.  
  1967. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  1968.  Flag                              Description
  1969.  ────────────────────────────────────────────────────────────────────────────
  1970.  Carry                             Set if an operation generates a carry to
  1971.                                    or a borrow from a destination operand.
  1972.  
  1973.  Parity                            Set if the low-order bits of the result
  1974.                                    of an operation contain an even number
  1975.                                    of set bits.
  1976.  Flag                              Description
  1977.  ────────────────────────────────────────────────────────────────────────────
  1978.                                   of set bits.
  1979.  
  1980.  Auxiliary Carry                   Set if an operation generates a carry to
  1981.                                    or a borrow from the low-order four bits
  1982.                                    of an operand. This flag is used for
  1983.                                    binary coded decimal (BCD) arithmetic.
  1984.  
  1985.  Zero                              Set if the result of an operation is 0.
  1986.  
  1987.  Sign                              Equal to the high-order bit of the
  1988.                                    result of an operation (0 is positive, 1
  1989.                                    is negative).
  1990.  
  1991.  Trap                              If set, the processor generates a
  1992.                                    single-step interrupt after each
  1993.                                    instruction. A debugging program can use
  1994.                                    this feature to execute a program one
  1995.                                    instruction at a time.
  1996.  
  1997.  Flag                              Description
  1998.  ────────────────────────────────────────────────────────────────────────────
  1999. 
  2000.  Interrupt Enable                  If set, interrupts are recognized and
  2001.                                    acted on as they are received. The bit
  2002.                                    can be cleared to turn off interrupt
  2003.                                    processing temporarily.
  2004.  
  2005.  Direction                         Set to make string operations process
  2006.                                    down from high addresses to low
  2007.                                    addresses; can be cleared to make string
  2008.                                    operations process up from low addresses
  2009.                                    to high addresses.
  2010.  
  2011.  Overflow                          Set if the result of an operation is too
  2012.                                    large or small to fit in the destination
  2013.                                    operand.
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  1.2.8  Statements
  2019.  
  2020.  Statements are the line-by-line components of source files. Each MASM
  2021.  statement specifies an instruction or directive for the assembler.
  2022.  Statements have up to four fields. The syntax is shown below:
  2023.  
  2024.    «name» «operation» «operands»
  2025.    «;comment»
  2026.  
  2027.  The fields are explained below:
  2028.  
  2029.  Field                             Purpose
  2030.  ────────────────────────────────────────────────────────────────────────────
  2031.  name                              Defines a label that can be accessed
  2032.                                    from elsewhere in the program. For
  2033.                                    example, it can name a variable, type,
  2034.                                    segment, or code location.
  2035.  
  2036.  operation                         States the action of the statement. This
  2037.                                    field contains either an instruction or
  2038.                                    an assembler directive.
  2039.  
  2040.  operands                          Lists one or more items on which the
  2041.                                    instruction or directive operates.
  2042.  
  2043.  comment                           Provides a comment for the programmer.
  2044.                                    Comments
  2045.                                    are for documentation only; they are
  2046.                                    ignored by the
  2047.                                    assembler.
  2048.  
  2049.  
  2050.  The following line contains all four fields:
  2051.  
  2052.    mainlp: mov     ax, 7   ; Comments follow the semicolon
  2053.  
  2054.  Here,  mainlp  is the label,  mov  is the operation, and  ax  and  7  are
  2055.  the operands, separated by a comma. The comment follows the semicolon.
  2056.  
  2057.  All fields are optional, although certain directives and instructions
  2058.  require an entry in the name or operand field. Some instructions and
  2059.  directives place restrictions on the choice of operands. By default, MASM is
  2060.  not case sensitive.
  2061.  
  2062.  Each field (except the comment field) must be separated from other fields by
  2063.  white-space characters (spaces or tabs). MASM also requires code labels to
  2064.  be followed by a colon, operands to be separated by commas, and comments to
  2065.  be preceded by a semicolon.
  2066.  
  2067.  The backslash character joins physical lines into one logical line.
  2068.  
  2069.  A logical line can contain up to 512 characters and occupy one or more
  2070.  physical lines. To extend a logical line into two or more physical lines,
  2071.  put the backslash character (\) as the last non-whitespace character before
  2072.  the comment or end of the line. You can place a comment after the backslash
  2073.  as shown in this example:
  2074.  
  2075.    .IF     (x > 0)    \  ; X must be positive
  2076.             &&     (ax > x)   \  ; Result from function must be > x
  2077.             &&     (cx == 0)     ; Check loop counter too
  2078.             mov    dx, 20h
  2079.            .ENDIF
  2080.  
  2081.  Multiline comments can also be specified with the COMMENT directive. The
  2082.  assembler ignores all code between the delimiter character following the
  2083.  directive and the line containing the next instance of the delimiter
  2084.  character. This example illustrates the use of COMMENT.
  2085.  
  2086.    COMMENT ^               The assembler
  2087.                            ignores this text
  2088.    ^       mov     ax, 1   and this code
  2089.  
  2090.  
  2091.  1.3  The Assembly Process
  2092.  
  2093.  Creating and running an executable file involves several processes:
  2094.  
  2095.  
  2096.    ■   Assembling the source code into an object file
  2097.  
  2098.    ■   Linking the object file with other modules or libraries into an
  2099.        executable program
  2100.  
  2101.    ■   Loading that program into memory
  2102.  
  2103.    ■   Running the program
  2104.  
  2105.  
  2106.  Once you have written your assembly-language program, MASM provides several
  2107.  options for assembling it. The OPTION directive, new to MASM 6.0, has
  2108.  several different arguments that let you control the way MASM assembles your
  2109.  programs.
  2110.  
  2111.  You can control assembly behavior with conditional assembly.
  2112.  
  2113.  Conditional assembly allows you to create one source file that can generate
  2114.  a variety of programs, depending on the status of various
  2115.  conditional-assembly statements.
  2116.  
  2117.  
  2118.  1.3.1  Generating and Running Executable Programs
  2119.  
  2120.  This section briefly lists all the actions that take place during each of
  2121.  the assembly steps. You can change the behavior of some of these actions in
  2122.  various ways, for example, by using macros instead of procedures, or by
  2123.  using the OPTION directive or conditional assembly. The other chapters in
  2124.  this book discuss specific programming methods; this list simply gives you
  2125.  an overview.
  2126.  
  2127.  
  2128.  1.3.1.1  Assembling
  2129.  
  2130.  The ML.EXE program does two things to create an executable program. First,
  2131.  it assembles the source code into an intermediate object file. Second, it
  2132.  calls the linker, LINK.EXE, which links the object files and libraries into
  2133.  an executable program (usually with the .EXE extension).
  2134.  
  2135.  At assembly time, the assembler
  2136.  
  2137.  
  2138.    ■   Evaluates conditional-assembly directives, assembling if the
  2139.        conditions are true.
  2140.  
  2141.    ■   Expands macros and macro functions.
  2142.  
  2143.    ■   Evaluates constant expressions such as  MYFLAG AND 80H, substituting
  2144.        the calculated value for the expression.
  2145.  
  2146.    ■   Encodes instructions and nonaddress operands. For example,  mov cx, 13
  2147.         can be encoded at assembly time because the instruction does not
  2148.        access memory.
  2149.  
  2150.    ■   Saves memory offsets as offsets from their segment.
  2151.  
  2152.    ■   Passes segments and segment attributes to the object file.
  2153.  
  2154.    ■   Saves placeholders for offsets and segments (relocatable addresses).
  2155.  
  2156.    ■   Outputs a listing if requested.
  2157.  
  2158.    ■   Passes messages (such as INCLUDELIB and .DOSSEG) directly to the
  2159.        linker.
  2160.  
  2161.  
  2162.  See Section 1.3.3 for information about conditional assembly; see Chapter 9
  2163.  for macros. Chapters 2 and 3 give further details about segments and
  2164.  offsets, and Appendix C explains listing files.
  2165.  
  2166.  
  2167.  1.3.1.2  Linking
  2168.  
  2169.  Once your source code is assembled, the resulting object file is passed to
  2170.  the linker. At this point, the linker may combine several object files into
  2171.  an executable program.
  2172.  
  2173.  At link time, the linker
  2174.  
  2175.  
  2176.    ■   Combines segments according to the instructions in the object files,
  2177.        rearranging the positions of segments that share the same class or
  2178.        group.
  2179.  
  2180.    ■   Fills in placeholders for offsets (relocatable addresses).
  2181.  
  2182.    ■   Writes relocations for segments into the header of .EXE files (but not
  2183.        .COM files).
  2184.  
  2185.    ■   Writes an executable image.
  2186.  
  2187.  
  2188.  Section 2.3.4, "Defining Segment Groups," defines classes and groups.
  2189.  Chapter 3, "Using Addresses and Pointers," explains segments and offsets.
  2190.  
  2191.  
  2192.  1.3.1.3  Loading
  2193.  
  2194.  The operating system loads the file generated by the linker into memory.
  2195.  When the executable file is loaded into memory, DOS
  2196.  
  2197.  
  2198.    ■   Reads the program segment prefix (PSP) header into memory.
  2199.  
  2200.    ■   Allocates memory for the program, based on the values in the PSP.
  2201.  
  2202.    ■   Loads the program.
  2203.  
  2204.    ■   Calculates the correct values for absolute addresses from the
  2205.        relocation table.
  2206.  
  2207.    ■   Loads the segment registers SS, CS, DS, and ES with values that point
  2208.        to the proper areas of memory.
  2209.  
  2210.    ■   Loads the instruction pointer (IP) to point to the start address in
  2211.        the code segment and the stack pointer (SP) to point to the stack.
  2212.  
  2213.    ■   Begins execution of the program.
  2214.  
  2215.  
  2216.  The process is similar for OS/2.
  2217.  
  2218.  See Section 1.2.7, "Registers," for information about segment registers, the
  2219.  instruction pointer (IP), and the stack pointer (SP). See MASM online help
  2220.  or a DOS reference for more information on the PSP.
  2221.  
  2222.  
  2223.  1.3.1.4  Running
  2224.  
  2225.  Your program is now ready to run. Some program operations cannot be handled
  2226.  until the program runs, such as resolving indirect memory operands. See
  2227.  Section 7.1.1.2, "Indirect Operands."
  2228.  
  2229.  
  2230.  1.3.2  Using the OPTION Directive
  2231.  
  2232.  The OPTION directive lets you modify global aspects of the assembly process.
  2233.  With OPTION, you can change command-line options and default arguments.
  2234.  These changes affect only statements that follow the use of OPTION.
  2235.  
  2236.  For example, you may have MASM code in which the first character of a
  2237.  variable, macro, structure, or field name is a dot (.). Since a leading dot
  2238.  causes MASM 6.0 to generate an error, you can use this statement in your
  2239.  program:
  2240.  
  2241.    OPTION DOTNAME
  2242.  
  2243.  This enables the use of the dot for the first character.
  2244.  
  2245.  Changes made with OPTION override any corresponding command-line option. For
  2246.  example, suppose you compile a module with this command line (which enables
  2247.  M510 compatibility):
  2248.  
  2249.    ML /Zm TEST.ASM
  2250.  
  2251.  but this statement is in the module:
  2252.  
  2253.    OPTION NOM510
  2254.  
  2255.  From this point on in the module, the M510 compatibility options are
  2256.  disabled.
  2257.  
  2258.  The lists below explain each of the arguments for the OPTION directive. You
  2259.  can put more than one OPTION statement on one line if you separate them by
  2260.  commas.
  2261.  
  2262.  
  2263.  Options for M510 Compatibility
  2264.  
  2265. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  2266.  Argument                          Description
  2267.  ────────────────────────────────────────────────────────────────────────────
  2268.  CASEMAP: maptype                  CASEMAP:NONE (or /Cx) causes internal
  2269.                                    symbol recognition to be case sensitive
  2270.  Argument                          Description
  2271.  ────────────────────────────────────────────────────────────────────────────
  2272.                                   symbol recognition to be case sensitive
  2273.                                    and causes the case of identifiers in
  2274.                                    the .OBJ file to be the same as
  2275.                                    specified in the
  2276.                                    EXTERNDEF, PUBLIC, or COMM statement.
  2277.                                    The default is CASEMAP:NOTPUBLIC (or
  2278.                                    /Cp). It specifies case insensitivity
  2279.                                    for internal symbol recognition and the
  2280.                                    same behavior as CASEMAP:NONE for case
  2281.                                    of identifiers in .OBJ files.
  2282.                                    CASEMAP:ALL (/Cu) specifies case
  2283.                                    insensitivity for identifiers and
  2284.                                    converts all identifier names to
  2285.                                    uppercase.
  2286.  
  2287.  DOTNAME | NODOTNAME               Enables the use of the dot (.) as the
  2288.                                    leading character in variable, macro,
  2289.                                    structure, union, and member names.
  2290.                                    NODOTNAME is the default.
  2291.  Argument                          Description
  2292.  ────────────────────────────────────────────────────────────────────────────
  2293.                                   NODOTNAME is the default.
  2294.  
  2295.  M510 | NOM510                     Sets all features to be compatible with
  2296.                                    MASM version 5.1, disabling the SCOPED
  2297.                                    argument and enabling OLDMACROS,
  2298.                                    DOTNAME, and, OLDSTRUCTS. OPTION M510
  2299.                                    conditionally sets other arguments for
  2300.                                    the OPTION directive. The default is
  2301.                                    NOM510. See Appendix A for more
  2302.                                    information on using OPTION M510.
  2303.  
  2304.  OLDMACROS | NOOLDMACROS           Enables the version 5.1 treatment of
  2305.                                    macros. MASM 6.0 treats macros
  2306.                                    differently. The default is NOOLDMACROS.
  2307.  
  2308.  
  2309.  
  2310.  OLDSTRUCTS | NOOLDSTRUCTS         Enables compatibility with MASM 5.1 for
  2311.                                    treatment of structure members. See
  2312.  Argument                          Description
  2313.  ────────────────────────────────────────────────────────────────────────────
  2314.                                   treatment of structure members. See
  2315.                                    Section 5.2 for information on
  2316.                                    structures.
  2317.  
  2318.  SCOPED | NOSCOPED                 Guarantees that all labels inside
  2319.                                    procedures are local to the procedure
  2320.                                    when SCOPED (the default) is enabled.
  2321.  
  2322.  
  2323.  
  2324.  
  2325.  Options for Procedure Use
  2326.  
  2327.  Argument                          Description
  2328.  ────────────────────────────────────────────────────────────────────────────
  2329.  LANGUAGE : langtype               Specifies the default language type (C,
  2330.                                    PASCAL, FORTRAN, BASIC, SYSCALL, or
  2331.                                    STDCALL) to be used with PROC, EXTERN,
  2332.                                    and PUBLIC. This use of the OPTION
  2333.                                    directive overrides the .MODEL directive
  2334.                                    but is normally used when .MODEL is not
  2335.                                    given.
  2336.  
  2337.  EPILOGUE: macroname               Instructs the assembler to call the
  2338.                                    macroname to generate a user-
  2339.                                    defined epilogue instead of the standard
  2340.                                    epilogue code when a RET instruction is
  2341.                                    encountered. See Section 7.3.8.
  2342.  
  2343.  PROLOGUE: macroname               Instructs the assembler to call
  2344.                                    macroname to generate a user-
  2345.                                    defined prologue instead of generating
  2346.                                    the standard prologue code. See Section
  2347.                                    7.3.8.
  2348.  
  2349.  PROC: visibility                  Allows the default visibility to be set
  2350.                                    explicitly. The default visibility is
  2351.                                    PUBLIC. The visibility can also be
  2352.                                    either EXPORT or PRIVATE.
  2353.  
  2354.  
  2355.  
  2356.  Other Options
  2357.  
  2358. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  2359.  Argument                          Description
  2360.  ────────────────────────────────────────────────────────────────────────────
  2361.  EXPR16 | EXPR32                   Sets the expression word size to 16 or
  2362.                                    32 bits. The default is 32 bits. The
  2363.                                    M510 argument to the OPTION directive
  2364.                                    sets the word size to 16 bits. Once set
  2365.                                    with the OPTION directive, the
  2366.                                    expression word size cannot be changed.
  2367.  
  2368.  EMULATOR | NOEMULATOR             Controls the generation of
  2369.                                    floating-point instructions. The
  2370.                                    NOEMULATOR option generates the
  2371.                                    coprocessor instructions directly. The
  2372.                                    EMULATOR option generates instructions
  2373.                                    with special fixup records for the
  2374.                                    linker so that the Microsoft
  2375.  Argument                          Description
  2376.  ────────────────────────────────────────────────────────────────────────────
  2377.                                   linker so that the Microsoft
  2378.                                    floating-point emulator, supplied with
  2379.                                    other Microsoft languages, can be used.
  2380.                                    It produces the same result as setting
  2381.                                    the /Fpi command-line option. You can
  2382.                                    set this option only once per module.
  2383.  
  2384.  LJMP | NOLJMP                     Enables automatic conditional-jump
  2385.                                    lengthening. The default is LJMP. See
  2386.                                    Section 7.1.2 for information about
  2387.                                    conditional-jump lengthening.
  2388.  
  2389.  NOKEYWORD:<keywordlist>           Disables the specified reserved words.
  2390.                                    See Section 1.2.1, "Reserved Words," for
  2391.                                    an example of the syntax for this
  2392.                                    argument.
  2393.  
  2394.  NOSIGNEXTEND                      Overrides the default sign-extended
  2395.                                    opcodes for the AND, OR, and XOR
  2396.  Argument                          Description
  2397.  ────────────────────────────────────────────────────────────────────────────
  2398.                                   opcodes for the AND, OR, and XOR
  2399.                                    instructions and generates the larger
  2400.                                    non-sign-extended forms of these
  2401.                                    instructions. Provided for compatibility
  2402.                                    with NEC V25 (R) and NEC V35(tm)
  2403.                                    controllers.
  2404.  
  2405.  OFFSET: offsettype                Determines the result of OFFSET operator
  2406.                                    fixups. SEGMENT sets the defaults for
  2407.                                    fixups to be segment-
  2408.                                    relative (compatible with MASM 5.1).
  2409.                                    GROUP, the default, generates fixups
  2410.                                    relative to the group (if the label is
  2411.                                    in a group). FLAT causes fixups to be
  2412.                                    relative to a flat frame. (The .386 mode
  2413.                                    must be enabled to use FLAT.) See
  2414.                                    Appendix A for more information.
  2415.  
  2416.  READONLY | NOREADONLY             Enables checking for instructions that
  2417.  Argument                          Description
  2418.  ────────────────────────────────────────────────────────────────────────────
  2419. READONLY | NOREADONLY             Enables checking for instructions that
  2420.                                    modify code segments, thereby
  2421.                                    guaranteeing that read-only code
  2422.                                    segments are not modified. Replaces the
  2423.                                    /p command-line option of MASM 5.1. It
  2424.                                    is useful for OS/2, where code segments
  2425.                                    are normally read-only.
  2426.  
  2427.  SEGMENT: segSize                  Allows global default segment size to be
  2428.                                    set. Also determines the default address
  2429.                                    size for external symbols defined
  2430.                                    outside any segment. The segSize can be
  2431.                                    USE16, USE32, or FLAT.
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  1.3.3  Conditional Directives
  2437.  
  2438.  MASM 6.0 provides conditional-assembly directives and conditional-error
  2439.  directives. You can also use conditional-assembly directives when you want
  2440.  to test for a specified condition and assemble a block of statements if the
  2441.  condition is true. You can use conditional-error directives when you want to
  2442.  test for a specified condition and generate an assembly error if the
  2443.  condition is true.
  2444.  
  2445.  Both kinds of conditional directives test assembly-time conditions, not
  2446.  run-time conditions. Only expressions that evaluate to constants during
  2447.  assembly can be compared or tested. Predefined symbols are often used in
  2448.  conditional assembly. See Section 1.2.3.
  2449.  
  2450.  
  2451.  Conditional-Assembly Directives
  2452.  
  2453.  The IF and ENDIF directives enclose the statements to be considered for
  2454.  conditional assembly. The optional ELSEIF and ELSE blocks follow the IF
  2455.  directive. There are many forms of the IF and ELSE directives. Online help
  2456.  provides a complete list.
  2457.  
  2458.  The syntax used for the IF directives is shown below. The syntax for other
  2459.  condition-assembly directives follow the same form.
  2460.  
  2461.    IF expression1
  2462.    ifstatements
  2463.    [[ELSEIF expression2
  2464.    elseifstatements]]
  2465.    [[ELSE
  2466.    elsestatements]]
  2467.    ENDIF
  2468.  
  2469.  
  2470.  
  2471.  The statements following the IF directive can be any valid statements,
  2472.  including other conditional blocks, which in turn can contain any number of
  2473.  ELSEIF blocks. ENDIF ends the block.
  2474.  
  2475.  The statements following the IF directive are assembled only if the
  2476.  corresponding condition is true. If the condition is not true and an ELSEIF
  2477.  directive is used, the assembler checks to see if the corresponding
  2478.  condition is true. If so, it assembles the statements following the ELSEIF
  2479.  directive. If no IF or ELSEIF conditions are satisfied, the statements
  2480.  following the ELSE directive are assembled.
  2481.  
  2482.  For example, you may want to assemble a line of code only if a particular
  2483.  variable has been defined. In this example,
  2484.  
  2485.    IFDEF   buffer
  2486.    buff    BYTE    buffer DUP(?)
  2487.            ENDIF
  2488.  
  2489.  buff  is allocated only if  buffer  has been previously defined.
  2490.  
  2491.  The following list summarizes the conditional-assembly directives:
  2492.  
  2493.  Directive                         Use
  2494.  ────────────────────────────────────────────────────────────────────────────
  2495.  IF and IFE                        Tests the value of an expression and
  2496.                                    allows
  2497.                                    assembly based on the result.
  2498.  
  2499.  IFDEF and IFNDEF                  Tests whether a symbol has been defined
  2500.                                    and allows assembly based on the result.
  2501.  
  2502.  IFB and IFNB                      Tests to see if a specified argument was
  2503.                                    passed to a macro and allows assembly
  2504.                                    based on the result.
  2505.  
  2506.  IFIDN and IFDIF                   Compares two macro arguments and allows
  2507.                                    assembly based on the result. (IFDIFI
  2508.                                    and IFIDNI perform the same action but
  2509.                                    are case insensitive.)
  2510.  
  2511.  
  2512.  
  2513.  
  2514.  
  2515.  Conditional-Error Directives
  2516.  
  2517.  You can use conditional-error directives to debug programs and check for
  2518.  assembly-time errors. By inserting a conditional-error directive at a key
  2519.  point in your code, you can test assembly-time conditions at that point. You
  2520.  can also use conditional-error directives to test for boundary conditions in
  2521.  macros.
  2522.  
  2523.  Like other severe errors, those generated by conditional-error directives
  2524.  cause the assembler to return a nonzero exit code. If a severe error is
  2525.  encountered during assembly, MASM does not generate the object module.
  2526.  
  2527.  For example, the .ERRNDEF directive produces an error if some label has not
  2528.  been defined. In this example, .ERRNDEF at the beginning of the conditional
  2529.  block makes sure that a  publevel  actually exists.
  2530.  
  2531.    .ERRNDEF    publevel
  2532.            IF          publevel LE 2
  2533.            PUBLIC      var1, var2
  2534.            ELSE
  2535.            PUBLIC      var1, var2, var3
  2536.            ENDIF
  2537.  
  2538.  These directives use the syntax given in the previous section. The following
  2539.  list summarizes the conditional-error directives.
  2540.  
  2541.  Directive                 Use
  2542.  ────────────────────────────────────────────────────────────────────────────
  2543.  .ERR                      Forces an error where the directives occur in
  2544.                            the source file. The error is generated
  2545.                            unconditionally when the directive is
  2546.                            encountered, but the directives can be placed
  2547.                            within conditional-assembly blocks to limit the
  2548.                            errors to certain situations.
  2549.  
  2550.  .ERRE and .ERRNZ          Tests the value of an expression and
  2551.                            conditionally generates an error based on the
  2552.                            result.
  2553.  
  2554.  .ERRDEF and               Tests whether a symbol is defined and
  2555.  .ERRNDEF                  conditionally generates an error based on the
  2556.                            result.
  2557.  
  2558.  .ERRB and .ERRNB          Tests whether a specified argument was passed to
  2559.                            a macro and conditionally generates an error
  2560.                            based on the result.
  2561.  
  2562.  .ERRIDN and               Compares two macro arguments and conditionally
  2563.  .ERRDIF                   generates an error based on the result. (
  2564.                            .ERRIDNI and .ERRDIFI perform the same action
  2565.                            but are case sensitive.)
  2566.  
  2567.  
  2568.  
  2569.  1.4  Related Topics in Online Help
  2570.  
  2571.  In addition to information covered in this chapter, information on the
  2572.  following topics can be found in online help.
  2573.  
  2574. ╓┌─────────────────────────────────────┌─────────────────────────────────────╖
  2575.  Topic                                 Access
  2576.  ────────────────────────────────────────────────────────────────────────────
  2577.  Predefined symbols                    From the "MASM 6.0 Contents" screen,
  2578.                                        choose "Predefined Symbols"
  2579.  
  2580.  Operator precedence                   From the list of tables on the "MASM
  2581.                                        6.0 Contents" screen, choose
  2582.                                        "Operator Precedence"
  2583.  
  2584.  Data types                            Choose "Directives" from the "MASM
  2585.  Topic                                 Access
  2586.  ────────────────────────────────────────────────────────────────────────────
  2587. Data types                            Choose "Directives" from the "MASM
  2588.                                        6.0 Contents" screen; then choose
  2589.                                        "Data Allocation" or "Complex Data
  2590.                                        Types" from the resulting screen
  2591.  
  2592.  Registers                             From the "MASM 6.0 Contents" screen,
  2593.                                        choose "Language Overview"; then
  2594.                                        choose "Processor Register Summary"
  2595.  
  2596.  Processor directives                  To see a table of directives, choose
  2597.                                        "Processor Selection" from the "MASM
  2598.                                        6.0 Contents" screen
  2599.  
  2600.  Conditional assembly and conditional  Choose "Directives" from the "MASM
  2601.  errors                                6.0 Contents" screen
  2602.  
  2603.  EVEN, ALIGN,                          From the "MASM 6.0 Contents" screen,
  2604.  OPTION                                choose "Directives," then
  2605.                                        "Miscellaneous"
  2606.  Topic                                 Access
  2607.  ────────────────────────────────────────────────────────────────────────────
  2608.                                       "Miscellaneous"
  2609.  
  2610.  Radix specifiers                      From the "MASM 6.0 Contents" screen,
  2611.                                        choose "Language Overview"
  2612.  
  2613.  ML command-line options               From the "Microsoft Advisor Contents"
  2614.                                        screen, choose "Macro Assembler"
  2615.                                        from the " Command Line" list
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  Chapter 2  Organizing MASM Segments
  2625.  ────────────────────────────────────────────────────────────────────────────
  2626.  
  2627.  A segment is a collection of instructions or data whose addresses are all
  2628.  relative to the same segment register. The code in your assembly-language
  2629.  program defines and organizes them.
  2630.  
  2631.  Segments can be defined by using simplified segment directives or full
  2632.  segment definitions. Section 2.2, "Using Simplified Segment Directives,"
  2633.  covers the directives you can use to begin, end, and organize segment
  2634.  program modules. It also discusses how to access far data and code with
  2635.  simplified segment directives.
  2636.  
  2637.  Section 2.3, "Using Full Segment Definitions," describes how to order,
  2638.  combine, and divide segments, as well as how to use the SEGMENT directive to
  2639.  define full segments. It also tells you how to create a segment group so
  2640.  that you can use just one segment address to access all the data.
  2641.  
  2642.  Most of the information in this chapter also applies to writing modules to
  2643.  be called from other programs. Exceptions are noted when they apply. See
  2644.  Chapter 8, "Sharing Data and Procedures among Modules and Libraries," for
  2645.  more information about multiple-module programming.
  2646.  
  2647.  
  2648.  2.1  Overview of Memory Segments
  2649.  
  2650.  A physical segment is an area of memory in which all locations are
  2651.  contiguous and share the same segment address. A segment always begins on a
  2652.  16-byte (paragraph) boundary (unless an alignment attribute is specified
  2653.  with ALIGN). While 16-bit segments can occupy up to 64K (kilobytes), 32-bit
  2654.  segments can be as large as 4 gigabytes.
  2655.  
  2656.  Segments reflect the architecture of the original 8086 processor. Prior to
  2657.  the 80386 processors and OS/2 2.x, assembly-language programming meant using
  2658.  segmented memory. A flat address space is now available on 80386/486
  2659.  processors in 32-bit mode. This space is still segmented at the hardware
  2660.  level, but it allows you to ignore most segmentation concerns.
  2661.  
  2662.  Segments provide a means for associating similar kinds of data. Most
  2663.  programs have segments for code, data, constant data, and the stack. These
  2664.  logical segments are allocated by the assembler at assembly time.
  2665.  
  2666.  You can define segments in two ways: with simplified segment directives and
  2667.  with full segment definitions. You can also use both kinds of segment
  2668.  definitions in the same program.
  2669.  
  2670.  Simplified segment directives are easier to use than full segment
  2671.  definitions.
  2672.  
  2673.  Simplified segment directives hide many of the details of segment definition
  2674.  and assume the same conventions used by Microsoft high-level languages. (See
  2675.  Section 2.2.) The simplified segment directives generate necessary code,
  2676.  specify segment attributes, and arrange segment order.
  2677.  
  2678.  Full segment definitions require more complex syntax but provide more
  2679.  complete control over how the assembler generates segments. (See Section
  2680.  2.3.) If you use full segment definitions, you must write code to handle all
  2681.  the tasks performed automatically by the simplified segment directives.
  2682.  
  2683.  
  2684.  2.2  Using Simplified Segment Directives
  2685.  
  2686.  Structuring a MASM program using simplified segments requires use of several
  2687.  directives to assign standard names, alignment, and attributes to the
  2688.  segments in your program. These directives define the segments in such a way
  2689.  that linking with Microsoft high-level languages is easy.
  2690.  
  2691.  The simplified segment directives are .MODEL, .CODE, .CONST, .DATA, .DATA?,
  2692.  .FARDATA, .FARDATA?, .STACK, .STARTUP, and .EXIT. These directives and the
  2693.  arguments they take are discussed in the following sections.
  2694.  
  2695.  The main module is where execution begins.
  2696.  
  2697.  MASM programs consist of modules made up of segments. Every program written
  2698.  only in MASM has one main module, where program execution begins. This main
  2699.  module can contain code, data, or stack segments defined with all of the
  2700.  simplified segment directives. Any additional modules should contain only
  2701.  code and data segments. Every module that uses simplified segments must,
  2702.  however, begin with the .MODEL directive.
  2703.  
  2704.  
  2705.  The following example shows the structure of a main module using simplified
  2706.  segment directives. It uses the default processor (8086), the default
  2707.  operating system (OS_DOS), and the default stack distance (NEARSTACK).
  2708.  Additional modules linked to this main program would use only the .MODEL,
  2709.  .CODE, and .DATA directives and the END statement.
  2710.  
  2711.    ; This is the structure of a main module
  2712.    ;  using simplified segment directives
  2713.  
  2714.            .MODEL small, c ; This statement is required before you
  2715.                            ;  can use other simplified segment
  2716.                            ;  directives
  2717.  
  2718.            .STACK          ; Use default 1-kilobyte stack
  2719.  
  2720.            .DATA           ; Begin data segment
  2721.  
  2722.                            ; Place data declarations here
  2723.  
  2724.            .CODE           ; Begin code segment
  2725.            .STARTUP        ; Generate start-up code
  2726.  
  2727.                            ; Place instructions here
  2728.  
  2729.            .EXIT           ; Generate exit code
  2730.            END
  2731.  
  2732.  A module must always finish with the END directive.
  2733.  
  2734.  The .DATA and .CODE statements do not require any separate statements to
  2735.  define the end of a segment. They close the preceding segment and then open
  2736.  a new segment. The .STACK directive opens and closes the stack segment but
  2737.  does not close the current segment. The END statement closes the last
  2738.  segment and marks the end of the source code. It must be at the end of every
  2739.  module, whether or not it is the main module.
  2740.  
  2741.  
  2742.  2.2.1  Defining Basic Attributes with .MODEL
  2743.  
  2744.  The .MODEL directive defines the attributes that affect the entire module:
  2745.  memory model, default calling and naming conventions, operating system, and
  2746.  stack type. This directive enables use of simplified segments and controls
  2747.  the name of the code segment and the default distance for procedures.
  2748.  
  2749.  You must place .MODEL in your source file before any other simplified
  2750.  segment directive. The syntax is
  2751.  
  2752.    .MODEL memorymodel «, modeloptions »
  2753.  
  2754.  The memorymodel field is required and must appear immediately after the
  2755.  .MODEL directive. The use of modeloptions, which define the other
  2756.  attributes, is optional. The modeloptions must be separated by commas. You
  2757.  can also use equates passed from the ML command line to define the
  2758.  modeloptions.
  2759.  
  2760.  The list below summarizes the memorymodel field and the modeloptions fields
  2761.  (language, operating system, and stack distance):
  2762.  
  2763.  Field                             Description
  2764.  ────────────────────────────────────────────────────────────────────────────
  2765.  Memory model                      TINY, SMALL, COMPACT, MEDIUM, LARGE,
  2766.                                    HUGE, or FLAT. Determines size of code
  2767.                                    and data pointers. This field is
  2768.                                    required.
  2769.  
  2770.  Language                          C, BASIC, FORTRAN, PASCAL, SYSCALL, or
  2771.                                    STDCALL. Sets calling and naming
  2772.                                    conventions for procedures and public
  2773.                                    symbols.
  2774.  
  2775.  Operating system                  OS_OS2 or OS_DOS. Determines behavior of
  2776.                                    .STARTUP and .EXIT.
  2777.  
  2778.  Stack distance                    NEARSTACK or FARSTACK. Specifying
  2779.                                    NEARSTACK groups the stack segment into
  2780.                                    a single physical segment (DGROUP) along
  2781.                                    with data. SS is assumed to equal DS.
  2782.                                    FARSTACK does not group the stack with
  2783.                                    DGROUP; thus SS does not equal DS.
  2784.  
  2785.  
  2786.  You can use no more than one reserved word from each field. The following
  2787.  examples show how you can combine various fields:
  2788.  
  2789.    .MODEL   small                  ; Small memory model
  2790.            .MODEL   large, c, farstack     ; Large memory model,
  2791.                                            ;  C conventions,
  2792.                                            ;  separate stack
  2793.            .MODEL   medium, pascal, os_os2 ; Medium memory model,
  2794.                                            ;  Pascal conventions,
  2795.                                            ;  OS/2 start-up/exit
  2796.  
  2797.  The next four sections give more detail on each field.
  2798.  
  2799.  
  2800.  Defining the Memory Model
  2801.  
  2802.  MASM supports the standard memory models used by Microsoft high-level
  2803.  languages─tiny, small, medium, compact, large, huge, and flat. You specify
  2804.  the memory model with attributes of the same name placed after the .MODEL
  2805.  directive. Your choice of a memory model does not limit the kind of
  2806.  instructions you can write. It does, however, control segment defaults and
  2807.  determine whether data and code are near or far by default (see Table 2.1).
  2808.  
  2809.  
  2810.  Table 2.1  Attributes of Memory Models
  2811.  
  2812. ╓┌─────────────┌─────────────┌─────────────┌────────────────┌────────────────╖
  2813.  Memory Model  Default Code  Default Data  Operating        Data and Code
  2814.                                            System           Combined
  2815.  ────────────────────────────────────────────────────────────────────────────
  2816.  Memory Model  Default Code  Default Data  Operating        Data and Code
  2817.                                            System           Combined
  2818.  ────────────────────────────────────────────────────────────────────────────
  2819.  Tiny          Near          Near          DOS              Yes
  2820.  
  2821.  Small         Near          Near          DOS, OS/2 1.x    No
  2822.  
  2823.  Medium        Far           Near          DOS, OS/2 1.x    No
  2824.  
  2825.  Compact       Near          Far           DOS, OS/2 1.x    No
  2826.  
  2827.  Large         Far           Far           DOS, OS/2 1.x    No
  2828.  
  2829.  Huge          Far           Far           DOS, OS/2 1.x    No
  2830.  
  2831.  Flat          Near          Near          OS/2 2.x         Yes
  2832.  
  2833.  ────────────────────────────────────────────────────────────────────────────
  2834.  
  2835.  
  2836.  
  2837.  When writing assembler modules for a high-level language, you should use the
  2838.  same memory model as the calling language. Generally, choose the smallest
  2839.  memory model available that can contain your data and code, since near
  2840.  references are more efficient than far references.
  2841.  
  2842.  The predefined symbol @Model returns the memory model. It encodes memory
  2843.  models as integers 1 through 7. See Section 1.2.3 for more information on
  2844.  predefined symbols, and see online help for an example of how to use them.
  2845.  
  2846.  The seven memory models supported by MASM 6.0 divide into three groups.
  2847.  
  2848.  Small, Medium, Compact, Large, and Huge Models - The traditional memory
  2849.  models recognized by many DOS and OS/2 1.x languages are small, medium,
  2850.  compact, large, and huge. Small model supports one data segment and one code
  2851.  segment. All data and code are near by default. Large model supports
  2852.  multiple code and multiple data segments. All data and code are far by
  2853.  default. Medium and compact models are in between. Medium model supports
  2854.  multiple code and single data segments; compact model supports multiple data
  2855.  segments and a single code segment.
  2856.  
  2857.  Huge model implies individual data items larger than a single segment, but
  2858.  the implementation of huge data items must be coded by the programmer. Since
  2859.  the assembler provides no direct support for this feature, huge model is
  2860.  essentially the same as large model.
  2861.  
  2862.  In each of these models, you can override the default. For example, you can
  2863.  make large data items far in small model, or internal procedures near in
  2864.  large model.
  2865.  
  2866.  Tiny Model - OS/2 does not support tiny model, but DOS does under MASM 6.0.
  2867.  This model places all data and code in a single segment. Therefore, the
  2868.  total program size can be no more than 64K. The default is near for code and
  2869.  static data items; you cannot override this default. However, you can
  2870.  allocate far data dynamically at run time using DOS memory allocation
  2871.  services.
  2872.  
  2873.  Tiny model produces DOS .COM files. Specifying  .MODEL tiny  automatically
  2874.  sends a /TINY to the linker. Therefore, /AT is not necessary with  .MODEL
  2875.  tiny. However, /AT does not insert a .MODEL directive. It only verifies that
  2876.  there are no base or pointer fixups, and sends /TINY to the linker.
  2877.  
  2878.  Flat Model - The flat memory model is a nonsegmented configuration available
  2879.  for 32-bit operating systems. It is similar to tiny model in that all code
  2880.  and data go in a single 32-bit segment.
  2881.  
  2882.  OS/2 2.x uses flat model when you specify the .386 or .486 directive before
  2883.  .MODEL FLAT. All data and code (including system resources) are in a single
  2884.  32-bit segment. Segment registers are initialized automatically at load
  2885.  time; the programmer needs to modify them only when mixing 16-bit and 32-bit
  2886.  segments in a single application. CS, DS, ES, and SS are all assumed to the
  2887.  supergroup FLAT. FS and GS are assumed to ERROR, since 32-bit versions of
  2888.  OS/2 reserve the use of these registers. Addresses and pointers passed to
  2889.  system services are always 32-bit near addresses and pointers. Although the
  2890.  theoretical size of the single flat segment is four gigabytes, OS/2 2.0
  2891.  actually limits it to 512 megabytes in flat model.
  2892.  
  2893.  
  2894.  Choosing the Language Convention
  2895.  
  2896.  The language type is most important when you write a mixed-language program.
  2897.  
  2898.  
  2899.  The language option facilitates compatibility with high-level languages by
  2900.  determining the internal encoding for external and public symbol names, the
  2901.  code generated for procedure initialization and cleanup, and the order that
  2902.  arguments are passed to a procedure with INVOKE. It also facilitates
  2903.  compatibility with high-level-language modules. The PASCAL, BASIC, and
  2904.  FORTRAN conventions are identical. C and SYSCALL have the same calling
  2905.  convention but different naming conventions. OS/2 system calls require the
  2906.  PASCAL calling convention for OS/2 1.x, but require the SYSCALL convention
  2907.  for OS/2 2.x. Specifying STDCALL for the calling convention enables a
  2908.  different calling convention and the same naming convention (see Section
  2909.  20.1).
  2910.  
  2911.  Procedure definitions (PROC) and high-level procedure calls (INVOKE)
  2912.  automatically generate code consistent with the calling convention of the
  2913.  specified language. The PROC, INVOKE, PUBLIC, and EXTERN directives all use
  2914.  the naming convention of the language. These directives follow the default
  2915.  language conventions from the .MODEL directive unless you specifically
  2916.  override the default. Chapter 7, "Controlling Program Flow," tells how to
  2917.  use these directives. You can also use the OPTION directive to set the
  2918.  language type. (See Section 1.3.2.) Not specifying a language type in either
  2919.  the .MODEL, OPTION, EXTERN, PROC, INVOKE, or PROTO statement causes the
  2920.  assembler to generate an error.
  2921.  
  2922.  The predefined symbol @Interface provides information about the language
  2923.  parameters. See online help for a description of the bit flags.
  2924.  
  2925.  See Chapter 20, "Mixed-Language Programming," for more information on
  2926.  calling and naming conventions. See Chapter 7, "Controlling Program Flow,"
  2927.  for information about writing procedures and prototypes. See Chapter 8,
  2928.  "Sharing Data and Procedures among Modules and Libraries," for information
  2929.  on multiple-module programming.
  2930.  
  2931.  
  2932.  Specifying the Operating System
  2933.  
  2934.  The operating-system options (OS_DOS or OS_OS2) are arguments of .MODEL.
  2935.  They specify the start-up and exit code generated by the .STARTUP and .EXIT
  2936.  directives. (See Section 2.2.6.) If you do not use .STARTUP and .EXIT, you
  2937.  can omit this option. The default is OS_DOS.
  2938.  
  2939.  
  2940.  Setting the Stack Distance
  2941.  
  2942.  The NEARSTACK setting places the stack segment in a group, DGROUP, shared
  2943.  with data. The .STARTUP directive then generates code to adjust SS:SP so
  2944.  that SS (Stack Segment register) holds the same address as DS (Data Segment
  2945.  register). If you do not use .STARTUP, you must make this adjustment
  2946.  yourself or your program may fail to run. (See Section 2.2.6 for information
  2947.  about start-up code.) In this case, you can use DS to access stack items
  2948.  (including parameters and local variables) and SS to access near data.
  2949.  Furthermore, since stack items share the same segment address as near data,
  2950.  you can reliably pass near pointers to stack items.
  2951.  
  2952.  Having SS equal to DS gives some programming advantages.
  2953.  
  2954.  The FARSTACK setting gives the stack a segment of its own. That is, SS does
  2955.  not equal DS. The default stack type, NEARSTACK, is a convenient setting for
  2956.  most programs. Use FARSTACK for special cases such as memory-resident
  2957.  programs and dynamic-link libraries (DLLs) when you cannot assume that the
  2958.  caller's stack is near.
  2959.  
  2960.  The stack specification also affects the ASSUME statement generated by
  2961.  .MODEL and .STACK. You can use the predefined symbol @Stack to determine if
  2962.  the stack location is DGROUP (for near stacks) or STACK (for far stacks).
  2963.  
  2964.  
  2965.  2.2.2  Specifying a Processor and Coprocessor
  2966.  
  2967.  MASM supports a set of directives for selecting processors and coprocessors.
  2968.  Once you select a processor, you must use only the instruction set available
  2969.  for that processor. The default is the 8086 processor. If you always want
  2970.  your code to run on this processor, you do not need to add any processor
  2971.  directives.
  2972.  
  2973.  To enable a different processor mode and the additional instructions
  2974.  available on that processor, use the directives .186, .286, .386, and .486.
  2975.  
  2976.  
  2977.  The .286P, .386P, and .486P directives enable the instructions available
  2978.  only at higher privilege levels in addition to the normal instruction set
  2979.  for the given processor. Privileged instructions are not necessary for
  2980.  writing applications, even for OS/2. Generally, you don't need privileged
  2981.  instructions unless you are writing operating-systems code or device
  2982.  drivers.
  2983.  
  2984.  Processor directives affect availability of various MASM language features.
  2985.  
  2986.  
  2987.  In addition to enabling different instruction sets, the processor directives
  2988.  also affect the behavior of extended language features. For example, the
  2989.  INVOKE directive pushes arguments onto the stack. If the .286 directive is
  2990.  in effect, INVOKE takes advantage of operations possible only on 80286 and
  2991.  later processors.
  2992.  
  2993.  Use the directives .8087 (the default), .287, .387, and .NO87 to select a
  2994.  math coprocessor instruction set. The .NO87 directive turns off assembly of
  2995.  all coprocessor instructions. Note that .486 also enables assembly of all
  2996.  coprocessor instructions because the 80486 processor has a complete set of
  2997.  coprocessor registers and instructions built into the chip. The processor
  2998.  instructions imply the corresponding coprocessor directive. The coprocessor
  2999.  directives are provided to override the defaults.
  3000.  
  3001.  
  3002.  2.2.3  Creating a Stack
  3003.  
  3004.  The stack is the section of memory used for pushing or popping registers and
  3005.  storing the return address when a subroutine is called. The stack often
  3006.  holds temporary and local variables.
  3007.  
  3008.  If your main module is written in a high-level language, that language
  3009.  handles the details of creating a stack. Use the .STACK directive only when
  3010.  you write a main module in assembly language.
  3011.  
  3012.  The .STACK directive creates a stack segment. By default, the assembler
  3013.  allocates 1K of memory for the stack. This size is sufficient for most small
  3014.  programs.
  3015.  
  3016.  To create a stack of a size other than the default size, give .STACK a
  3017.  single numeric argument indicating stack size in bytes:
  3018.  
  3019.    .STACK  2048            ; Use 2K stack
  3020.  
  3021.  For a description of how stack memory is used with procedure calls and local
  3022.  variables, see Chapter 7, "Controlling Program Flow."
  3023.  
  3024.  
  3025.  2.2.4  Creating Data Segments
  3026.  
  3027.  Programs can contain both near and far data. In general, you should place
  3028.  important and frequently used data in the near data area, where data access
  3029.  is faster. This area can get crowded, however, because (in 16-bit operating
  3030.  systems) the total amount of all near data in all modules cannot exceed 64K.
  3031.  Therefore, you may want to place infrequently used or particularly large
  3032.  data items in a far data segment.
  3033.  
  3034.  The .DATA, .DATA?, .CONST, .FARDATA, and .FARDATA? directives create data
  3035.  segments. You can access the various segments within DGROUP without
  3036.  reloading segment registers (see Section 2.3.4, "Defining Segment Groups").
  3037.  These four directives also prevent instructions from appearing in data
  3038.  segments by assuming CS to ERROR. (See Section 2.3.3 for information about
  3039.  ASSUME.)
  3040.  
  3041.  
  3042.  Near Data Segments
  3043.  
  3044.  The .DATA directive creates a near data segment. This segment contains the
  3045.  frequently used data for your program. It can occupy up to 64K in DOS or 512
  3046.  megabytes under flat model in OS/2 2.0. It is placed in a special group
  3047.  identified as DGROUP, which is also limited to 64K.
  3048.  
  3049.  Near data pointers always point to DGROUP.
  3050.  
  3051.  When you use .MODEL, the assembler automatically defines DGROUP for your
  3052.  near data segment. The segments in DGROUP form near data, which can normally
  3053.  be accessed directly through DS or SS.
  3054.  
  3055.  You can also define the .DATA? and .CONST segments that go into DGROUP
  3056.  unless you are using flat model. Although all of these segments (along with
  3057.  the stack) are eventually grouped together and handled as data segments,
  3058.  .DATA? and .CONST enhance compatibility with Microsoft high-level languages.
  3059.  In Microsoft languages, .CONST is used for defining constant data such as
  3060.  strings and floating-point numbers that must be stored in memory. The .DATA?
  3061.  segment is used for storing uninitialized variables. You can follow this
  3062.  convention if you wish. If you use C start-up code, .DATA? is initialized to
  3063.  0.
  3064.  
  3065.  You can use @data to determine the group of the data segment and @DataSize
  3066.  to determine the size of the memory model set by the .MODEL directive. The
  3067.  predefined symbols @WordSize and @CurSeg return the size attribute and name
  3068.  of the current segment, respectively. See Section 1.2.3, "Predefined
  3069.  Symbols."
  3070.  
  3071.  
  3072.  Far Data Segments
  3073.  
  3074.  The compact, large, and huge memory models use far data addresses by
  3075.  default. With these memory models, however, you can still use .DATA, .DATA?,
  3076.  and .CONST to create data segments. The effect of these directives does not
  3077.  change from one memory model to the next. They always contribute segments to
  3078.  the default data area, DGROUP, which has a total limit of 64K.
  3079.  
  3080.  
  3081.  When you use .FARDATA or .FARDATA? in the small and medium memory models,
  3082.  the assembler creates far data segments FAR_DATA and FAR_BSS, respectively.
  3083.  You can access variables with:
  3084.  
  3085.    mov     ax, SEG farvar2
  3086.            mov     ds, ax
  3087.  
  3088.  See Section 3.1.2 for more information on far data.
  3089.  
  3090.  
  3091.  2.2.5  Creating Code Segments
  3092.  
  3093.  Whether you are writing a main module or a module to be called from another
  3094.  module, you can have both near and far code segments. This section explains
  3095.  how to use near and far code segments and how to use the directives and
  3096.  predefined equates that relate to code segments.
  3097.  
  3098.  
  3099.  Near Code Segments
  3100.  
  3101.  The small memory model is often the best choice for assembly programs that
  3102.  are not linked to modules in other languages, especially if you do not need
  3103.  more than 64K of code. This memory model defaults to near (two-byte)
  3104.  addresses for code and data, which makes the program run faster and use less
  3105.  memory.
  3106.  
  3107.  When you use .MODEL and simplified segment directives, the .CODE directive
  3108.  in your program instructs the assembler to start a code segment. The next
  3109.  segment directive closes the previous segment; the END directive at the end
  3110.  of your program closes remaining segments. The example at the beginning of
  3111.  Section 2.2, "Using Simplified Segment Directives," shows how to do this.
  3112.  
  3113.  You can use the predefined symbol @CodeSize to determine whether code
  3114.  pointers default to NEAR or FAR.
  3115.  
  3116.  
  3117.  Far Code Segments
  3118.  
  3119.  When you need more than 64K of code, use the medium, large, or huge memory
  3120.  model to create far segments.
  3121.  
  3122.  The medium, large, and huge memory models use far code addresses by default.
  3123.  In the larger memory models, the assembler creates a different code segment
  3124.  for each module. If you use multiple code segments in the small, compact, or
  3125.  tiny model, the linker combines the .CODE segments for all modules into one
  3126.  segment.
  3127.  
  3128.  The assembler assigns names to code segments.
  3129.  
  3130.  For far code segments, the assembler names each code segment MODNAME_TEXT,
  3131.  in which MODNAME is the name of the module. With near code, the assembler
  3132.  names every code segment _TEXT, causing the linker to concatenate these
  3133.  segments into one. You can override the default name by providing an
  3134.  argument after .CODE. (See Appendix E, "Default Segment Names," for a
  3135.  complete list of segment names generated by MASM.)
  3136.  
  3137.  With far code, a single module can contain multiple code segments. The .CODE
  3138.  directive takes an optional text argument that names the segment. For
  3139.  instance, the example below creates two distinct code segments, FIRST_TEXT
  3140.  and SECOND_TEXT.
  3141.  
  3142.    .CODE   FIRST
  3143.            .
  3144.            .       ; First set of instructions here
  3145.            .
  3146.            .CODE   SECOND
  3147.            .
  3148.            .       ; Second set of instructions here
  3149.            .
  3150.  
  3151.  Whenever the processor executes a far call or jump, it loads CS with the new
  3152.  segment address. No special action is necessary other than making sure that
  3153.  you use far calls and jumps. See Section 3.1.2, "Near and Far Addresses."
  3154.  
  3155.  ────────────────────────────────────────────────────────────────────────────
  3156.  NOTE
  3157.  The ASSUME directive is never necessary when you change code segments. In
  3158.  MASM 6.0, the assembler always assumes that the CS register contains the
  3159.  address of the current code segment or group. See Section 2.3.3 for more
  3160.  information about ASSUME used with segment registers.
  3161.  ────────────────────────────────────────────────────────────────────────────
  3162.  
  3163.  
  3164.  2.2.6  Starting and Ending Code with .STARTUP and .EXIT
  3165.  
  3166.  The easiest way to begin and end a program is to use the .STARTUP and .EXIT
  3167.  directives in the main module. The main module contains the starting point
  3168.  and usually the termination point. You do not need these directives in a
  3169.  module called by another module.
  3170.  
  3171.  .STARTUP generates the start-up code required by either DOS or OS/2.
  3172.  
  3173.  These directives make programs easy to maintain. They automatically generate
  3174.  code appropriate to the operating system and stack types specified with
  3175.  .MODEL. Thus, you can specify the program is for a different operating
  3176.  system or stack type by altering keywords in the .MODEL directive.
  3177.  
  3178.  To start a program, place the .STARTUP directive where you want execution to
  3179.  begin. Usually, this location immediately follows the .CODE directive:
  3180.  
  3181.    .CODE
  3182.            .STARTUP
  3183.            .
  3184.            .       ; Place executable code here
  3185.            .
  3186.            .EXIT
  3187.            END
  3188.  
  3189.  Note that .EXIT generates executable code, while END does not. The END
  3190.  directive informs the assembler that it has reached the end of the module.
  3191.  All modules must end with the END directive whether you use simplified or
  3192.  full segments.
  3193.  
  3194.  If you do not use .STARTUP, you must give the starting address as an
  3195.  argument to the END directive. When .STARTUP is present, the assembler
  3196.  ignores any argument to END.
  3197.  
  3198.  The code generated by .STARTUP depends on the operating system specified
  3199.  after .MODEL.
  3200.  
  3201.  If your program uses DOS for its operating system (the default), the
  3202.  initialization code sets DS to DGROUP, and adjusts SS:SP so that it is
  3203.  relative to the group for near data, DGROUP. To initialize a DOS program
  3204.  with the default NEARSTACK attribute, .STARTUP generates the following code:
  3205.  
  3206.  
  3207.    @Startup:
  3208.            mov     dx, DGROUP
  3209.            mov     ds, dx
  3210.            mov     bx, ss
  3211.            sub     bx, dx
  3212.            shl     bx, 1   ; If .286 or higher, this is
  3213.            shl     bx, 1   ;  shortened to shl bx, 4
  3214.            shl     bx, 1
  3215.            shl     bx, 1
  3216.            cli             ; Not necessary in .286 or higher
  3217.            mov     ss, dx
  3218.            add     sp, bx
  3219.            sti             ; Not necessary in .286 or higher
  3220.            .
  3221.            .
  3222.            .
  3223.            END     @Startup
  3224.  
  3225.  A DOS program with the FARSTACK attribute does not need to adjust SS:SP, so
  3226.  it just initializes DS:
  3227.  
  3228.    @Startup:
  3229.           mov     dx, DGROUP
  3230.           mov     ds, dx
  3231.           .
  3232.           .
  3233.           .
  3234.           END     @Startup
  3235.  
  3236.  OS/2 initializes DS so that it points to DGROUP and sets SS:SP as desired.
  3237.  Thus, when the OS_OS2 attribute is given, .STARTUP generates only a starting
  3238.  address. This does not show up in the listing file, however, since the /Sg
  3239.  option for listing files shows only the generated instructions.
  3240.  
  3241.  When the program terminates, you can return an exit code to the operating
  3242.  system. Applications that check exit codes usually assume that an exit code
  3243.  of 0 means no problem occurred and that 1 means an error terminated the
  3244.  program. The .EXIT directive accepts the exit code as its one optional
  3245.  argument:
  3246.  
  3247.    .EXIT   1       ; Return exit code 1
  3248.  
  3249.  This directive generates a DOS interrupt or OS/2 system call, depending on
  3250.  the operating system specified in .MODEL. The code generated under DOS
  3251.  depends on the argument provided to .EXIT. One example is
  3252.  
  3253.    mov     al, value
  3254.            mov     ah, 04Ch
  3255.            int     21h
  3256.  
  3257.  if a return value is specified. The return value can be a constant, a memory
  3258.  reference, or a register that can be moved into the AL register. If no
  3259.  return value is specified, the first line in the example code above is not
  3260.  generated.
  3261.  
  3262.  For OS/2, .EXIT invokes DosExit if you provide a prototype for DosExit and
  3263.  if you include OS2.LIB. The listing file shows the statements generated by
  3264.  INVOKE if the /Sg command-line option is specified. If you specify a return
  3265.  value as an expression, the code generated passes the expression instead of
  3266.  the register contents to the DosExit function. See Chapter 17 for
  3267.  information on writing programs for OS/2.
  3268.  
  3269.  
  3270.  2.3  Using Full Segment Definitions
  3271.  
  3272.  If you need complete control over segments, you can fully define the
  3273.  segments in your program. This section explains segment definitions,
  3274.  including how to order segments and how to define the segment types.
  3275.  
  3276.  If you write a program under DOS without .MODEL and .STARTUP, you must
  3277.  initialize registers yourself and use the END directive to indicate the
  3278.  starting address. Under OS/2 you do not have to initialize registers.
  3279.  Section 2.3.2, "Controlling the Segment Order," describes typical start-up
  3280.  code.
  3281.  
  3282.  
  3283.  2.3.1  Defining Segments with the SEGMENT Directive
  3284.  
  3285.  The SEGMENT directive begins a segment, and the ENDS directive ends a
  3286.  segment:
  3287.  
  3288.    name SEGMENT «align» «READONLY»
  3289.    «combine» «use» «'class'»
  3290.    statements
  3291.    name ENDS
  3292.  
  3293.  The name defines the name of the segment. Within a module, all segment
  3294.  definitions with the same name are treated as though they reference the same
  3295.  segment. The linker also combines identically named segments from different
  3296.  modules unless the combine type is PRIVATE. In addition, segments can be
  3297.  nested.
  3298.  
  3299.  Options used with the SEGMENT directive can be in any order.
  3300.  
  3301.  The optional types that follow the SEGMENT directive give the linker and the
  3302.  assembler instructions on how to set up and combine segments. The list below
  3303.  summarizes these types; the following sections explain them in more detail.
  3304.  
  3305.  
  3306.  Type                              Description
  3307.  ────────────────────────────────────────────────────────────────────────────
  3308.  align                             Defines the memory boundary on which a
  3309.                                    new segment begins.
  3310.  
  3311.  READONLY                          Tells the assembler to report an error
  3312.                                    if it detects an instruction modifying
  3313.                                    any item in a
  3314.                                    READONLY segment.
  3315.  
  3316.  combine                           Determines how the linker combines
  3317.                                    segments from different modules when
  3318.                                    building executable files.
  3319.  
  3320.  use (80386/486 only)              Determines the size of a segment. USE16
  3321.                                    indicates that offsets in the segment
  3322.                                    are 16 bits wide. USE32 indicates 32-bit
  3323.                                    offsets.
  3324.  
  3325.  class                             Provides a class name for the segment.
  3326.                                    The linker automatically groups segments
  3327.                                    of the same class in memory.
  3328.  
  3329.  
  3330.  Types can be specified in any order. You can specify only one attribute from
  3331.  each of these fields; for example, you cannot have two different align
  3332.  types.
  3333.  
  3334.  Once you define a segment, you can reopen it later with another SEGMENT
  3335.  directive. When you reopen a segment, you need only give the segment name.
  3336.  
  3337.  ────────────────────────────────────────────────────────────────────────────
  3338.  NOTE
  3339.  
  3340.  The PAGE align type and the PUBLIC combine type are distinct from the PAGE
  3341.  and PUBLIC directives. The assembler distinguishes them by means of context.
  3342.  ────────────────────────────────────────────────────────────────────────────
  3343.  
  3344.  
  3345.  Aligning Segments
  3346.  
  3347.  The optional align type in the SEGMENT directive defines the range of memory
  3348.  addresses from which a starting address for the segment can be selected. The
  3349.  align type can be any one of these:
  3350.  
  3351.  Align Type                        Starting Address
  3352.  ────────────────────────────────────────────────────────────────────────────
  3353.  BYTE                              Next available byte address.
  3354.  
  3355.  WORD                              Next available word address.
  3356.  
  3357.  DWORD                             Next available doubleword address.
  3358.  
  3359.  PARA                              Next available paragraph address (16
  3360.                                    bytes per paragraph). Default.
  3361.  
  3362.  PAGE                              Next available page address (256 bytes
  3363.                                    per page).
  3364.  
  3365.  
  3366.  The linker uses the alignment information to determine the relative starting
  3367.  address for each segment. The operating system calculates the actual
  3368.  starting address when the program is loaded.
  3369.  
  3370.  
  3371.  Making Segments Read-Only
  3372.  
  3373.  The optional READONLY attribute is helpful when creating read-only code
  3374.  segments for protected mode or when writing code to be placed in read-only
  3375.  memory (ROM). It protects against illegal self-modifying code.
  3376.  
  3377.  The READONLY attribute causes the assembler to check for instructions that
  3378.  modify the segment and to generate an error if it finds any. The assembler
  3379.  generates an error if you attempt to write directly to a read-only segment.
  3380.  
  3381.  
  3382.  
  3383.  Combining Segments
  3384.  
  3385.  The optional combine type in the SEGMENT directive defines how the linker
  3386.  combines segments having the same name but appearing in different modules.
  3387.  The combine type controls linker behavior, not assembler behavior. The
  3388.  combine types are described in full detail in online help and are summarized
  3389.  below.
  3390.  
  3391. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  3392.  Combine Type                      Linker Action
  3393.  ────────────────────────────────────────────────────────────────────────────
  3394.  PRIVATE                           Does not combine the segment with
  3395.                                    segments from other modules, even if
  3396.                                    they have the same name.
  3397.                                    Default.
  3398.  
  3399.  PUBLIC                            Concatenates all segments having the
  3400.                                    same name to form a single, contiguous
  3401.                                    segment.
  3402.  
  3403.  STACK                             Concatenates all segments having the
  3404.  Combine Type                      Linker Action
  3405.  ────────────────────────────────────────────────────────────────────────────
  3406. STACK                             Concatenates all segments having the
  3407.                                    same name and causes the operating
  3408.                                    system to set SS:00 to the bottom and
  3409.                                    SS:SP to the top of the resulting
  3410.                                    segment. Data initialization is
  3411.                                    unreliable, as discussed below.
  3412.  
  3413.  COMMON                            Overlaps segments. The length of the
  3414.                                    resulting area is the length of the
  3415.                                    largest of the combined segments. Data
  3416.                                    initialization is unreliable, as
  3417.                                    discussed below.
  3418.  
  3419.  MEMORY                            Used as a synonym for the PUBLIC combine
  3420.                                    type.
  3421.  
  3422.  AT address                        Assumes address as the segment location.
  3423.                                    An AT segment cannot contain any code or
  3424.                                    initialized data, but it is useful for
  3425.  Combine Type                      Linker Action
  3426.  ────────────────────────────────────────────────────────────────────────────
  3427.                                   initialized data, but it is useful for
  3428.                                    defining structures or variables that
  3429.                                    correspond to specific far memory
  3430.                                    locations, such as a screen buffer or
  3431.                                    low memory.
  3432.                                    The AT combine type cannot be used in
  3433.                                    protected-mode programs.
  3434.  
  3435.  
  3436.  
  3437.  Do not place initialized data in STACK or COMMON segments. With these
  3438.  combine types, the linker overlays initialized data for each module at the
  3439.  beginning of the segment. The last module containing initialized data writes
  3440.  over any data from other modules.
  3441.  
  3442.  ────────────────────────────────────────────────────────────────────────────
  3443.  NOTE
  3444.  
  3445.  Normally, you should provide at least one stack segment (having STACK
  3446.  combine type) in a program. If no stack segment is declared, LINK displays a
  3447.  warning message. You can ignore this message if you have a specific reason
  3448.  for not declaring a stack segment. For example, you would not have a
  3449.  separate stack segment in a DOS tiny model (.COM) program, nor would you
  3450.  need a separate stack in a DLL library that used the caller's stack.
  3451.  ────────────────────────────────────────────────────────────────────────────
  3452.  
  3453.  
  3454.  Setting Segment Word Sizes (80386/486 Only)
  3455.  
  3456.  The use type in the SEGMENT directive specifies the segment word size on the
  3457.  80386/486 processors. Segment word size determines the default operand and
  3458.  address size of all items in a segment.
  3459.  
  3460.  The 80386/486 can operate in 16-bit or 32-bit mode.
  3461.  
  3462.  The size attribute can be USE16, USE32, or FLAT. If the 80386 or 80486
  3463.  processor has been selected with the .386 or .486 directive, and this
  3464.  directive precedes .MODEL, then USE32 is the default. This attribute
  3465.  specifies that items in the segment are addressed with a 32-bit offset
  3466.  rather than a 16-bit offset. If .MODEL precedes the .386 or .486 directive,
  3467.  USE16 is the default. To make USE32 the default, put .386 or .486 before
  3468.  .MODEL. You can override the USE32 default with the USE16 attribute.
  3469.  
  3470.  
  3471.  ────────────────────────────────────────────────────────────────────────────
  3472.  NOTE
  3473.  Mixing 16-bit and 32-bit segments in the same program is possible but
  3474.  usually is necessary only in systems programming.
  3475.  ────────────────────────────────────────────────────────────────────────────
  3476.  
  3477.  
  3478.  Setting Segment Order with Class Type
  3479.  
  3480.  Segments of the same class are grouped together in the executable file.
  3481.  
  3482.  The optional class type in the SEGMENT directive helps control segment
  3483.  ordering. Two segments with the same name are not combined if their class is
  3484.  different. The linker arranges segments so that all segments identified with
  3485.  a given class type are next to each other in the executable file. However,
  3486.  within a particular class, the linker orders segments in the order
  3487.  encountered. The .ALPHA, .SEQ, or .DOSSEG directive determines this order in
  3488.  each .OBJ file. The most common application for specifying a class type is
  3489.  to place all code segments first in the executable file.
  3490.  
  3491.  
  3492.  2.3.2  Controlling the Segment Order
  3493.  
  3494.  The assembler normally positions segments in the object file in the order in
  3495.  which they appear in source code. The linker, in turn, processes object
  3496.  files in the order in which they appear on the command line. Within each
  3497.  object file, the linker outputs segments in the order they appear, subject
  3498.  to any group, class, and .DOSSEG requirements.
  3499.  
  3500.  You can usually ignore segment ordering. However, it is important whenever
  3501.  you want certain segments to appear at the beginning or end of a program or
  3502.  when you make assumptions about which segments are next to each other in
  3503.  memory. For tiny model (.COM) programs, code segments must appear first in
  3504.  the executable file, because execution must start at the address 100h.
  3505.  
  3506.  
  3507.  Segment Order Directives
  3508.  
  3509.  You can control the order in which segments appear in the executable program
  3510.  with three directives. The default, .SEQ, arranges segments in the order in
  3511.  which they are declared.
  3512.  
  3513.  The .ALPHA directive specifies alphabetical segment ordering within a
  3514.  module. .ALPHA is provided for compatibility with early versions of the IBM
  3515.  assembler. If you have trouble running code from older books on assembly
  3516.  language, try using .ALPHA.
  3517.  
  3518.  The .DOSSEG directive specifies the DOS segment-ordering convention. It
  3519.  places segments in the standard order required by Microsoft languages. Do
  3520.  not use .DOSSEG in a module to be called from another module.
  3521.  
  3522.  The .DOSSEG directive orders segments in this order:
  3523.  
  3524.  
  3525.    1.  Code segments
  3526.  
  3527.    2.  Data segments, in this order:
  3528.  
  3529.        a.  Segments not in class BSS or STACK
  3530.  
  3531.        b.  Class BSS segments
  3532.  
  3533.        c.  Class STACK segments
  3534.  
  3535.  
  3536.  
  3537.  When you declare two or more segments to be in the same class, the linker
  3538.  automatically makes them contiguous. This rule overrides the
  3539.  segment-ordering directives. (See "Setting Segment Order with Class Type" in
  3540.  the previous section for more about segment classes.)
  3541.  
  3542.  
  3543.  Linker Control
  3544.  
  3545.  Most of the segment-ordering techniques (class names, .ALPHA, .SEQ) control
  3546.  the order in which the assembler outputs segments. Usually, you are more
  3547.  interested in the order in which segments appear in the executable file. The
  3548.  linker controls this order.
  3549.  
  3550.  The linker processes object files in the order in which they appear on the
  3551.  command line. Within each module, it then outputs segments in the order
  3552.  given in the object file. If the first module defines segments DSEG and
  3553.  STACK and the second module defines CSEG, then CSEG is output last. If you
  3554.  want to place CSEG first, there are two ways to do so.
  3555.  
  3556.  .DOSSEG handles segment ordering.
  3557.  
  3558.  The simpler method is to use .DOSSEG. This directive is output as a special
  3559.  record to the object file linker, and it tells the linker to use the
  3560.  Microsoft segment-ordering convention. This convention overrides
  3561.  command-line order of object files, and it places all segments of class
  3562.  'CODE'  first. (See Section 2.3.1, "Defining Segments with the SEGMENT
  3563.  Directive.")
  3564.  
  3565.  The other method is to define all the segments as early as possible (in an
  3566.  include file, for example, or in the first module). These definitions can be
  3567.  "dummy segments"─that is, segments with no content. The linker observes the
  3568.  segment ordering given, then later combines the empty segments with segments
  3569.  in other modules that have the same name.
  3570.  
  3571.  For example, you might include the following at the start of the first
  3572.  module of your program or in an include file:
  3573.  
  3574.    _TEXT   SEGMENT WORD PUBLIC 'CODE'
  3575.    _TEXT   ENDS
  3576.    _DATA   SEGMENT WORD PUBLIC 'DATA'
  3577.    _DATA   ENDS
  3578.    CONST   SEGMENT WORD PUBLIC 'CONST'
  3579.    CONST   ENDS
  3580.    STACK   SEGMENT PARA STACK 'STACK'
  3581.    STACK   ENDS
  3582.  
  3583.  Later in the program, the order in which you write  _TEXT,  _DATA, or other
  3584.  segments does not matter because the ultimate order is controlled by the
  3585.  segment order defined in the include file.
  3586.  
  3587.  
  3588.  2.3.3  Setting the ASSUME Directive for Segment Registers
  3589.  
  3590.  Many of the assembler instructions assume a default segment. For example,
  3591.  JMP assumes the segment associated with the CS register, PUSH and POP assume
  3592.  the segment associated with the SS register, and MOV instructions assume the
  3593.  segment associated with the DS register.
  3594.  
  3595.  
  3596.  The assembler must know the location of segment addresses.
  3597.  
  3598.  When the assembler needs to reference an address, it must know what segment
  3599.  contains the address. It finds this by using the default segment or group
  3600.  addresses assigned with the ASSUME directive. The syntax is
  3601.  
  3602.    ASSUME  segregister:seglocation [[,segregister:seglocation]]
  3603.    ASSUME  dataregister:qualifiedtype [[,dataregister:qualifiedtype]]
  3604.    ASSUME  register:ERROR [[,register:ERROR]]
  3605.    ASSUME  [[register:»NOTHING
  3606.    [[, register: NOTHING]]
  3607.  
  3608.  The seglocation must be the name of the segment or group that is to be
  3609.  associated with segregister. Subsequent instructions that assume a default
  3610.  register for referencing labels or variables automatically assume that if
  3611.  the default segment is segregister, the label or variable is in the
  3612.  seglocation. Beginning with MASM 6.0, the assembler automatically sets CS to
  3613.  have the address of the current code segment. Therefore, you do not need to
  3614.  include
  3615.  
  3616.    ASSUME CS : MY_CODE
  3617.  
  3618.  at the beginning of your program if you want the current segment associated
  3619.  with CS.
  3620.  
  3621.  ────────────────────────────────────────────────────────────────────────────
  3622.  NOTE
  3623.  Using the ASSUME directive to tell the assembler which segment to associate
  3624.  with a segment register is not the same as telling the processor. The ASSUME
  3625.  directive  affects only assembly-time assumptions. You may need to use
  3626.  instructions to change run-time assumptions. Initializing segment registers
  3627.  at run time is discussed in Section 3.1.1.1, "Informing the Assembler about
  3628.  Segment Values."
  3629.  ────────────────────────────────────────────────────────────────────────────
  3630.  
  3631.  The ASSUME directive can define a segment for each of the segment registers.
  3632.  The segregister can be CS, DS, ES, or SS (and FS and GS on the 80386/486).
  3633.  The seglocation must be one of the following:
  3634.  
  3635.  
  3636.    ■   The name of a segment defined in the source file with the SEGMENT
  3637.        directive
  3638.  
  3639.    ■   The name of a group defined in the source file with the GROUP
  3640.        directive
  3641.  
  3642.    ■   The keyword NOTHING, ERROR, or FLAT
  3643.  
  3644.    ■   A SEG expression (see Section 3.2.2, "Immediate Operands")
  3645.  
  3646.    ■   A string equate (text macro) that evaluates to a segment or group name
  3647.        (but not a string equate that evaluates to a SEG expression)
  3648.  
  3649.  
  3650.  It is legal to combine assumes to FLAT with assumes to specific segments.
  3651.  Combinations might be necessary in operating-system code that handles both
  3652.  16- and 32-bit segments.
  3653.  
  3654.  The keyword NOTHING cancels the current segment assumptions. For example,
  3655.  the statement ASSUME NOTHING cancels all register assumptions made by
  3656.  previous ASSUME statements.
  3657.  
  3658.  The ASSUME directive can be used anywhere in your program.
  3659.  
  3660.  Usually, a single ASSUME statement defines all four segment registers at the
  3661.  start of the source file. However, you can use the ASSUME directive at any
  3662.  point to change segment assumptions.
  3663.  
  3664.  Using the ASSUME directive to change segment assumptions is often equivalent
  3665.  to changing assumptions with the segment-override operator (:) (see Section
  3666.  3.2.3, "Direct Memory Operands"). The segment-override operator is more
  3667.  convenient for one-time overrides, whereas the ASSUME directive may be more
  3668.  convenient if previous assumptions must be overridden for a sequence of
  3669.  instructions.
  3670.  
  3671.  You can also prevent the use of a register with
  3672.  
  3673.    ASSUME  SegRegister : ERROR
  3674.  
  3675.  The assembler does an  ASSUME CS:ERROR  when you use simplified directives
  3676.  to create data segments, effectively preventing instructions or code labels
  3677.  from appearing in a data segment.
  3678.  
  3679.  See Section 3.3.2 for information on other applications of ASSUME.
  3680.  
  3681.  
  3682.  2.3.4  Defining Segment Groups
  3683.  
  3684.  A group is a collection of segments totalling not more than 64K in 16-bit
  3685.  mode. Each code or data item in the group can be addressed relative to the
  3686.  beginning of the group through DS or SS.
  3687.  
  3688.  Segments within a group can be treated as if they shared the same segment
  3689.  address.
  3690.  
  3691.  A group lets you develop separate segments for different kinds of data and
  3692.  then combine these into one segment (a group) for all the data. Using a
  3693.  group can save you from having to continually reload segment registers to
  3694.  access different segments. As a result, the program uses fewer instructions
  3695.  and runs faster.
  3696.  
  3697.  The most common example of a group is the specially named group for near
  3698.  data, DGROUP. In the Microsoft segment model, several segments (_DATA, _BSS,
  3699.  CONST, and STACK) are combined into a single group called DGROUP. Microsoft
  3700.  high-level languages place all near data segments in this group. (By
  3701.  default, the stack is placed here, too.) The .MODEL directive automatically
  3702.  defines DGROUP. The DS register normally points to the beginning of the
  3703.  group, giving you relatively fast access to all data in DGROUP.
  3704.  
  3705.  The syntax of the group directive is
  3706.  
  3707.    name GROUP segment [[,segment]]...
  3708.  
  3709.  The name labels the group. It can refer to a group that was previously
  3710.  defined. This feature lets you add segments to a group one at a time. For
  3711.  example, if MYGROUP  was previously defined to include  ASEG  and  BSEG,
  3712.  then the statement
  3713.  
  3714.    MYGROUP GROUP   CSEG
  3715.  
  3716.  is perfectly legal. It simply adds  CSEG  to the group  MYGROUP;  ASEG  and
  3717.  BSEG  are not removed.
  3718.  
  3719.  Each segment can be any valid segment name (including a segment defined
  3720.  later in source code), with one restriction: a segment cannot belong to more
  3721.  than one group.
  3722.  
  3723.  The GROUP directive does not affect the order in which segments of a group
  3724.  are loaded. You can place any number of 16-bit segments in a group as long
  3725.  as the total size does not exceed 65,536 bytes. If the processor is in
  3726.  32-bit mode, the maximum size is four gigabytes. You need to make sure that
  3727.  non-grouped segments do not get placed between grouped segments in such a
  3728.  way that the size of the group exceeds 64K or 4 gigabytes. Neither can you
  3729.  place a 16-bit and a 32-bit segment in the same group.
  3730.  
  3731.  
  3732.  2.4  Related Topics in Online Help
  3733.  
  3734.  In addition to information covered in this chapter, information on the
  3735.  following topics can be found in online help.
  3736.  
  3737.  Topic                                 Access
  3738.  ────────────────────────────────────────────────────────────────────────────
  3739.  Memory models                         Choose "Memory Models" from the list
  3740.                                        of tables on the "MASM 6.0 Contents"
  3741.                                        screen
  3742.  
  3743.  @Model, @CodeSize, @DataSize          Choose "Predefined Symbols" from the
  3744.                                        "MASM 6.0 Contents" screen
  3745.  
  3746.  Calling conventions                   From the MASM Index, choose "Calling
  3747.                                        Convention"
  3748.  
  3749.  Coprocessor Directives                From the "MASM 6.0 Contents" screen,
  3750.                                        choose "Directives"; then choose
  3751.                                        "Processor Selection"
  3752.  
  3753.  Simplified and full (complete)        From the "MASM 6.0 Contents" screen,
  3754.  segment control                       choose "Directives"; then choose
  3755.                                        "Simplified Segment Control" or
  3756.                                        "Complete Segment Control"
  3757.  
  3758.  
  3759.  
  3760.  
  3761.  
  3762.  
  3763.  
  3764.  Chapter 3  Using Addresses and Pointers
  3765.  ────────────────────────────────────────────────────────────────────────────
  3766.  
  3767.  Most processor and operating-system modes require the use of segmented
  3768.  addresses to access the code and data for MASM applications. The address of
  3769.  the code or data in a segment is relative to an address in a segment
  3770.  register. You can also use pointers to access data in MASM programs.
  3771.  
  3772.  The first section of this chapter describes how to initialize default
  3773.  segment registers to access near and far addresses. The next section
  3774.  describes how to use the available addressing modes to access the code and
  3775.  data. It also describes the related operators, syntax, and displacements.
  3776.  
  3777.  The third section of this chapter explains how to use the TYPEDEF directive
  3778.  to declare pointers (variables containing addresses) and the ASSUME
  3779.  directive to give the assembler information about registers containing
  3780.  pointers. This section also shows you how to do typical pointer operations
  3781.  and how to write code that works for pointer variables in any memory model.
  3782.  
  3783.  
  3784.  
  3785.  3.1  Programming Segmented Addresses
  3786.  
  3787.  Before you use segmented addresses in your programs, you need to initialize
  3788.  the segment registers. The initialization process depends on the registers
  3789.  used and on your choice of simplified segment directives or full segment
  3790.  definitions. The simplified segment directives (introduced in Section 2.2)
  3791.  handle most of the initialization process for you. This section explains how
  3792.  to inform the assembler and the processor of segment addresses, and how to
  3793.  access the near and far code and data in those segments.
  3794.  
  3795.  
  3796.  3.1.1  Initializing Default Segment Registers
  3797.  
  3798.  The segmented architecture of the 8086-family of processors does not require
  3799.  you to specify two addresses every time you access memory. As Chapter 2,
  3800.  "Organizing MASM Segments," explains, the 8086 family of processors uses a
  3801.  system of default segment registers to simplify access to the most commonly
  3802.  used data and code.
  3803.  
  3804.  The segment registers DS, SS, and CS are normally initialized to default
  3805.  segments at the beginning of a program. If you write the main module in a
  3806.  high-level language, the compiler initializes the segment registers. If you
  3807.  write the
  3808.  
  3809.  main module in assembly language, you must initialize them yourself. Follow
  3810.  these two steps to initialize segments:
  3811.  
  3812.  
  3813.    1.  Tell the assembler which segment is associated with a register. The
  3814.        assembler must know the default segments at assembly time.
  3815.  
  3816.    2.  Tell the processor which segment is associated with a register by
  3817.        writing the necessary code to load the correct segment value into the
  3818.        segment register on the processor.
  3819.  
  3820.  
  3821.  These steps are discussed separately in the following sections.
  3822.  
  3823.  
  3824.  3.1.1.1  Informing the Assembler about Segment Values
  3825.  
  3826.  Use ASSUME to inform the assembler about default segments.
  3827.  
  3828.  The first step in initializing segments is to tell the assembler which
  3829.  segment to associate with a register. You do this with the ASSUME directive.
  3830.  If you use simplified segment directives, the assembler generates the
  3831.  appropriate ASSUME statements automatically. If you use full segment
  3832.  definitions, you must code the ASSUME statements for registers other than CS
  3833.  yourself. (ASSUME can also be used on general-purpose registers, as
  3834.  explained in Section 3.3.2, "Defining Register Types with ASSUME.")
  3835.  
  3836.  With simplified segment directives, the .STARTUP directive and the start-up
  3837.  code initialize DS to be equal to SS (unless you specify FARSTACK), which
  3838.  allows default data to be accessed through either SS or DS. This can improve
  3839.  efficiency in the code generated by compilers. The "DS equals SS" convention
  3840.  may not work with certain applications, such as memory-resident programs in
  3841.  DOS and multithread programs in OS/2. The code generated for .STARTUP is
  3842.  shown in Section 2.2.6, "Starting and Ending Code with .STARTUP and .EXIT."
  3843.  You can use similar code to set DS equal to SS in programs using full
  3844.  segment definitions.
  3845.  
  3846.  Here is an example using full segment definitions; it is equivalent to the
  3847.  ASSUME statement generated with simplified segment directives in small model
  3848.  with NEARSTACK:
  3849.  
  3850.    ASSUME cs:_TEXT, ds:DGROUP, ss:DGROUP
  3851.  
  3852.  In the example above, DS and SS are part of the same segment group. It is
  3853.  also possible to have different segments for data and code, and to use
  3854.  ASSUME to set ES, as shown below:
  3855.  
  3856.    ASSUME cs:MYCODE, ds:MYDATA, ss:MYSTACK, es:OTHER
  3857.  
  3858.  Correct use of the ASSUME statement can help find addressing errors. With
  3859.  .CODE, the assembler assumes CS to the current segment. When you use the
  3860.  simplified segment directives .DATA, .DATA?, .CONST, .FARDATA, or .FARDATA?,
  3861.  the assembler automatically assumes CS to ERROR. This prevents
  3862.  
  3863.  instructions from appearing in these segments. If you use full segment
  3864.  definitions, you can accomplish the same by placing  ASSUME CS:ERROR  in a
  3865.  data segment.
  3866.  
  3867.  With either simple or full segments, you can cancel the control of an ASSUME
  3868.  statement by assuming NOTHING. No assumptions is the default condition. For
  3869.  example, you cancel the assumption for ES above with the following
  3870.  statement:
  3871.  
  3872.    ASSUME es:NOTHING
  3873.  
  3874.  Prior to the .MODEL statement (or in its absence), the assembler sets the
  3875.  ASSUME statement for DS, ES, and SS to the current segment.
  3876.  
  3877.  
  3878.  3.1.1.2  Informing the Processor about Segment Values
  3879.  
  3880.  The second step in initializing segments is to inform the processor of
  3881.  segment values at run time. How segment values are initialized at run time
  3882.  differs for each segment register and depends on your use of simplified
  3883.  segment directives or full segment definitions and on the operating system.
  3884.  
  3885.  
  3886.  Specifying a Starting Address - The CS segment register and the IP
  3887.  (instruction pointer) register are initialized automatically if you use the
  3888.  .STARTUP directive with simplified segment directives. If you use full
  3889.  segment definitions, you must specifically set a label in the code segment
  3890.  at the instruction you want executed first. Then provide that label as an
  3891.  argument to the END directive. Both CS and IP are set at load time to the
  3892.  start address the linker gets from the END directive:
  3893.  
  3894.    _TEXT   SEGMENT WORD PUBLIC 'CODE
  3895.            ORG     100h    ; Use this declaration for .COM files only
  3896.    start:                  ; First instruction here
  3897.            .
  3898.            .
  3899.            .
  3900.    _TEXT   ENDS
  3901.            END     start   ; Name of starting label
  3902.  
  3903.  The operating system automatically resolves the value of CS:IP at load time.
  3904.  The label specified as the start address becomes the initial value of IP. In
  3905.  an executable (.EXE) file, the start address is encoded into the header and
  3906.  is initialized by the operating system at load time. In a .COM file, the
  3907.  initial IP is always assumed to be 100h. Therefore, you must use the ORG
  3908.  directive to set the start address to 100h. CS and IP cannot be directly
  3909.  modified except through jump, call, and interrupt instructions.
  3910.  
  3911.  DS is initialized automatically under OS/2, but you must initialize it for
  3912.  DOS.
  3913.  
  3914.  Initializing DS - The DS register is automatically initialized to the
  3915.  correct value (DGROUP) if you use .STARTUP or if you are writing a program
  3916.  for OS/2. If you do not use .STARTUP with DOS, you must initialize DS using
  3917.  the following instructions:
  3918.  
  3919.    mov     ax, DGROUP
  3920.            mov     ds, ax
  3921.  
  3922.  The initialization requires two instructions because the segment name is a
  3923.  constant and the assembler does not allow a constant to be loaded directly
  3924.  to a segment register. The example above loads DGROUP, but you can load any
  3925.  valid segment or group.
  3926.  
  3927.  SS and SP are initialized automatically.
  3928.  
  3929.  Initializing SS and SP - The SS and SP registers are initialized
  3930.  automatically if you use the .STACK directive with simplified segments or if
  3931.  you define a segment that has the STACK combine type with full segment
  3932.  definitions. Using the STACK directive initializes SS to the stack segment.
  3933.  If you want SS to be equal to DS, use .STARTUP or its equivalent. (See
  3934.  "Combining Segments" in Section 2.3.1.) For an executable file, the values
  3935.  are encoded into the executable header and resolved at link time. For a .COM
  3936.  file, SS is initialized to the first address of the 64K program segment and
  3937.  SP is initialized to 0FFFEh.
  3938.  
  3939.  If you do not need to access far data in your program, you do not need to
  3940.  initialize the ES register, although you can do so. Use the same technique
  3941.  as for the DS register. You can initialize SS to a far stack in the same
  3942.  way.
  3943.  
  3944.  
  3945.  3.1.2  Near and Far Addresses
  3946.  
  3947.  Addresses which have an implied segment name or segment registers associated
  3948.  with them are called "near addresses." Addresses which have an explicit
  3949.  segment associated with them are called "far addresses." The assembler
  3950.  handles near and far code automatically, as described below. You must
  3951.  specify how to handle far data.
  3952.  
  3953.  The Microsoft segment model puts all near data and the stack in a group
  3954.  called DGROUP. Near code is put in a segment called _TEXT. Each module's far
  3955.  code or far data is placed in a separate segment. This convention is
  3956.  described in Section 2.3.2, "Controlling the Segment Order."
  3957.  
  3958.  The assembler cannot determine the address for some program components,
  3959.  which are said to be relocatable. The assembler generates a fixup record and
  3960.  the linker provides the address once the location of all segments has been
  3961.  determined. Usually a relocatable operand references a label, but there are
  3962.  exceptions. Examples in the next two sections include information about the
  3963.  relocatability of near and far data.
  3964.  
  3965.  Near Code - Control transfers within near code do not require changes to
  3966.  segment registers. The processor automatically handles changes to the offset
  3967.  in the IP register when control-flow instructions such as JMP, CALL, and RET
  3968.  are used. The statement
  3969.  
  3970.    call    nearproc        ; Change code offset
  3971.  
  3972.  changes the IP register to the new address but leaves the segment unchanged.
  3973.  When the procedure returns, the processor resets IP to the offset of the
  3974.  next instruction after the call.
  3975.  
  3976.  Far Code - The processor automatically handles segment register changes when
  3977.  dealing with far code. The statement
  3978.  
  3979.    call    farproc         ; Change code segment and offset
  3980.  
  3981.  automatically moves the segment and offset of the  farproc  procedure to the
  3982.  CS and IP registers. When the procedure returns, the processor sets CS to
  3983.  the original code segment and sets IP to the offset of the next instruction
  3984.  after the call.
  3985.  
  3986.  Near Data - Near data can usually be accessed directly. That is, a segment
  3987.  register already holds the correct segment for the data item. The term "near
  3988.  data" is often used to refer to the data in the DGROUP group.
  3989.  
  3990.  After the first initialization of the DS and SS registers, these registers
  3991.  normally point into DGROUP. If you modify the contents of either of these
  3992.  registers during the execution of the program, the register may need to be
  3993.  reloaded prior to being used for addressing DGROUP data.
  3994.  
  3995.  If a stack variable is accessed directly through BP or SP, the SS register
  3996.  is the default. Otherwise, the default is DS:
  3997.  
  3998.    nearvar WORD    0
  3999.            .
  4000.            .
  4001.            .
  4002.            mov     ax, nearvar ; Access near data through DS or SS
  4003.            mov     ax, [bp+6]  ; Access near data through SS
  4004.  
  4005.  In this example,  nearvar  is a relocatable label. The assembler does not
  4006.  know where the memory for  nearvar  will be allocated. The linker provides
  4007.  the address at link time. The expression  [bp+6]  is not relocatable. The
  4008.  linker does not need to provide an address for this expression.
  4009.  
  4010.  Far Data - To read or modify a far address, a segment register must point to
  4011.  the segment of the data. This requires two steps. First load the segment
  4012.  (normally either ES or DS) with the correct value, and then (optionally) set
  4013.  an assume of the segment register to the segment of the address (or to
  4014.  NOTHING).
  4015.  
  4016.  ────────────────────────────────────────────────────────────────────────────
  4017.  NOTE
  4018.  In flat model (OS/2 2.x), far addresses are rarely used. By default, all
  4019.  addressing is relative to the initial values of the segment registers. Thus,
  4020.  this section on far addressing does not apply to most flat model programs.
  4021.  ────────────────────────────────────────────────────────────────────────────
  4022.  
  4023.  You can initialize ES.
  4024.  
  4025.  One method commonly used to access far data is to initialize the ES segment
  4026.  register. This example shows two ways to do this:
  4027.  
  4028.    ; First method
  4029.            mov     ax, SEG farvar  ; Load segment of the far address
  4030.            mov     es, ax
  4031.            mov     ax, es:farvar   ; Provide an explicit segment
  4032.                                    ;  override on the addressing
  4033.    ; Second method
  4034.            mov     ax, SEG farvar2 ; Load the segment of the
  4035.                                    ;  far address
  4036.            mov     ex, ax
  4037.            ASSUME  ES:SEG farvar2  ; Tell the assembler that ES points
  4038.                                    ;  to the segment containing farvar2
  4039.            mov     ax, farvar2     ; The assembler provides the ES
  4040.                                    ;  override since it knows that
  4041.                                    ;  the label is addressable
  4042.  
  4043.  After loading the segment of the address into the ES segment register, you
  4044.  can either explicitly override the segment register so that the addressing
  4045.  is correct (method 1) or allow the assembler to insert the override for you
  4046.  (method 2). The assembler uses ASSUME statements to determine which segment
  4047.  register can be used to address a segment of memory. To use the segment
  4048.  override operator, the left operand must be a segment register, not a
  4049.  segment name. (See Section 3.2.3 for more information on segment overrides.)
  4050.  
  4051.  
  4052.  If an instruction needs a segment override, the resulting code is slightly
  4053.  larger and slower, since the override must be encoded into the instruction.
  4054.  However, the resulting code may still be smaller than the code for multiple
  4055.  loads of the default segment register for the instruction.
  4056.  
  4057.  The DS, SS, FS, and GS segment registers (FS and GS are available only on
  4058.  the 80386/486 processors) may also be used to provide for addressing through
  4059.  other segments.
  4060.  
  4061.  If a program uses ES to access far data, it need not restore ES when
  4062.  finished (unless the program uses flat model). Some compilers require that
  4063.  you restore ES before returning to a module written in a high-level
  4064.  language.
  4065.  
  4066.  You can reinitialize DS.
  4067.  
  4068.  For a series of memory accesses to far data, you can reinitialize DS to the
  4069.  far data and then restore DS when you are finished. Use the ASSUME directive
  4070.  to let the assembler know that DS is no longer associated with the default
  4071.  data segment, as shown below:
  4072.  
  4073.    push    ds               ; Save original segment
  4074.            mov     ax, SEG fararray ; Move segment into data register
  4075.            mov     ds, ax           ; Initialize segment register
  4076.            ASSUME  ds:SEG fararray  ; Tell assembler where data is
  4077.            mov     ax, fararray[0]  ; Direct access faster
  4078.            mov     dx, fararray[2]  ; (A relocatable expression)
  4079.            .
  4080.            .
  4081.            .
  4082.            pop     ds               ; Restore segment
  4083.            ASSUME  ds:@DATA         ;  and default assumption
  4084.  
  4085.  The additional overhead of saving and restoring the DS register in this data
  4086.  access method may be worthwhile to avoid repeated segment overrides.
  4087.  
  4088.  If a program changes DS to access far data, it should restore DS when
  4089.  finished. This allows procedures to assume that DS is the segment for near
  4090.  data. This is a convention used in many compilers, including Microsoft
  4091.  compilers.
  4092.  
  4093.  Relocatable Data - The memory expression  es:farvar  is a relocatable memory
  4094.  expression, since the assembler cannot determine the address at assembly
  4095.  time.
  4096.  
  4097.  Since no label is referenced, you may expect
  4098.  
  4099.    mov ax, _myseg:0
  4100.  
  4101.  to be nonrelocatable (in small model). However, in this case,  _myseg:0  is
  4102.  a location in a local module whose memory location is dependent on the link
  4103.  order, so  mov ax, _myseg:0  is relocatable.
  4104.  
  4105.  A group name is also an immediate constant representing the beginning of the
  4106.  group. The first three expressions below are relocatable expressions; the
  4107.  fourth is not.
  4108.  
  4109.    mov ax, DGROUP             ; Relocatable
  4110.            mov ax, @data              ; Relocatable
  4111.            mov ax, mygroup            ; Relocatable
  4112.            mov ax, ds:0               ; Not relocatable
  4113.  
  4114.  
  4115.  3.2  Specifying Addressing Modes
  4116.  
  4117.  The 8086 family of processors recognizes four kinds of instruction operands:
  4118.  register, immediate, direct memory, and indirect memory. Each type of
  4119.  operand corresponds to a different addressing mode.
  4120.  
  4121.  The four types of operands are summarized in the following list and
  4122.  described at length in the rest of this section.
  4123.  
  4124.  Operand Type                      Addressing Mode
  4125.  ────────────────────────────────────────────────────────────────────────────
  4126.  Register                          An 8-bit or 16-bit register on the
  4127.                                    8086-80486; can also be 32-bit on the
  4128.                                    80386/486
  4129.  
  4130.  Immediate                         A constant value contained in the
  4131.                                    instruction itself
  4132.  
  4133.  Direct memory                     A fixed location in memory
  4134.  
  4135.  Indirect memory                   A memory location determined at run time
  4136.                                    by using the address stored in one or
  4137.                                    two registers and a constant
  4138.  
  4139.  
  4140.  
  4141.  3.2.1  Register Operands
  4142.  
  4143.  A register operand specifies that the value in a particular register is an
  4144.  operand. Code for the register or registers used in operands is encoded into
  4145.  the instruction at assembly time.
  4146.  
  4147.  Register operands can be used anywhere you need an operand. The following
  4148.  examples show typical register operands:
  4149.  
  4150.    mov     bx, 10          ; Load constant to BX
  4151.            add     ax, bx          ; Add AX and BX
  4152.            jmp     di              ; Jump to the address in DI
  4153.  
  4154.  Register operands have a specific use related to addresses.
  4155.  
  4156.  An offset stored in a base or index register is often used as a pointer into
  4157.  memory. An offset can be stored in one of the base or index registers; the
  4158.  register can then be used as an indirect memory operand (see Section 3.2.4).
  4159.  For example:
  4160.  
  4161.    mov     [bx], dl ; Store DL in indirect memory operand
  4162.            inc     bx       ; Increment register operand
  4163.            mov     [bx], dl ; Store DL in new indirect memory operand
  4164.  
  4165.  This example moves the value in DL to two consecutive bytes of a memory
  4166.  location pointed to by BX. Any instruction that changes the register value
  4167.  also changes the data item pointed to by the register.
  4168.  
  4169.  
  4170.  3.2.2  Immediate Operands
  4171.  
  4172.  An immediate operand is a constant value that is specified at assembly time.
  4173.  It can be a constant or the result of a constant expression. Immediate
  4174.  values are usually encoded into the internal representation of the
  4175.  instruction at assembly time. These are typical examples:
  4176.  
  4177.    mov     cx, 20          ; Load constant to register
  4178.            add     var, 1Fh        ; Add hex constant to variable
  4179.            sub     bx, 25 * 80     ; Subtract constant expression
  4180.  
  4181.  The OFFSET Operator - Address constants are a special case of immediate
  4182.  operand and consist of an offset or segment value. The OFFSET operator
  4183.  specifies the offset of a memory location, as shown below:
  4184.  
  4185.    mov     bx, OFFSET var  ; Load offset address
  4186.  
  4187.  For information on differences between MASM 5.1 behavior and MASM 6.0
  4188.  behavior related to OFFSET, see Appendix A.
  4189.  
  4190.  An OFFSET expression is resolved at link time.
  4191.  
  4192.  Since segments in different modules may be combined into a single segment,
  4193.  the true base of the segment is not known. Thus, the offset cannot be
  4194.  resolved until link time and  var  is a relocatable immediate.
  4195.  
  4196.  The SEG Operator - The SEG operator specifies the segment of a memory
  4197.  location:
  4198.  
  4199.    mov     ax, SEG farvar  ; Load segment address
  4200.            mov     es, ax
  4201.  
  4202.  A SEG expression is resolved at load time.
  4203.  
  4204.  The actual value of a particular segment is never known until the program is
  4205.  loaded into memory. Constant segments are encoded into the header of the
  4206.  executable file at link time. Executable files in the DOS .COM format (tiny
  4207.  model) cannot contain relocatable segment expressions.
  4208.  
  4209.  When you use the SEG operator with a variable that is not external, MASM 6.0
  4210.  returns the address of the frame (the segment, group, or segment register)
  4211.  if one has been explicitly set. Otherwise, it returns the group if one has
  4212.  been specified. In the absence of a defined group, SEG returns the segment
  4213.  where the variable is defined.
  4214.  
  4215.  For external variables that are not defined in a segment, the linker fills
  4216.  in the segment portion of the address, which may be a segment or group.
  4217.  
  4218.  This behavior can be changed with the /Zm command-line option or with the
  4219.  OPTION OFFSET:SEGMENT statement (see Appendix A, "Differences between MASM
  4220.  6.0 and 5.1"). Section 1.3.2 introduces the OPTION directive.
  4221.  
  4222.  
  4223.  3.2.3  Direct Memory Operands
  4224.  
  4225.  A direct memory operand specifies the data at a given address. The address
  4226.  and size of the data are encoded into the internal representation of the
  4227.  instruction. However, the instruction acts on the contents of the address,
  4228.  not the address itself. You must usually specify the size of these operands
  4229.  so that the instruction knows how much memory to operate on.
  4230.  
  4231.  The offset value of a direct memory operand is not resolved until link time,
  4232.  and the segment must always be in a segment register at run time. The
  4233.  assembler automatically handles address resolution.
  4234.  
  4235.  You usually represent a direct memory operand in source code as a symbolic
  4236.  name previously declared with a data directive such as BYTE, as illustrated
  4237.  below:
  4238.  
  4239.    .DATA?          ; Segment for uninitialized data
  4240.    var     BYTE   ?        ; Reserve one byte at current address
  4241.                            ;  and assign this address to var
  4242.            .CODE
  4243.            .
  4244.            .
  4245.            .
  4246.            mov     var, al ; Load contents of byte register into
  4247.                               address specified by var
  4248.  
  4249.  Any location in memory can be a direct memory operand as long as a size is
  4250.  specified and the location is fixed. The data at the address can change, but
  4251.  the address cannot. By default, instructions that use direct memory
  4252.  addressing use the DS register. You can create an expression that points to
  4253.  a memory location using any of the following operators:
  4254.  
  4255.  Operator Name                     Symbol
  4256.  Plus
  4257.  ────────────────────────────────────────────────────────────────────────────
  4258.  Minus                             -
  4259.  Index                             [ ]
  4260.  Structure member                  .
  4261.  Segment override                  :
  4262.  
  4263.  These operators are discussed in more detail below.
  4264.  
  4265.  Several operators can be used in expressions that evaluate to direct memory
  4266.  operands.
  4267.  
  4268.  Plus and Minus - The result of combining a memory operand and a constant
  4269.  number with the plus or minus operator is a direct memory operand. However,
  4270.  the result of combining two memory operands with the minus operator is an
  4271.  immediate operand. For example:
  4272.  
  4273.    memvar  EQU     array + 5       ; Address five bytes beyond
  4274.    array
  4275.    immexp  EQU     mem1 - mem2     ; Distance between addresses
  4276.  
  4277.  The second expression is legal only if both addresses are in the same
  4278.  segment.
  4279.  
  4280.  The expression  mem1 - mem2  is not relocatable, since the reference to the
  4281.  two labels represents a difference in addresses (offsets). The linker does
  4282.  not need to know about the labels in this statement.
  4283.  
  4284.  Index - The index operator (brackets enclosing an index value) specifies the
  4285.  register or registers for indirect operands. It should contain a constant
  4286.  index when used with direct memory operands. It is equivalent to the plus
  4287.  operator. For example, the following statements are the same:
  4288.  
  4289.    mov     ax, array[5]
  4290.            mov     ax, array+5
  4291.  
  4292.  Any direct memory operand can be enclosed in the index operator. The
  4293.  following are equivalent:
  4294.  
  4295.    mov     ax, var
  4296.            mov     ax, [var]
  4297.  
  4298.  Some programmers prefer to enclose the operand in brackets to show that the
  4299.  contents, not the address, are used.
  4300.  
  4301.  Structure Field - The structure operator (a period) accesses elements of a
  4302.  structure. A field within a structure variable can be accessed as a direct
  4303.  memory operand:
  4304.  
  4305.    mov     bx, structvar.field1
  4306.  
  4307.  The address of the structure operand is the sum of the offsets of  structvar
  4308.   and  field1. See Section 5.2, "Structures and Unions," for more information
  4309.  about structures.
  4310.  
  4311.  Segment Override - The segment override operator (a colon) specifies a
  4312.  segment portion of the address that is different from the default segment.
  4313.  When used with instructions, this operator can apply to segment registers or
  4314.  segment names:
  4315.  
  4316.    mov     ax, es:farvar           ; Use segment override
  4317.  
  4318.  The assembler will not generate a segment override if the default segment is
  4319.  explicitly provided. Thus, the following two statements are equivalent:
  4320.  
  4321.    mov     [bx], ax
  4322.            mov     ds:[bx], ax
  4323.  
  4324.  A segment name override or the segment override operator forces the operand
  4325.  to be an address expression.
  4326.  
  4327.    mov     WORD PTR FARSEG:0, ax   ; Segment name override
  4328.            mov     WORD PTR es:100h, ax    ; Legal and equivalent
  4329.            mov     WORD PTR es:[100h], ax  ;  expressions
  4330.    ;       mov     WORD PTR [100h], ax     ; Illegal, not an address
  4331.  
  4332.  As the example shows, a constant expression cannot be an address expression
  4333.  unless it has a segment override.
  4334.  
  4335.  
  4336.  3.2.4  Indirect Memory Operands
  4337.  
  4338.  Like direct memory operands, indirect memory operands specify the contents
  4339.  of a given address. However, the processor calculates the address at run
  4340.  time by referring to the contents of registers. Since values in the
  4341.  registers can change at run time, indirect memory operands provide dynamic
  4342.  access to memory.
  4343.  
  4344.  Indirect memory operands make possible run-time operations such as pointer
  4345.  indirection and dynamic indexing of array elements, including indexing of
  4346.  multidimensional arrays.
  4347.  
  4348.  Strict rules govern which registers can be used for indirect memory operands
  4349.  under 16-bit versions of the 8086-based processors. The rules change
  4350.  significantly for 32-bit processors starting with the 80386. However, the
  4351.  new rules apply only to code that does not need to be backward compatible.
  4352.  
  4353.  This section first discusses features of indirect operands in either mode.
  4354.  Then it explains the specific 16-bit rules and 32-bit rules separately.
  4355.  
  4356.  
  4357.  3.2.4.1  Indirect Operands with 16- and 32-Bit Registers
  4358.  
  4359.  Some rules and options for indirect memory operands always apply, regardless
  4360.  of the size of the register. For example, you must always specify the
  4361.  register and operand size for indirect memory operands. But you can use
  4362.  various syntaxes to indicate an indirect memory operand. This section
  4363.  describes the rules that apply to both 16-bit and 32-bit register modes.
  4364.  
  4365.  Certain rules govern the use of base and index registers.
  4366.  
  4367.  Specifying Indirect Memory Operands - The index operator specifies the
  4368.  register or registers for indirect operands. The processor uses the data
  4369.  pointed to by the register. For example, the following instruction moves the
  4370.  word-sized data at the address contained in DS:BX into AX:
  4371.  
  4372.    mov     ax, WORD PTR [bx]
  4373.  
  4374.  When you specify more than one register, the processor adds the two
  4375.  addresses together to determine the effective address (the address of the
  4376.  data to operate on):
  4377.  
  4378.    mov     ax, [bx+si]
  4379.  
  4380.  An indirect memory operand can have a displacement.
  4381.  
  4382.  Specifying Displacements - You can specify an address displacement─ a
  4383.  constant value to add to the effective address. A direct memory specifier is
  4384.  the most common displacement:
  4385.  
  4386.    mov     ax, table[si]
  4387.  
  4388.  In the relocatable expression above, the displacement  table  is the base
  4389.  address of an array; SI holds an index to an array element. The SI value is
  4390.  calculated at run time, often in a loop. The element loaded into AX depends
  4391.  on the value of SI at the time the instruction is executed.
  4392.  
  4393.  Each displacement can be an address or numeric constant. If there is more
  4394.  than one displacement, the assembler adds them together at assembly time and
  4395.  encodes the total displacement. For example, in the statement
  4396.  
  4397.    table   WORD    100 DUP (0)
  4398.            .
  4399.            .
  4400.            .
  4401.            mov     ax, table[bx][di]+6
  4402.  
  4403.  both  table  and  6  are displacements. The assembler adds the value of
  4404.  table  to  6  to get the total displacement. However, this statement is not
  4405.  legal:
  4406.  
  4407.    mov ax, mem1[si] + mem2
  4408.  
  4409.  Indirect memory operands must always have a size.
  4410.  
  4411.  Specifying Operand Size - Indirect memory operands must always have a
  4412.  specified size. Often the size is specified by the size of the identifier.
  4413.  In the example above, the size of the  table  array determines the operand
  4414.  size. If an indirect memory operand is used with a register operand, the
  4415.  register size determines the size of the memory object:
  4416.  
  4417.    mov     ax, [bx]        ; Size is 2 bytes - same as
  4418.    AX
  4419.            mov     table[bx], 0    ; Size is 2 bytes - from size
  4420.                                    ;  of table
  4421.  
  4422.  If there is no address or register operand, the size must be given
  4423.  specifically with the PTR operator, as shown below:
  4424.  
  4425.    inc     WORD PTR [bx]           ; Word size
  4426.            mov     BYTE PTR [bp+6], 0      ; Byte size
  4427.  
  4428.  Syntax Options - The assembler allows a variety of syntaxes for indirect
  4429.  memory operands. However, all registers must be inside brackets. You can
  4430.  enclose each register in its own pair of brackets, or you can place the
  4431.  registers in the same pair of brackets separated by a plus operator (+). All
  4432.  the following variations are legal and equivalent:
  4433.  
  4434.    mov     ax, table[bx][di]
  4435.            mov     ax, table[di][bx]
  4436.            mov     ax, table[bx+di]
  4437.            mov     ax, [table+bx+di]
  4438.            mov     ax, [bx][di]+table
  4439.  
  4440.  All of these statements move the value in  table  indexed by  BX+DI  into
  4441.  AX.
  4442.  
  4443.  Registers pointing into arrays must be zero-based and scaled for the size of
  4444.  the array.
  4445.  
  4446.  Scaling Indexes - The value of index registers pointing into arrays must
  4447.  often be adjusted for zero-based arrays and scaled according to the size of
  4448.  the array items. For a word array, the item number must be multiplied by two
  4449.  (shifted left two places). When you are using 16-bit registers, scaling must
  4450.  be done with separate instructions, as shown below:
  4451.  
  4452.    mov     bx, 5           ; Get sixth element (adjust
  4453.    for 0)
  4454.            shl     bx, 1           ; Scale by two (word size)
  4455.            inc     wtable[bx]      ; Increment sixth element in table
  4456.  
  4457.  When using 32-bit registers on the 80386/486 processor, you can include
  4458.  scaling in the operand, as described in Section 3.2.4.3, "Indirect Memory
  4459.  Operands with 32-Bit Registers."
  4460.  
  4461.  Accessing Structure Elements  - The structure member operator can be used in
  4462.  indirect memory operands to access structure elements. In this example, the
  4463.  structure member operator loads the  year  field of the fourth element of
  4464.  the  students  array into AL:
  4465.  
  4466.    STUDENT STRUCT
  4467.      grade WORD    ?
  4468.      name  BYTE    20 DUP (?)
  4469.      year  BYTE    ?
  4470.    STUDENT ENDS
  4471.  
  4472.    students        STUDENT  < >
  4473.            .
  4474.            .                               ; Assume array initialized
  4475.            .                               ;  earlier
  4476.            mov     bx, OFFSET students     ; Point to array of students
  4477.            mov     ax, 4                   ; Get fourth element
  4478.            mov     di, SIZE STUDENT        ; Get size of STUDENT
  4479.            mul     di                      ; Multiply size times
  4480.                                            ;  elements to point to
  4481.                                            ;  current element
  4482.                                            ; Load field from element:
  4483.            mov     al, (STUDENT PTR[bx+di]).year
  4484.  
  4485.  See Section 5.2 for more information on MASM structures.
  4486.  
  4487.  
  4488.  3.2.4.2  Indirect Memory Operands with 16-Bit Registers
  4489.  
  4490.  For 8086-based computers and DOS, you must follow the strict indexing rules
  4491.  established for the 8086 processor. Only four registers are allowed─BP, BX,
  4492.  SI, and DI─and those only in certain combinations.
  4493.  
  4494.  BP and BX are base registers. SI and DI are index registers. You can use
  4495.  either a base or an index register by itself. But if you combine two
  4496.  registers, one must be a base and one an index. Here are legal and illegal
  4497.  forms:
  4498.  
  4499.    mov     ax, [bx+di]     ; Legal
  4500.            mov     ax, [bx+si]     ; Legal
  4501.            mov     ax, [bp+di]     ; Legal
  4502.            mov     ax, [bp+si]     ; Legal
  4503.    ;       mov     ax, [bx+bp]     ; Illegal - two base registers
  4504.    ;       mov     ax, [di+si]     ; Illegal - two index registers
  4505.  
  4506.  Table 3.1 shows the modes in which registers can be used to specify indirect
  4507.  memory operands.
  4508.  
  4509.  Table 3.1  Indirect Addressing Modes with 16-Bit Registers
  4510.  
  4511. ╓┌─────────────────────┌────────────────────────┌────────────────────────────╖
  4512.  Mode                  Syntax                   Effective Address
  4513.  ────────────────────────────────────────────────────────────────────────────
  4514.  Register indirect     [BX]                     Contents of register
  4515.                        [BP]
  4516.                        [DI]
  4517.  Mode                  Syntax                   Effective Address
  4518.  ────────────────────────────────────────────────────────────────────────────
  4519.                       [DI]
  4520.                        [SI]
  4521.  
  4522.  ────────────────────────────────────────────────────────────────────────────
  4523.  
  4524.  Base or index         displacement[BX]         Contents of register plus
  4525.                        displacement[BP]         displacement
  4526.                        displacement[DI]
  4527.                        displacement[SI]
  4528.  
  4529.  ────────────────────────────────────────────────────────────────────────────
  4530.  
  4531.  Base plus index       [BX][DI]                 Contents of base register
  4532.                        [BP][DI]                 plus contents of index
  4533.                        [BX][SI]                 register
  4534.                        [BP][SI]
  4535.  
  4536.  ────────────────────────────────────────────────────────────────────────────
  4537.  
  4538.  Mode                  Syntax                   Effective Address
  4539.  ────────────────────────────────────────────────────────────────────────────
  4540. 
  4541.  Base plus index with  displacement[BX][DI]     Sum of base register, index
  4542.  displacement          displacement[BP][DI]     register, and displacement
  4543.                        displacement[BX][SI]
  4544.                        displacement[BP][SI]
  4545.  
  4546.  ────────────────────────────────────────────────────────────────────────────
  4547.  
  4548.  
  4549.  
  4550.  Different combinations of registers and displacements have different
  4551.  timings, as shown in the Macro Assembler Reference.
  4552.  
  4553.  
  4554.  3.2.4.3  Indirect Memory Operands with 32-Bit Registers
  4555.  
  4556.  Instructions for the 80386/486 processor can be given in two segment
  4557.  modes─16-bit and 32-bit. Indirect memory operands are different in each
  4558.  mode. The segment mode is independent of the register size; you can use
  4559.  32-bit registers in either mode.
  4560.  
  4561.  In 16-bit mode, the 80386/486 operates in the mode used by all other
  4562.  8086-based processors, with one difference: you can use 32-bit registers. If
  4563.  the 80386/486 processor is enabled (with the .386 or .486 directive), 32-bit
  4564.  general-purpose registers are available in either segment mode. Using them
  4565.  eliminates many of the limitations of 16-bit indirect memory operands. Using
  4566.  80386/486 features can make your DOS programs run faster and more
  4567.  efficiently if you are willing to sacrifice backward compatibility with
  4568.  other processors.
  4569.  
  4570.  In 32-bit mode, an offset address can be up to four gigabytes. (Segments are
  4571.  still represented in 16 bits.) This effectively eliminates size restrictions
  4572.  on each segment, since few programs need four gigabytes of memory. OS/2 2.x
  4573.  uses 32-bit mode and flat model, which spans all segments. XENIX 386 uses
  4574.  32-bit mode with multiple segments.
  4575.  
  4576.  Any general-purpose 32-bit register can be used as either the base or the
  4577.  index.
  4578.  
  4579.  80386/486 Enhancements - On the 80386/486, the processor allows any
  4580.  general-purpose 32-bit register to be used as either the base or the index
  4581.  register (except ESP, which can be a base but not an index). The same
  4582.  register can also be used as both the base and index, but you cannot combine
  4583.  16-bit and 32-bit registers. Several examples are shown below:
  4584.  
  4585.    add     edx, [eax]              ; Add double
  4586.            mov     dl, [esp+10]            ; Add byte from stack
  4587.            dec     WORD PTR [edx][eax]     ; Decrement word
  4588.            cmp     ax, array[ebx][ecx]     ; Compare word from array
  4589.            jmp     FWORD PTR table[ecx]    ; Jump into pointer table
  4590.  
  4591.  The index register can have a scaling factor of 1, 2, 4, or 8.
  4592.  
  4593.  Scaling Factors - With 80386/486 registers, the index register can have a
  4594.  scaling factor of 1, 2, 4, or 8. Any register except ESP can be the index
  4595.  register and can have a scaling factor. Specify the scaling factor by using
  4596.  the multiplication operator (*) adjacent to the register.
  4597.  
  4598.  You can use scaling to index into arrays with different sizes of elements.
  4599.  For example, the scaling factor is 1 for byte arrays (no scaling needed), 2
  4600.  for word arrays, 4 for doubleword arrays, and 8 for quadword arrays. There
  4601.  is no performance penalty for using a scaling factor. Scaling is illustrated
  4602.  in the following examples:
  4603.  
  4604.    mov     eax, darray[edx*4]     ; Load double of double
  4605.    array
  4606.            mov     eax, [esi*8][edi]      ; Load double of quad array
  4607.            mov     ax, wtbl[ecx+2][edx*2] ; Load word of word array
  4608.  
  4609.  Scaling is also necessary on earlier processors, but it must be done with
  4610.  separate instructions before the indirect memory operand is used, as
  4611.  described in Section 3.2.4.2, "Indirect Memory Operands with 16-Bit
  4612.  Registers."
  4613.  
  4614.  The number of registers and the scaling factor affect base and index
  4615.  registers.
  4616.  
  4617.  The default segment register is SS if the base register is EBP or ESP; it is
  4618.  DS for all other base registers. If two registers are used, only one can
  4619.  have a scaling factor. The register with the scaling factor is defined as
  4620.  the index register. The other register is defined as the base. If scaling is
  4621.  not used, the first register is the base. If only one register is used, it
  4622.  is considered the base for deciding the default segment unless it is scaled.
  4623.  The following examples illustrate how to determine the base register:
  4624.  
  4625.    mov   eax, [edx][ebp*4] ; EDX base (not scaled - seg
  4626.    DS)
  4627.            mov   eax, [edx*1][ebp] ; EBP base (not scaled - seg SS)
  4628.            mov   eax, [edx][ebp]   ; EDX base (first - seg DS)
  4629.            mov   eax, [ebp][edx]   ; EBP base (first - seg SS)
  4630.            mov   eax, [ebp*2]      ; EBP base (only - seg SS)
  4631.  
  4632.  Mixing 16-Bit and 32-Bit Registers - Statements can mix 16-bit and 32-bit
  4633.  registers if the register use is correct. For example, the following
  4634.  statement is legal for either 16-bit or 32-bit segments:
  4635.  
  4636.    mov     eax, [bx]
  4637.  
  4638.  This statement moves the 32-bit value pointed to by BX into the EAX
  4639.  register. Although BX is a 16-bit pointer, it can still point into a 32-bit
  4640.  segment.
  4641.  
  4642.  However, the following statement is never legal, since the CX register
  4643.  cannot be used as a 16-bit pointer (although ECX can be used as a 32-bit
  4644.  pointer):
  4645.  
  4646.    ;       mov     eax, [cx]       ; illegal
  4647.  
  4648.  Operands that mix 16-bit and 32-bit registers are also illegal:
  4649.  
  4650.    ;       mov     eax, [ebx+si]   ; illegal
  4651.  
  4652.  The following statement is legal in either mode:
  4653.  
  4654.    mov     bx, [eax]
  4655.  
  4656.  This statement moves the 16-bit value pointed to by EAX into the BX
  4657.  register. This works fine in 32-bit mode. However, in 16-bit mode, moving a
  4658.  32-bit pointer into a 16-bit segment is illegal. If EAX contains a 16-bit
  4659.  value (the top half of the 32-bit register is 0), the statement works.
  4660.  However, if the top half of the EAX register is not 0, the operand points
  4661.  into a part of the segment that doesn't exist, and this generates an error.
  4662.  If you use 32-bit registers as indexes in 16-bit mode, you must make sure
  4663.  that the index registers contain valid 16-bit addresses.
  4664.  
  4665.  
  4666.  3.3  Accessing Data with Pointers and Addresses
  4667.  
  4668.  In high-level languages, a "pointer" (or pointer variable) is an address
  4669.  that is stored in a variable. Assembly language also uses pointer variables,
  4670.  but the term "pointer" has a wider use. The indirect memory operands
  4671.  discussed in the previous section can be thought of as pointers stored in
  4672.  registers.
  4673.  
  4674.  An address can be stored in a pointer variable for later use. Program
  4675.  procedures (including OS/2 systems calls) frequently pass pointer variables
  4676.  onto the stack to transfer data between the calling program and the called
  4677.  procedure.
  4678.  
  4679.  A pointer variable must be transferred to registers before it can be used.
  4680.  
  4681.  Regardless of the reason for maintaining it, a pointer variable to data
  4682.  cannot in itself be directly used in MASM statements. (Pointers to code can
  4683.  be used directly.) It must first be loaded into registers as an indirect
  4684.  memory operand.
  4685.  
  4686.  There is a difference between a far address and a far pointer. A "far
  4687.  address" is the address of a variable located in a far data segment. A "far
  4688.  pointer" is a variable that can specify both a segment and an offset. Like
  4689.  any other variable, a pointer variable can be located in either the default
  4690.  (near) data segment or in a far segment.
  4691.  
  4692.  Previous versions of MASM allow pointer variables but provide little support
  4693.  for them. In previous versions, any address loaded into a variable can be
  4694.  considered a pointer, as in the following statements:
  4695.  
  4696.    Var     BYTE    0               ; Variable
  4697.    npVar   WORD    Var             ; Near pointer to variable
  4698.    fpVar   DWORD   Var             ; Far pointer to variable
  4699.  
  4700.  If a variable is initialized to the name of another variable, the
  4701.  initialized variable is a pointer, as shown in the example above. However,
  4702.  in previous versions of MASM, the CodeView debugger recognizes  npVar  and
  4703.  fpVar  as word and doubleword variables. CodeView does not treat them as
  4704.  pointers, nor does it recognize the type of data they point to (bytes, in
  4705.  the example).
  4706.  
  4707.  The new directive TYPEDEF and the new capabilities of ASSUME make it easier
  4708.  to manage pointers in registers and variables. These directives are
  4709.  discussed in the next two sections. Basic pointer and address operations are
  4710.  covered in Section 3.3.3.
  4711.  
  4712.  
  4713.  3.3.1  Defining Pointer Types with TYPEDEF
  4714.  
  4715.  Once defined, a TYPEDEF is considered the same as an intrinsic type.
  4716.  
  4717.  You can define types for pointer variables using the TYPEDEF directive. A
  4718.  type so defined is considered the same as the intrinsic types provided by
  4719.  the assembler and can be used in the same contexts. The syntax for TYPEDEF
  4720.  when used to define pointers is
  4721.  
  4722.    typename TYPEDEF «distance» PTR  qualifiedtype
  4723.  
  4724.  The typename is the name assigned to the new type. The distance can be NEAR,
  4725.  FAR, or any distance modifier. The qualifiedtype can be any previously
  4726.  intrinsic or defined MASM type, or a type previously defined with TYPEDEF.
  4727.  (See Section 1.2.6, "Data Types," for a full definition of qualifiedtype.)
  4728.  
  4729.  Here are some examples of user-defined types:
  4730.  
  4731.    PBYTE   TYPEDEF      PTR BYTE   ; Pointer to bytes
  4732.    NPBYTE  TYPEDEF NEAR PTR BYTE   ; Near pointer to bytes
  4733.    FPBYTE  TYPEDEF FAR  PTR BYTE   ; Far pointer to bytes
  4734.    PWORD   TYPEDEF      PTR WORD   ; Pointer to words
  4735.    NPWORD  TYPEDEF NEAR PTR WORD   ; Near pointer to words
  4736.    FPWORD  TYPEDEF FAR  PTR WORD   ; Far pointer to words
  4737.  
  4738.    PPBYTE  TYPEDEF      PTR PBYTE  ; Pointer to pointer to bytes
  4739.                                    ;  (in C, an array of strings)
  4740.    PVOID   TYPEDEF      PTR        ; Pointer to any type of data
  4741.  
  4742.    STRUCT  PERSON                  ; Structure type
  4743.      name  BYTE    20 DUP (?)
  4744.      num   WORD    ?
  4745.    PERSON  ENDS
  4746.    PPERSON TYPEDEF      PTR PERSON ; Pointer to structure type
  4747.  
  4748.  The distance of a pointer can either be set specifically or determined
  4749.  automatically by the memory model (set by .MODEL) and the segment size (16
  4750.  or 32 bits). If you don't use .MODEL, near pointers are the default.
  4751.  
  4752.  In 16-bit mode, a near pointer is two bytes that contain the offset of the
  4753.  object pointed to. A far pointer requires four bytes, and it contains both
  4754.  the offset and the segment. In 32-bit mode, a near pointer is four bytes and
  4755.  a far pointer is six bytes. If you specify the distance with NEAR or FAR,
  4756.  the default distance of the current segment size is used. You can use
  4757.  NEAR16, NEAR32, FAR16, and FAR32 to override the defaults set by the current
  4758.  segment size. In flat model, NEAR is the default.
  4759.  
  4760.  A pointer type created with TYPEDEF can be used to declare pointer
  4761.  variables. Here are some examples using the pointer types defined above:
  4762.  
  4763.    ; Type declarations
  4764.    Array   WORD    25 DUP (0)
  4765.    Msg     BYTE    "This is a string", 0
  4766.    pMsg    PBYTE   Msg             ; Pointer to string
  4767.    pArray  PWORD   Array           ; Pointer to word array
  4768.    npMsg   NPBYTE  Msg             ; Near pointer to string
  4769.    npArray NPWORD  Array           ; Near pointer to word array
  4770.    fpArray FPWORD  Array           ; Far pointer to word array
  4771.    fpMsg   FPBYTE  Msg             ; Far pointer to string
  4772.  
  4773.    S1      BYTE    "first", 0      ; Some strings
  4774.    S2      BYTE    "second", 0
  4775.    S3      BYTE    "third", 0
  4776.    pS123   PBYTE   S1, S2, S3, 0   ; Array of pointers to strings
  4777.    ppS123  PPBYTE  pS123           ; A pointer to pointers to strings
  4778.  
  4779.    Andy    PERSON  <>              ; Structure variable
  4780.    pAndy   PPERSON Andy            ; Pointer to structure variable
  4781.  
  4782.                                    ; Procedure prototype
  4783.  
  4784.    EXTERN  ptrArray:PBYTE          ; External variable
  4785.    Sort    PROTO   pArray:PBYTE    ; Parameter for prototype
  4786.  
  4787.    ; Parameter for procedure
  4788.    Sort    PROC    pArray:PBYTE
  4789.            LOCAL   pTmp:PBYTE      ; Local variable
  4790.            .
  4791.            .
  4792.            .
  4793.            ret
  4794.    Sort    ENDP
  4795.  
  4796.  Once defined, pointer types can be used in any context where intrinsic types
  4797.  are allowed.
  4798.  
  4799.  
  4800.  3.3.2  Defining Register Types with ASSUME
  4801.  
  4802.  Beginning with MASM 6.0, you can use the ASSUME directive with
  4803.  generalpurpose registers to specify that a register is a pointer to a
  4804.  certain size of object. For example:
  4805.  
  4806.    ASSUME  bx:PTR WORD     ; BX is word pointer until further
  4807.                                    ;  notice
  4808.            inc     [bx]            ; Increment word pointed to by BX
  4809.            add     bx, 2           ; Point to next word
  4810.            mov     [bx], 0         ; Word pointed to by BX = 0
  4811.            .
  4812.            .                       ; Other pointer operations with BX
  4813.            .
  4814.            ASSUME  bx:NOTHING      ; Cancel assumptions
  4815.  
  4816.  In this example, BX is specified to be a pointer to a word. After a sequence
  4817.  of using BX as a pointer, the assumption is cancelled by assuming NOTHING.
  4818.  
  4819.  Without the assumption to PTR WORD, many instructions need a size specifier.
  4820.  The INC and MOV statements from the examples above would have to be written
  4821.  like this to specify the sizes of the memory operands:
  4822.  
  4823.    inc     WORD PTR [bx]
  4824.            mov     WORD PTR [bx], 0
  4825.  
  4826.  When you have used ASSUME, attempts to use the register for other purposes
  4827.  generate assembly errors. In the example above, while the PTR WORD
  4828.  assumption is in effect, any use of BX inconsistent with its ASSUME
  4829.  declaration generates an error. For example,
  4830.  
  4831.    ;       mov     al, [bx]       ; Can't move word to byte register
  4832.  
  4833.  You can also use the PTR operator to override defaults:
  4834.  
  4835.    mov     ax, BYTE PTR [bx] ; Legal
  4836.  
  4837.  Similarly, you can use ASSUME to prevent the use of a register as a pointer
  4838.  or even to disable a register:
  4839.  
  4840.    ASSUME  bx:WORD, dx:ERROR
  4841.    ;       mov     al, [bx] ; Error - BX is an integer, not a pointer
  4842.    ;       mov     ax, dx   ; Error - DX disabled
  4843.  
  4844.  See Section 2.3.3 for information on using ASSUME with segment registers.
  4845.  
  4846.  
  4847.  3.3.3  Basic Pointer and Address Operations
  4848.  
  4849.  You can do these basic operations with pointers and addresses:
  4850.  
  4851.  
  4852.    ■   Initialize a pointer variable by storing an address in it
  4853.  
  4854.    ■   Load an address into registers, directly or from a pointer
  4855.  
  4856.  
  4857.  The sections in the rest of this chapter describe variations of these tasks
  4858.  with both pointers and addresses. The examples in these sections assume that
  4859.  you have previously defined the following pointer types with the TYPEDEF
  4860.  directive:
  4861.  
  4862.    PBYTE   TYPEDEF      PTR BYTE   ; Pointer to bytes
  4863.    NPBYTE  TYPEDEF NEAR PTR BYTE   ; Near pointer to bytes
  4864.    FPBYTE  TYPEDEF FAR  PTR BYTE   ; Far pointer to bytes
  4865.  
  4866.  
  4867.  3.3.3.1  Initializing Pointer Variables
  4868.  
  4869.  Let the assembler initialize pointer variables when possible.
  4870.  
  4871.  If the value of a pointer is known at assembly time, the assembler can
  4872.  initialize it automatically so that no processing time is wasted on the task
  4873.  at run time. The following example illustrates how to do this:
  4874.  
  4875.    Msg     BYTE    "String", 0
  4876.    pMsg    PBYTE   Msg
  4877.  
  4878.  If a pointer variable can be conditionally defined to one of several
  4879.  constant addresses, initialization must be delayed until run time. The
  4880.  technique is different for near pointers than for far pointers, as shown
  4881.  below:
  4882.  
  4883.    Msg1    BYTE    "String1"
  4884.    Msg2    BYTE    "String2"
  4885.    npMsg   NPBYTE  ?
  4886.    fpMsg   FPBYTE  ?
  4887.            .
  4888.            .
  4889.            .
  4890.            mov     npMsg, OFFSET Msg1              ; Load near pointer
  4891.  
  4892.            mov     WORD PTR fpMsg[0], OFFSET Msg2  ; Load far offset
  4893.            mov     WORD PTR fpMsg[2], SEG Msg2     ; Load far segment
  4894.  
  4895.  If you know that the segment for a far pointer is currently in a register,
  4896.  you can load it directly:
  4897.  
  4898.    mov     WORD PTR fpMsg[2], ds           ; Load segment
  4899.    of
  4900.                                                    ;  far pointer
  4901.  
  4902.  Dynamic Addresses - Often the address to be initialized is dynamic. You know
  4903.  the register or registers containing the address, and you want to save them
  4904.  in a variable for later use. Typical situations include memory allocated by
  4905.  DOS (see interrupt 21h function 48h in online help) and addresses found by
  4906.  the SCAS or CMPS instructions (see Section 5.1.3.1). The technique for
  4907.  saving dynamic addresses is illustrated below:
  4908.  
  4909.    ; Dynamically allocated buffer
  4910.    fpBuf   FPBYTE  0               ; Initialize so offset will be zero
  4911.            .
  4912.            .
  4913.            .
  4914.            mov     ah, 48h         ; Allocate memory
  4915.            mov     bx, 10h         ; Request 16 paragraphs
  4916.            int     21h             ; Call DOS
  4917.            jc      error           ; Return segment in AX
  4918.            mov     WORD PTR fpBuf[2], ax   ; Load segment
  4919.            .                               ;  (offset is already 0)
  4920.            .
  4921.            .
  4922.    error:                          ; Handle error
  4923.  
  4924.  There are several options for copying pointers.
  4925.  
  4926.  Copying Pointers - Sometimes one pointer variable must be initialized by
  4927.  copying from another. Here are two ways to copy a far pointer:
  4928.  
  4929.    fpBuf1  FPBYTE  ?
  4930.    fpBuf2  FPBYTE  ?
  4931.            .
  4932.            .
  4933.            .
  4934.    ; Copy through registers is faster, but requires a spare register
  4935.            mov     bx, WORD PTR fpBuf1[0]
  4936.            mov     WORD PTR fpBuf2[0], bx
  4937.            mov     bx, WORD PTR fpBuf1[2]
  4938.            mov     WORD PTR fpBuf2[2], bx
  4939.  
  4940.    ; Copy through stack is slower, but does not use a register
  4941.            push    WORD PTR fpBuf1[0]
  4942.            push    WORD PTR fpBuf1[2]
  4943.            pop     WORD PTR fpBuf2[2]
  4944.            pop     WORD PTR fpBuf2[0]
  4945.  
  4946.  Pointers passed as procedure arguments are pushed onto the stack.
  4947.  
  4948.  Pointers as Arguments - When a pointer is passed as an argument to a
  4949.  procedure, it must be pushed onto the stack. The procedure then sets up a
  4950.  stack frame so that it can access the arguments from the stack. This
  4951.  technique is discussed in detail in Section 7.3.2, "Passing Arguments on the
  4952.  Stack." Pushing a pointer is illustrated below:
  4953.  
  4954.    ; Push a far pointer (segment always pushed first)
  4955.            push    WORD PTR fpMsg[2]       ; Push segment
  4956.            push    WORD PTR fpMsg[0]       ; Push offset
  4957.  
  4958.  Pushing an address is somewhat different:
  4959.  
  4960.    ; Push a far address as a far pointer
  4961.            mov     ax, SEG fVar    ; Load and push segment
  4962.            push    ax
  4963.            mov     ax, OFFSET fVar ; Load and push offset
  4964.            push    ax
  4965.  
  4966.  On the 80186 and later processors, you can shorten pushing a constant to one
  4967.  step:
  4968.  
  4969.    push    SEG fVar        ; Push segment
  4970.            push    OFFSET fVar     ; Push offset
  4971.  
  4972.  
  4973.  3.3.3.2  Loading Addresses into Registers
  4974.  
  4975.  Loading an address into a pair of registers is one of the most common tasks
  4976.  in assembly-language programming. You cannot do processing work with a
  4977.  constant address or a pointer variable until the address is loaded into
  4978.  registers.
  4979.  
  4980.  Certain register pairs have standard uses.
  4981.  
  4982.  You often load addresses into particular segment:offset pairs. The following
  4983.  pairs have specific uses:
  4984.  
  4985.  Segment:Offset Pair        Standard Use
  4986.  ────────────────────────────────────────────────────────────────────────────
  4987.  DS:SI                      Source for string operations
  4988.  ES:DI                      Destination for string operations
  4989.  DS:DX                      Input for DOS functions
  4990.  ES:BX                      Output from DOS functions
  4991.  
  4992.  In addition, you can use ES:SI, DS:DI, DS:BX, or any segment:offset pair for
  4993.  your own indirect memory operands. You can use SS:BP with a displacement to
  4994.  access procedure arguments or local variables in procedures.
  4995.  
  4996.  Addresses from Data Segments - For near addresses, you need only load the
  4997.  offset; the segment is assumed as SS for stack-based data and as DS for
  4998.  other data. You must load both segment and offset for far pointers.
  4999.  
  5000.  Here is an example of loading an address to DS:BX from a near data segment:
  5001.  
  5002.  
  5003.    .DATA
  5004.    Msg     BYTE    "String"
  5005.            .
  5006.            .
  5007.            .
  5008.            mov     bx, OFFSET Msg  ; Load address to BX
  5009.                                    ;  (DS already loaded)
  5010.  
  5011.  If the data is in a far data segment, it is loaded like this:
  5012.  
  5013.    .FARDATA
  5014.    Msg     BYTE    "String"
  5015.            .
  5016.            .
  5017.            .
  5018.            mov     ax, SEG Msg     ; Load address to ES:BX
  5019.            mov     es, ax
  5020.            mov     bx, OFFSET Msg
  5021.  
  5022.  Stack Variables - The technique for loading the address of a stack variable
  5023.  is significantly different from the technique for loading near addresses.
  5024.  You may need to put the correct segment value into ES for string operations.
  5025.  The following example illustrates how to load the address of a local (stack)
  5026.  variable to ES:DI:
  5027.  
  5028.    Task    PROC
  5029.            LOCAL   Arg[4]:BYTE
  5030.  
  5031.            push    ss      ; Since it's stack-based, segment is SS
  5032.            pop     es      ; Copy SS to ES
  5033.            lea     di, Arg ; Load offset to DI
  5034.  
  5035.  Use LEA to load the offset of an indirect memory operand.
  5036.  
  5037.  The local variable in this case actually evaluates to SS:[BP-4]. This is an
  5038.  offset from the stack frame (described in Section 7.3.2, "Passing Arguments
  5039.  on the Stack"). Since you cannot use the OFFSET operator to get the offset
  5040.  of an indirect memory operand, you must use the LEA (Load Effective Address)
  5041.  instruction.
  5042.  
  5043.  Use MOV and OFFSET to load the offset of a direct memory operand.
  5044.  
  5045.  Direct Memory Operands - To get the address of a direct memory operand, you
  5046.  can use the MOV instruction with OFFSET or the LEA instruction. MASM 6.0
  5047.  automatically optimizes the LEA statement by generating the smaller and
  5048.  faster code, as shown in this example:
  5049.  
  5050.  
  5051.    lea     si, Msg        ; If you code this statement,
  5052.            mov     si, OFFSET Msg ;  MASM 6.0 generates this code
  5053.  
  5054.  The LEA instruction can be used to determine the address of indirect memory
  5055.  operands, as shown below.
  5056.  
  5057.    lea     si, [bx]        ; Legal - LEA required for indirect
  5058.     ;      mov     si, OFFSET [bx] ; Illegal - no OFFSET on indirect
  5059.  
  5060.  Far Pointers  - Use the LES and LDS instructions to load far pointers. Use
  5061.  the MOV instruction to load a near pointer. The following example shows how
  5062.  to load a far pointer to ES:DI and a near pointer to SI (assuming DS as the
  5063.  segment):
  5064.  
  5065.    InBuf   BYTE    20 DUP (1)
  5066.    OutBuf  BYTE    20 DUP (0)
  5067.  
  5068.    npIn    NPBYTE  InBuf
  5069.    fpOut   FPBYTE  OutBuf
  5070.            .
  5071.            .
  5072.            .
  5073.            les     di, fpOut      ; Load far pointer to ES:DI
  5074.  
  5075.            mov     si, npIn       ; Load near pointer to SI (assume DS)
  5076.  
  5077.  Copying between Segment Pairs - Copying from one register pair to another is
  5078.  complicated by the fact that you cannot copy one segment register directly
  5079.  to another. Two methods are shown below. Timings are for the 8088 processor:
  5080.  
  5081.  
  5082.    ; Copy DS:SI to ES:DI, generating smaller code
  5083.            push    ds              ; 1 byte, 14 clocks
  5084.            pop     es              ; 1 byte, 12 clocks
  5085.            mov     di, si          ; 2 bytes, 2 clocks
  5086.  
  5087.    ; Copy DS:SI to ES:DI, generating faster code
  5088.            mov     di, ds          ; 2 bytes, 2 clocks
  5089.            mov     es, di          ; 2 bytes, 2 clocks
  5090.            mov     di, si          ; 2 bytes, 2 clocks
  5091.  
  5092.  
  5093.  3.3.3.3  Model-Independent Techniques
  5094.  
  5095.  Use conditional assembly to write memory-model independent code.
  5096.  
  5097.  Often you may want to write code that is memory-model independent. If you
  5098.  are writing libraries that must be available for different memory models,
  5099.  you can use conditional assembly to handle different sizes of pointers. You
  5100.  can use the predefined symbols @DataSize and @Model to test the current
  5101.  assumptions.
  5102.  
  5103.  Use conditional assembly to handle pointers that have no specified distance.
  5104.  
  5105.  
  5106.  You can use conditional assembly to write code that works with pointer
  5107.  variables that have no specified distance. The predefined symbol @DataSize
  5108.  tests the pointer size for the current memory model:
  5109.  
  5110.    Msg1    BYTE    "String1"
  5111.    pMsg    PBYTE   ?
  5112.            .
  5113.            .
  5114.            .
  5115.            IF      @DataSize
  5116.            mov     WORD PTR pMsg[0], OFFSET Msg1   ; Load far offset
  5117.            mov     WORD PTR pMsg[2], SEG Msg1      ; Load far segment
  5118.            ELSE
  5119.            mov     pMsg, OFFSET Msg1               ; Load near pointer
  5120.            ENDIF
  5121.  
  5122.  In the following example, a procedure receives as an argument a pointer to a
  5123.  word variable. The code inside the procedure uses @DataSize to determine
  5124.  whether the current memory model supports far or near data. It loads and
  5125.  processes the data accordingly:
  5126.  
  5127.    ; Procedure that receives an argument by reference
  5128.    mul8    PROC    arg:PTR WORD
  5129.  
  5130.            IF      @DataSize
  5131.            les     bx, arg     ; Load far pointer to ES:BX
  5132.            mov     ax, es:[bx] ; Load the data pointed to
  5133.            ELSE
  5134.            mov     bx, arg     ; Load near pointer to BX (assume DS)
  5135.            mov     ax, [bx]    ; Load the data pointed to
  5136.            ENDIF
  5137.            shl     ax, 1       ; Multiply by 8
  5138.            shl     ax, 1
  5139.            shl     ax, 1
  5140.            ret
  5141.    mul8    ENDP
  5142.  
  5143.  If you have many routines, writing the conditionals for each case can be
  5144.  tedious. The following conditional statements generate the proper
  5145.  instructions and segment overrides automatically.
  5146.  
  5147.    ; Equates for conditional handling of pointers
  5148.            IF @DataSize
  5149.    lesIF   TEXTEQU    <les>
  5150.    ldsIF   TEXTEQU    <lds>
  5151.    esIF    TEXTEQU    <es:>
  5152.            ELSE
  5153.    lesIF   TEXTEQU    <mov>
  5154.    ldsIF   TEXTEQU    <mov>
  5155.    esIF    TEXTEQU    <>
  5156.            ENDIF
  5157.  
  5158.  Once you define these conditionals, you can use them to simplify code that
  5159.  must handle several types of pointers. This next example rewrites the above
  5160.  mul8  procedure to use conditional code.
  5161.  
  5162.    mul8    PROC    arg:PTR WORD
  5163.  
  5164.            lesIF   bx, arg         ; Load pointer to BX or ES:BX
  5165.            mov     ax, esIF [bx]   ; Load the data from [BX] or ES:[BX]
  5166.            shl     ax, 1           ; Multiply by 8
  5167.            shl     ax, 1
  5168.            shl     ax, 1
  5169.            ret
  5170.    mul8    ENDP
  5171.  
  5172.  The conditional statements from the examples above can be defined once in an
  5173.  include file and used whenever you need to handle pointers.
  5174.  
  5175.  
  5176.  3.4  Related Topics in Online Help
  5177.  
  5178.  In addition to information covered in this chapter, information on the
  5179.  following topics can be found in online help.
  5180.  
  5181. ╓┌─────────────────────────────────────┌─────────────────────────────────────╖
  5182.  Topics                                Access
  5183.  ────────────────────────────────────────────────────────────────────────────
  5184.  LROFFSET, THIS                        From the "MASM 6.0 Contents" screen,
  5185.                                        choose "Operators"; then choose
  5186.                                        "Address"
  5187.  
  5188.  LFS, LGS, and LSS                     From the "MASM 6.0 Contents" screen,
  5189.  Topics                                Access
  5190.  ────────────────────────────────────────────────────────────────────────────
  5191. LFS, LGS, and LSS                     From the "MASM 6.0 Contents" screen,
  5192.                                        choose "Processor Instructions";
  5193.                                        then choose "Data
  5194.                                        Transfer"
  5195.  
  5196.  ALIGN, EVEN, ORG                      From the "MASM 6.0 Contents" screen,
  5197.                                        choose "Directives"; then choose
  5198.                                        "Miscellaneous"
  5199.  
  5200.  NEAR, NEAR16, NEAR32, FAR16, FAR32,   From the "MASM 6.0 Contents" screen,
  5201.  and TYPE                              choose "Operators"; then choose
  5202.                                        "Type and Size"
  5203.  
  5204.  PTR                                   From the "MASM 6.0 Contents" screen,
  5205.                                        choose "Operators"; then choose
  5206.                                        "Miscellaneous"
  5207.  
  5208.  PUSHCONTEXT and POPCONTEXT            Access from the Macro Assembler
  5209.                                        Index
  5210.  Topics                                Access
  5211.  ────────────────────────────────────────────────────────────────────────────
  5212.                                       Index
  5213.  
  5214.  ASSUME, .MODEL                        From the "MASM 6.0 Contents" screen,
  5215.                                        choose "Directives"; then choose
  5216.                                        "Simplified Segment Control"
  5217.  
  5218.  @DataSize, @Model                     From the "MASM 6.0 Contents" screen,
  5219.                                        choose "Predefined Symbols"
  5220.  
  5221.  
  5222.  
  5223.  
  5224.  
  5225.  
  5226.  
  5227.  
  5228.  Chapter 4  Defining and Using Integers
  5229.  ────────────────────────────────────────────────────────────────────────────
  5230.  
  5231.  The 8086 family of processors is designed to operate on integer data;
  5232.  therefore, most assembler statements are integer operations. Even string
  5233.  elements (discussed in Chapter 5, "Defining and Using Complex Data Types")
  5234.  are byte-sized integers to the assembler.
  5235.  
  5236.  This chapter covers the concepts essential for using integer variables in
  5237.  assembly-language programs. The first section shows how to declare integer
  5238.  variables. The second section describes basic integer operations including
  5239.  moving, loading, and sign-extending integers, as well as calculating with
  5240.  integers. Finally, the last section describes how to do various operations
  5241.  with integers at the bit level, such as using bitwise logical instructions
  5242.  and shifting and rotating bits.
  5243.  
  5244.  The complex data types introduced in the next chapter─arrays, strings,
  5245.  structures, unions, and records─use many of the integer operations
  5246.  illustrated in this chapter, since the components of complex data types are
  5247.  often integers. Floating-point operations require a different set of
  5248.  instructions and techniques. These are covered in Chapter 6, "Using
  5249.  Floating-Point and Binary Coded Decimal Numbers."
  5250.  
  5251.  
  5252.  4.1  Declaring Integer Variables
  5253.  
  5254.  You declare integer variables in the data segment of your program to
  5255.  allocate memory for data. The EQU and = directives define integer constants.
  5256.  Integer variables allocated with the data allocation directives can be
  5257.  initialized in several ways. MASM 6.0 provides new forms of the data
  5258.  allocation directives. This section discusses these features and explains
  5259.  how to use the SIZEOF and TYPE operators to provide information to the
  5260.  assembler about the types in your program. For information on symbolic
  5261.  integer constants, see Section 1.2.4, "Integer Constants and Constant
  5262.  Expressions."
  5263.  
  5264.  
  5265.  4.1.1  Allocating Memory for Integer Variables
  5266.  
  5267.  When you declare an integer variable by assigning a label to a data
  5268.  allocation directive, the assembler allocates memory space for the integer.
  5269.  The variable's name becomes a label for the memory space. The syntax is
  5270.  
  5271.    «name» directive initializer
  5272.  
  5273.  These directives, listed below, indicate the integer's size and value range.
  5274.  
  5275.  
  5276. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  5277.  Directive                         Description of Initializers
  5278.  BYTE, DB (bytes)                  Allocates unsigned numbers  from
  5279.                                    0 to 255.
  5280.  ────────────────────────────────────────────────────────────────────────────
  5281.  SBYTE (signed bytes)              Allocates signed numbers from
  5282.                                    -128 to +127.
  5283.  
  5284.  WORD, DW (words = 2 bytes)        Allocates unsigned numbers from
  5285.                                    0 to 65,535 (64K).
  5286.  
  5287.  SWORD (signed words)              Allocates signed numbers from
  5288.                                    -32,768 to +32,767.
  5289.  
  5290.  DWORD, DD (doublewords = 4 bytes) Allocates unsigned numbers from
  5291.                                    0 to 4,294,967,295 (4 megabytes).
  5292.  
  5293.  SDWORD (signed doublewords)       Allocates signed numbers from
  5294.  Directive                         Description of Initializers
  5295.  BYTE, DB (bytes)                  Allocates unsigned numbers  from
  5296.                                    0 to 255.
  5297.  ────────────────────────────────────────────────────────────────────────────
  5298. SDWORD (signed doublewords)       Allocates signed numbers from
  5299.                                    -2,147,483,648 to +2,147,483,647.
  5300.  
  5301.  FWORD, DF (farwords = 6 bytes)    Allocates 6-byte (48-bit) integers.
  5302.                                    These values are normally used only as
  5303.                                    pointer variables on the 80386/486
  5304.                                    processors.
  5305.  
  5306.  QWORD, DQ (quadwords = 8 bytes)   Allocates 8-byte integers used with
  5307.                                    8087-family coprocessor instructions.
  5308.  
  5309.  TBYTE, DT (10 bytes)              Allocates 10-byte (80-bit) integers if
  5310.                                    the initializer has a radix specifying
  5311.                                    the base of the number.
  5312.  
  5313.  
  5314.  
  5315.  See Chapter 6 for information on the REAL4, REAL8, and REAL10 directives
  5316.  that allocate real numbers.
  5317.  
  5318.  
  5319.  
  5320.  
  5321.  The assembler enforces only the size of initializers.
  5322.  
  5323.  MASM does not enforce the range of values assigned to an integer. If the
  5324.  value does not fit in the space allocated, however, the assembler generates
  5325.  an error.
  5326.  
  5327.  The SIZEOF and TYPE operators, when applied to a type, return the size of an
  5328.  integer of that type. The following list gives the size attribute associated
  5329.  with each data type.
  5330.  
  5331.  Data Type                       Bytes
  5332.  BYTE
  5333.  ────────────────────────────────────────────────────────────────────────────
  5334.  WORD, SWORD                     2
  5335.  DWORD, SDWORD                   3
  5336.  FWORD                           6
  5337.  QWORD                           8
  5338.  TBYTE                           10
  5339.  
  5340.  The SBYTE, SWORD, and SDWORD data types are new to MASM 6.0. Use of these
  5341.  signed data types tells the assembler to treat the initializers as signed
  5342.  data. It is important to use these signed types with high-level constructs
  5343.  such as .IF, .WHILE, and .REPEAT (see Section 7.2.1, "Loop-Generating
  5344.  Directives"), and with PROTO and INVOKE directives (see Sections 7.3.6,
  5345.  "Declaring Procedure Prototypes," and 7.3.7, "Calling Procedures with
  5346.  INVOKE").
  5347.  
  5348.  The assembler stores integers with the least significant bytes lowest in
  5349.  memory. Note that assembler listings and most debuggers show the bytes of a
  5350.  word in the opposite order─high byte first.
  5351.  
  5352.  Figure 4.1 illustrates the integer formats.
  5353.  
  5354.  (This figure may be found in the printed book.)
  5355.  
  5356.  TYPEDEF can define integer aliases.
  5357.  
  5358.  Although the TYPEDEF directive's primary purpose is to define pointer
  5359.  variables (see Section 3.3.1), you can also use TYPEDEF to create an alias
  5360.  for any integer type. For example, these declarations
  5361.  
  5362.    char    TYPEDEF SBYTE
  5363.    longint TYPEDEF DWORD
  5364.    float   TYPEDEF REAL4
  5365.    double  TYPEDEF REAL8
  5366.  
  5367.  allow you to use  char,  longint,  float, or  double  in your programs if
  5368.  you prefer the C data labels.
  5369.  
  5370.  
  5371.  4.1.2  Data Initialization
  5372.  
  5373.  You can initialize variables when you declare them by giving initial
  5374.  values─that is, constants or expressions that evaluate to integer constants.
  5375.  The assembler generates an error if you specify an initial value too large
  5376.  for the specified variable type. Variables can also be initialized with ? if
  5377.  there are no initial values.
  5378.  
  5379.  You can declare and initialize variables in one step with the data
  5380.  directives, as these examples show.
  5381.  
  5382.    integer         BYTE    16          ; Initialize byte to 16
  5383.    negint          SBYTE   -16         ; Initialize signed byte to -16
  5384.    expression      WORD    4*3         ; Initialize word to 12
  5385.    signedexp       SWORD   4*3         ; Initialize signed word to 12
  5386.    empty           QWORD   ?           ; Allocate uninitialized long
  5387.                                        ;  integer
  5388.                    BYTE    1,2,3,4,5,6 ; Initialize six unnamed bytes
  5389.    long            DWORD   4294967295  ; Initialize doubleword to
  5390.                                        ;  4,294,967,295
  5391.    longnum         SDWORD  -2147433648 ; Initialize signed doubleword
  5392.  
  5393.                                        ;  to -2,147,433,648
  5394.    tb              TBYTE   2345t       ; Initialize 10-byte binary
  5395.                                        ;  number
  5396.  
  5397.  See Section 5.1, "Arrays and Strings," for information on arrays and on
  5398.  using the DUP operator to allocate initializer lists.
  5399.  
  5400.  Once you have declared integer variables in your program, you can use them
  5401.  in integer operations such as adding, moving, loading, and exchanging. The
  5402.  next section describes these operations.
  5403.  
  5404.  
  5405.  4.2  Integer Operations
  5406.  
  5407.  You often need to copy, move, exchange, load, and sign-extend integer
  5408.  variables in your MASM code. This section shows how to do these operations
  5409.  as well as how to add, subtract, multiply, and divide integers; push and pop
  5410.  integers onto the stack; and do bit-level manipulations with logical, shift,
  5411.  and rotate instructions.
  5412.  
  5413.  The PTR operator tells the assembler the size of the operand.
  5414.  
  5415.  Since MASM instructions require operands to be the same size, you may need
  5416.  to operate on data in a size other than the size originally declared. The
  5417.  PTR operator lets you do this. For example, you can use the PTR operator to
  5418.  access the high-order word of a DWORD-size variable. The syntax for the PTR
  5419.  operator is
  5420.  
  5421.    type PTR expression
  5422.  
  5423.  where the PTR operator forces expression to be treated as having the type
  5424.  specified. An example of this use is
  5425.  
  5426.    .DATA
  5427.    num     DWORD   0
  5428.            .CODE
  5429.  
  5430.    mov     ax, WORD PTR num[0] ; Loads a word-size value
  5431.    from
  5432.            mov     dx, WORD PTR num[2] ;  a doubleword variable
  5433.  
  5434.  You might choose not to use PTR, in contrast to this example. In that case,
  5435.  trying to move  num[0]  into AX generates an error.
  5436.  
  5437.  
  5438.  4.2.1  Moving and Loading Integers
  5439.  
  5440.  The primary instructions for moving integers from operand to operand and
  5441.  loading them into registers are MOV (Move), XCHG (Exchange), XLAT
  5442.  (Translate), CWD (Convert Word to Double), and CBW (Convert Byte to Word).
  5443.  
  5444.  
  5445.  4.2.1.1  Moving Integers
  5446.  
  5447.  The most common method of moving data, the MOV instruction, can be thought
  5448.  of as a copy instruction, since it always copies the source operand to the
  5449.  destination operand. Immediately after a MOV instruction, both the source
  5450.  and destination operands contain the same value.
  5451.  
  5452.  The statements in the following example illustrate each type of memory move
  5453.  that can be performed with a single instruction. Note that you cannot move
  5454.  memory operands to memory operands in one operation.
  5455.  
  5456.    ; Immediate value moves
  5457.            mov     ax, 7       ; Immediate to register
  5458.            mov     mem, 7      ; Immediate to memory direct
  5459.            mov     mem[bx], 7  ; Immediate to memory indirect
  5460.    ; Register moves
  5461.            mov     mem, ax     ; Register to memory direct
  5462.            mov     mem[bx], ax ; Register to memory indirect
  5463.            mov     ax, bx      ; Register to register
  5464.            mov     ds, ax      ; General register to segment
  5465.                                ;  register
  5466.  
  5467.    ; Direct memory moves
  5468.            mov     ax, mem     ; Memory direct to register
  5469.            mov     ds, mem     ; Memory to segment register
  5470.  
  5471.    ; Indirect memory moves
  5472.            mov     ax, mem[bx] ; Memory indirect to register
  5473.            mov     ds, mem[bx] ; Memory indirect to segment register
  5474.  
  5475.    ; Segment register moves
  5476.            mov     mem, ds     ; Segment register to memory
  5477.            mov     mem[bx], ds ; Segment register to memory indirect
  5478.            mov     ax, ds      ; Segment register to general
  5479.                                ;  register
  5480.  
  5481.  This next example shows several common types of moves that require two
  5482.  instructions.
  5483.  
  5484.    ; Move immediate to segment register
  5485.            mov     ax, DGROUP  ; Load immediate to general register
  5486.            mov     ds, ax      ; Store general register to segment
  5487.                                ;  register
  5488.  
  5489.    ; Move memory to memory
  5490.            mov     ax, mem1    ; Load memory to general register
  5491.            mov     mem2, ax    ; Store general register to memory
  5492.  
  5493.    ; Move segment register to segment register
  5494.            mov     ax, ds      ; Load segment register to general
  5495.                                ;  register
  5496.            mov     es, ax      ; Store general register to segment
  5497.                                ;  register
  5498.  
  5499.  The MOVSX and MOVZX instructions for the 80386/486 processors extend and
  5500.  copy values in one step. See Section 4.2.1.4, "Extending Signed and Unsigned
  5501.  Integers."
  5502.  
  5503.  
  5504.  4.2.1.2  Exchanging Integers
  5505.  
  5506.  The XCHG (Exchange) instruction exchanges the data in the source and
  5507.  destination operands. Data can be exchanged between registers or between
  5508.  registers and memory, but not from memory to memory:
  5509.  
  5510.    xchg    ax, bx       ; Put AX in BX and BX in AX
  5511.            xchg    memory, ax   ; Put "memory" in AX and AX in "memory"
  5512.    ;       xchg    mem1, mem2   ; Illegal- can't exchange between
  5513.                                 ;  memory location
  5514.  
  5515.  In some circumstances, register-to-register moves are faster with XCHG than
  5516.  with MOV. If speed is important in your programs, check the Reference to
  5517.  find the fastest clock speeds for various operand combinations allowed with
  5518.  MOV  and XCHG.
  5519.  
  5520.  
  5521.  4.2.1.3  Translating Integers from Tables
  5522.  
  5523.  The XLAT (Translate) instruction loads data from a table into memory. The
  5524.  instruction is useful for translating bytes from one coding system to
  5525.  another. The syntax is
  5526.  
  5527.    XLAT[[B]] [[[[segment:]]memory]]
  5528.  
  5529.  XLAT and XLATB are synonyms.
  5530.  
  5531.  The BX register must contain the address of the start of the table. By
  5532.  default, the DS register contains the segment of the table, but you can use
  5533.  a segment override to specify a different segment. Also, you need not give
  5534.  the operand except when specifying a segment override. (See Section 3.2.3,
  5535.  "Direct Memory Operands," for information about the segment override
  5536.  operator.)
  5537.  
  5538.  Before the XLAT instruction executes, the AL register should contain a value
  5539.  that points into the table (the start of the table is position 0). After the
  5540.  instruction executes, AL contains the table value pointed to. For example,
  5541.  if AL contains 7, the assembler puts the eighth byte of the table in the AL
  5542.  register.
  5543.  
  5544.  This example, illustrating XLAT, looks up hexadecimal characters in a table
  5545.  to convert an eight-bit binary number to a string representing a hexadecimal
  5546.  number.
  5547.  
  5548.    ; Table of hexadecimal digits
  5549.    hex     BYTE    "0123456789ABCDEF"
  5550.    convert BYTE    "You pressed the key with ASCII code "
  5551.    key     BYTE    ?,?,"h",13,10,"$"
  5552.            .CODE
  5553.            .
  5554.            .
  5555.            .
  5556.            mov     ah, 8               ; Get a key in AL
  5557.            int     21h                 ; Call DOS
  5558.            mov     bx, OFFSET hex      ; Load table address
  5559.            mov     ah, al              ; Save a copy in high byte
  5560.            and     al, 00001111y       ; Mask out top character
  5561.            xlat                        ; Translate
  5562.            mov     key[1], al          ; Store the character
  5563.            mov     cl, 12              ; Load shift count
  5564.            shr     ax, cl              ; Shift high character into
  5565.                                        ;  position
  5566.            xlat                        ; Translate
  5567.            mov     key, al             ; Store the character
  5568.            mov     dx, OFFSET convert  ; Load message
  5569.            mov     ah, 9               ; Display character
  5570.            int     21h                 ; Call DOS
  5571.  
  5572.  
  5573.  4.2.1.4  Extending Signed and Unsigned Integers
  5574.  
  5575.  Since moving data to a different-sized register is illegal, you must
  5576.  "sign-extend" integers to convert signed data to a larger register or
  5577.  register pair.
  5578.  
  5579.  Sign-extending means copying the sign bit of the unextended operand to all
  5580.  bits of the extended operand. The instructions in the following list
  5581.  sign-extend values as shown. They work only on signed values in the
  5582.  accumulator register.
  5583.  
  5584.  Instruction    Function
  5585.  ────────────────────────────────────────────────────────────────────────────
  5586.  CBW            Convert byte to word
  5587.  CWD            Convert word to doubleword
  5588.  CWDE           Convert word to doubleword extended (80386/486 only)
  5589.  CDQ            Convert doubleword to quadword (80386/486 only)
  5590.  
  5591.  On the 80386/486, the CWDE instruction converts a signed 16-bit value in AX
  5592.  to a signed 32-bit value in EAX. The CDQ instruction converts a signed
  5593.  32-bit value in EAX to a signed 64-bit value in the EDX:EAX register pair.
  5594.  
  5595.  This example converts signed integers using CBW, CWD, CWDE, and CDQ.
  5596.  
  5597.    .DATA
  5598.    mem8    SBYTE   -5
  5599.    mem16   SWORD   -5
  5600.    mem32   SDWORD  -5
  5601.            .CODE
  5602.            .
  5603.            .
  5604.            .
  5605.            mov     al, mem8    ; Load 8-bit -5 (FBh)
  5606.            cbw                 ; Convert to 16-bit -5 (FFFBh) in AX
  5607.  
  5608.            mov     ax, mem16   ; Load 16-bit -5 (FFFBh)
  5609.            cwd                 ; Convert to 32-bit -5 (FFFF:FFFBh)
  5610.                                ;  in DX:AX
  5611.            mov     ax, mem16   ; Load 16-bit -5 (FFFBh)
  5612.            cwde                ; Convert to 32-bit -5 (FFFFFFFBh)
  5613.                                ;  in EAX
  5614.            mov     eax, mem32  ; Load 32-bit -5 (FFFFFFFBh)
  5615.            cdq                 ; Convert to 64-bit -5
  5616.                                ;  (FFFFFFFF:FFFFFFFBh) in EDX:EAX
  5617.  
  5618.  Conversion instructions do not operate on unsigned numbers.
  5619.  
  5620.  The procedure is different for unsigned values. Unsigned values are extended
  5621.  by filling the upper bits with zeros rather than by sign extension. Because
  5622.  the sign-extend instructions do not work on unsigned integers, you must set
  5623.  the value of the higher register to zero.
  5624.  
  5625.  This example shows sign extension for unsigned numbers.
  5626.  
  5627.    .DATA
  5628.    mem8    BYTE    251
  5629.    mem16   WORD    251
  5630.            .CODE
  5631.            .
  5632.            .
  5633.            .
  5634.            mov     al, mem8  ; Load 251 (FBh) from 8-bit memory
  5635.            sub     ah, ah    ; Zero upper half (AH)
  5636.  
  5637.            mov     ax, mem16 ; Load 251 (FBh) from 16-bit memory
  5638.            sub     dx, dx    ; Zero upper half (DX)
  5639.  
  5640.  The 80386/486 processors provide instructions that move and extend a value
  5641.  to a larger data size in a single step. MOVSX moves a signed value into a
  5642.  register and sign-extends it. MOVZX moves an unsigned value into a register
  5643.  and zeroextends it.
  5644.  
  5645.    ; 80386/486 instructions
  5646.            movzx   dx, bl      ; Load unsigned 8-bit value into
  5647.                                ;  16-bit register and zero-extend
  5648.  
  5649.  These special 80386 and 80486 instructions usually execute much faster than
  5650.  the equivalent 8086-80286 instructions.
  5651.  
  5652.  
  5653.  4.2.2  Pushing and Popping Stack Integers
  5654.  
  5655.  A stack is an area of memory for storing data temporarily. Unlike other
  5656.  segments that store data starting from low memory, the stack stores data in
  5657.  reverse order─starting from high memory. Data is always pushed or popped
  5658.  from the top of the stack. The data on the stack can be the calling
  5659.  addresses of procedures or interrupts, procedure arguments, or any operands,
  5660.  flags, or registers your program needs to store temporarily.
  5661.  
  5662.  At first, the stack is an uninitialized segment of a finite size. As data is
  5663.  added to the stack at run time, the stack grows downward from high memory to
  5664.  low memory. When items are removed from the stack, it shrinks upward from
  5665.  low to high memory.
  5666.  
  5667.  
  5668.  4.2.2.1  Saving Operands on the Stack
  5669.  
  5670.  PUSH and POP always operate on word-sized data.
  5671.  
  5672.  The PUSH instruction stores a two-byte operand on the stack. The POP
  5673.  instruction retrieves a previously pushed value. When a value is pushed onto
  5674.  the stack, the assembler decreases the SP (Stack Pointer) register by 2. On
  5675.  8086-based processors, the SP register always points to the top of the
  5676.  stack. The PUSH and POP instructions use the SP register to keep track of
  5677.  the current position.
  5678.  
  5679.  When a value is popped off the stack, the assembler increases the SP
  5680.  register by 2. Although the stack always contains word values, the SP
  5681.  register points to byte addresses. Thus, SP changes in multiples of two.
  5682.  When a PUSH or POP instruction executes in a 32-bit code segment (one with
  5683.  USE32 use type), the assembler transfers a four-byte value, and ESP changes
  5684.  in multiples of four.
  5685.  
  5686.  ────────────────────────────────────────────────────────────────────────────
  5687.  NOTE
  5688.  The 8086 and 8088 processors differ from later Intel processors in how they
  5689.  push and pop the SP register. If you give the statement  push sp  with the
  5690.  8086 or 8088, the word pushed is the word in SP after the push operation.
  5691.  ────────────────────────────────────────────────────────────────────────────
  5692.  
  5693.  Figure 4.2 illustrates how pushes and pops change the SP register.
  5694.  
  5695.  (Please refer to the printed book.)
  5696.  
  5697.  (This figure may be found in the printed book.)
  5698.  
  5699.  On the 8086, PUSH and POP take only registers or memory expressions as their
  5700.  operands. The other processors allow an immediate value to be an operand for
  5701.  PUSH. For example, the following statement is legal on the 80186-80486
  5702.  processors:
  5703.  
  5704.    push     7              ; 3 clocks on 80286
  5705.  
  5706.  That statement is faster than these equivalent statements, which are
  5707.  required on the 8088 or 8086:
  5708.  
  5709.    mov     ax, 7           ; 2 clocks plus
  5710.            push    ax              ; 3 clocks on 80286
  5711.  
  5712.  There are two ways to clean up the stack.
  5713.  
  5714.  Words are popped off the stack in reverse order: the last item pushed is the
  5715.  first popped. To return the stack to its original status, you can do the
  5716.  same number of pops as pushes. You can subtract the correct number of words
  5717.  from the SP register if you want to restore the stack without using the
  5718.  values on it.
  5719.  
  5720.  To reference operands on the stack, keep in mind that the values pointed to
  5721.  by the BP (Base Pointer) and SP registers are relative to the SS (Stack
  5722.  Segment) register. The BP register is often used to point to the base of a
  5723.  frame of reference (a stack frame) within the stack.
  5724.  
  5725.  This example shows how you can access values on the stack using indirect
  5726.  memory operands with BP as the base register.
  5727.  
  5728.    push    bp              ; Save current value of BP
  5729.            mov     bp, sp          ; Set stack frame
  5730.            push    ax              ; Push first;  SP = BP - 2
  5731.            push    bx              ; Push second; SP = BP - 4
  5732.            push    cx              ; Push third;  SP = BP - 6
  5733.            .
  5734.            .
  5735.            .
  5736.            mov     ax, [bp-6]      ; Put third in AX
  5737.            mov     bx, [bp-4]      ; Put second in BX
  5738.            mov     cx, [bp-2]      ; Put first in CX
  5739.            .
  5740.            .
  5741.            .
  5742.            add     sp, 6           ; Restore stack pointer
  5743.                                    ;  two bytes per push
  5744.            pop     bp              ; Restore BP
  5745.  
  5746.  Creating labels for stack variables makes code easier to read.
  5747.  
  5748.  If you use these stack values often in your program, you may want to give
  5749.  them labels. For example, you can use TEXTEQU to create a label such as
  5750.  count TEXTEQU <bp-6>. Now you can replace the  mov ax, [bp - 6]  statement
  5751.  in the example above with  mov ax, count. Section 9.1, "Text Macros," gives
  5752.  more information about the TEXTEQU directive.
  5753.  
  5754.  
  5755.  4.2.2.2  Saving Flags on the Stack
  5756.  
  5757.  Flags can be pushed and popped onto the stack with the PUSHF and POPF
  5758.  instructions. You can use these instructions to save the status of flags
  5759.  before a procedure call and then to restore the original status after the
  5760.  procedure. You can also use them within a procedure to save and restore the
  5761.  flag status of the caller. The 32-bit versions of these instructions are
  5762.  PUSHFD and POPFD.
  5763.  
  5764.  
  5765.  This example saves the flags register before calling the  systask
  5766.  procedure:
  5767.  
  5768.    pushf
  5769.            call    systask
  5770.            popf
  5771.  
  5772.  If you do not need to store the entire flag register, you can use the LAHF
  5773.  instruction to manually load and store the status of the lower byte of the
  5774.  flag register in the AH register. (You need to save AH before making a
  5775.  procedure call.) SAHF restores the value.
  5776.  
  5777.  
  5778.  4.2.2.3  Saving Registers on the Stack (80186-80486 Only)
  5779.  
  5780.  Starting with the 80186 processor, the PUSHA and POPA instructions push or
  5781.  pop all the general-purpose registers with only one instruction. These
  5782.  instructions save the status of all registers before a procedure call and
  5783.  then restore them after the return. Using PUSHA and POPA is significantly
  5784.  faster and takes fewer bytes of code than pushing and popping each register
  5785.  individually.
  5786.  
  5787.  The processor pushes the registers in the following order: AX, CX, DX, BX,
  5788.  SP, BP, SI, and DI. The SP word pushed is the value before the first
  5789.  register is pushed.
  5790.  
  5791.  The processor pops the registers in the opposite order. The 32-bit versions
  5792.  of these instructions are PUSHAD and POPAD.
  5793.  
  5794.  
  5795.  4.2.3  Adding and Subtracting Integers
  5796.  
  5797.  You can use the ADD, ADC, INC, SUB, SBB, and DEC instructions for adding,
  5798.  incrementing, subtracting, and decrementing values in single registers. You
  5799.  can also combine them to handle larger values that require two registers for
  5800.  storage.
  5801.  
  5802.  
  5803.  4.2.3.1  Adding and Subtracting Integers Directly
  5804.  
  5805.  The ADD, INC (Increment), SUB, and DEC (Decrement) instructions operate on
  5806.  8- and 16-bit values on the 8086-80286 processors, and on 8-, 16-, and
  5807.  32-bit values on the 80386/486 processors. They can be combined with the ADC
  5808.  and SBB instructions to work on 32-bit values on the 8086 and 64-bit values
  5809.  on the 80386/486 processors (see Section 4.2.3.2).
  5810.  
  5811.  
  5812.  These instructions have two requirements:
  5813.  
  5814.  
  5815.    1.  If there are two operands, only one operand can be a memory operand.
  5816.  
  5817.    2.  If there are two operands, both must be the same size.
  5818.  
  5819.  
  5820.  PTR allows you to operate on data in sizes different from its declared type.
  5821.  
  5822.  
  5823.  To meet the second requirement, you can use the PTR operator to force an
  5824.  operand to the size required (see Section 4.2, "Integer Operations"). For
  5825.  example, if  Buffer  is an array of bytes and BX points to an element of the
  5826.  array, you can add a word from  Buffer  with
  5827.  
  5828.    add     ax, WORD PTR Buffer[bx] ; Adds a word from the
  5829.                                            ;  byte variable
  5830.  
  5831.  The next example shows 8-bit signed and unsigned addition and subtraction.
  5832.  
  5833.    DATA
  5834.    mem8    BYTE    39
  5835.            .CODE
  5836.  
  5837.    ; Addition
  5838.  
  5839.                             ;                    signed    unsigned
  5840.            mov     al, 26   ; Start with register   26       26
  5841.            inc     al       ; Increment              1        1
  5842.            add     al, 76   ; Add immediate         76     + 76
  5843.                             ;                     ----     ----
  5844.                             ;                      103      103
  5845.            add     al, mem8 ; Add memory            39     + 39
  5846.                             ;                     ----     ----
  5847.            mov     ah, al   ; Copy to AH          -114      142
  5848.                                                   +overflow
  5849.            add     al, ah   ; Add register                  142
  5850.                             ;                              ----
  5851.                             ;                                28+carry
  5852.  
  5853.    ; Subtraction
  5854.  
  5855.                             ;                   signed    unsigned
  5856.            mov     al, 95   ; Load register         95       95
  5857.            dec     al       ; Decrement             -1       -1
  5858.            sub     al, 23   ; Subtract immediate   -23      -23
  5859.                             ;                     ----     ----
  5860.                             ;                       71       71
  5861.            sub     al, mem8 ; Subtract memory     -122     -122
  5862.                             ;                     ----     ----
  5863.                             ;                      -51      205+sign
  5864.  
  5865.            mov     ah, 119  ; Load register        119
  5866.            sub     al, ah   ;  and subtract        -51
  5867.                             ;                     ----
  5868.                             ;                       86+overflow
  5869.  
  5870.  The INC and DEC instructions treat integers as unsigned values and do not
  5871.  update the carry flag for signed carries and borrows.
  5872.  
  5873.  
  5874.  Your programs must include error-recovery for overflows and carries.
  5875.  
  5876.  When the sum of eight-bit signed operands exceeds 127, the processor sets
  5877.  the overflow flag. (The overflow flag is also set if both operands are
  5878.  negative and the sum is less than or equal to -128.) Placing a JO (Jump on
  5879.  Overflow) or INTO (Interrupt on Overflow) instruction in your program at
  5880.  this point can transfer control to error-recovery statements. When the sum
  5881.  exceeds 255, the processor sets the carry flag. A JC (Jump on Carry)
  5882.  instruction at this point can transfer control to error-recovery statements.
  5883.  
  5884.  
  5885.  In the subtraction example above, the processor sets the sign flag if the
  5886.  result goes below 0. At this point, you can use a JS (Jump on Sign)
  5887.  instruction to transfer control to error-recovery statements.
  5888.  
  5889.  
  5890.  4.2.3.2  Adding and Subtracting in Multiple Registers
  5891.  
  5892.  You can add and subtract numbers larger than the register size on your
  5893.  processor with the ADC (Add with Carry) and SBB (Subtract with Borrow)
  5894.  instructions. If the operations prior to an ADC or SBB instruction do not
  5895.  set the carry flag, these instructions are identical to ADD and SUB. When
  5896.  you operate on large values in more than one register, use ADD and SUB for
  5897.  the least significant part of the number and ADC or SBB for the most
  5898.  significant part.
  5899.  
  5900.  The following example illustrates multiple-register addition and
  5901.  subtraction. You can also use this technique with 64-bit operands on the
  5902.  80386/486 processors.
  5903.  
  5904.  
  5905.    .DATA
  5906.    mem32   DWORD   316423
  5907.    mem32a  DWORD   316423
  5908.    mem32b  DWORD   156739
  5909.            .CODE
  5910.            .
  5911.            .
  5912.            .
  5913.    ; Addition
  5914.            mov     ax, 43981               ; Load immediate     43981
  5915.            sub     dx, dx                  ;  into DX:AX
  5916.            add     ax, WORD PTR mem32[0]   ; Add to both     + 316423
  5917.            adc     dx, WORD PTR mem32[2]   ;  memory words     ------
  5918.                                            ; Result in DX:AX   360404
  5919.  
  5920.    ; Subtraction
  5921.            mov     ax, WORD PTR mem32a[0]  ; Load mem32        316423
  5922.            mov     dx, WORD PTR mem32a[2]  ;  into DX:AX
  5923.            sub     ax, WORD PTR mem32b[0]  ; Subtract low    - 156739
  5924.            sbb     dx, WORD PTR mem32b[2]  ;  then high        ------
  5925.                                            ; Result in DX:AX   159684
  5926.  
  5927.  For 32-bit registers on the 80386/486, only two steps are necessary. If your
  5928.  program needs to be assembled for more than one processor, you can assemble
  5929.  the statements conditionally, as shown in this example:
  5930.  
  5931.    .DATA
  5932.    mem32   DWORD   316423
  5933.    mem32a  DWORD   316423
  5934.    mem32b  DWORD   156739
  5935.    p386    TEXTEQU (@Cpu AND 08h)
  5936.            .CODE
  5937.            .
  5938.            .
  5939.            .
  5940.    ; Addition
  5941.            IF      p386
  5942.            mov     eax, 43981  ; Load immediate
  5943.            add     eax, mem32  ; Result in EAX
  5944.            ELSE
  5945.            .
  5946.            .       ; do steps in previous example
  5947.            .
  5948.            ENDIF
  5949.  
  5950.    ; Subtraction
  5951.            IF      p386
  5952.            mov     eax, mem32a ; Load memory
  5953.            sub     eax, mem32b ; Result in EAX
  5954.            ELSE
  5955.            .
  5956.            .       ; do steps in previous example
  5957.            .
  5958.            ENDIF
  5959.  
  5960.  Since the status of the carry flag affects the results of calculations with
  5961.  ADC and SUB, be sure to turn off the carry flag with the CLC (Clear Carry
  5962.  Flag) instruction or use ADD for the first calculation when appropriate.
  5963.  
  5964.  
  5965.  4.2.4  Multiplying and Dividing Integers
  5966.  
  5967.  The 8086 family of processors uses different multiplication and division
  5968.  instructions for signed and unsigned integers. Multiplication and division
  5969.  instructions also have special requirements depending on the size of the
  5970.  operands and the processor the code runs on.
  5971.  
  5972.  
  5973.  4.2.4.1  Using Multiplication Instructions
  5974.  
  5975.  The MUL instruction multiplies unsigned numbers. IMUL multiplies signed
  5976.  numbers. For both instructions, one factor must be in the accumulator
  5977.  register (AL for 8-bit numbers, AX for 16-bit numbers, EAX for 32-bit
  5978.  numbers). The other factor can be in any single register or memory operand.
  5979.  The result overwrites the contents of the accumulator register.
  5980.  
  5981.  Multiplying two 8-bit numbers produces a 16-bit result returned in AX.
  5982.  Multiplying two 16-bit operands yields a 32-bit result in DX:AX. The
  5983.  80386/486 processor handles 64-bit products in the same way in the EDX:EAX
  5984.  pair.
  5985.  
  5986.  This example illustrates multiplication of signed 16- and 32-bit integers.
  5987.  
  5988.    .DATA
  5989.    mem16   SWORD   -30000
  5990.            .CODE
  5991.            .
  5992.            .
  5993.            .
  5994.    ; 8-bit signed multiply
  5995.            mov     al, 23     ; Load AL                     23
  5996.            mov     bl, 24     ; Load BL                   * 24
  5997.            mul     bl         ; Multiply BL              -----
  5998.                               ; Product in AX              552
  5999.                               ;  overflow and carry set
  6000.  
  6001.    ; 16-bit unsigned multiply
  6002.            mov     ax, 50     ; Load AX                     50
  6003.                               ;                         -30000
  6004.            imul    mem16      ; Multiply memory          -----
  6005.                               ; Product in DX:AX      -1500000
  6006.                               ;  overflow and carry set
  6007.  
  6008.  A nonzero number in the upper half of the result (AH for byte, DX or EDX for
  6009.  word) sets the overflow and carry flags.
  6010.  
  6011.  On the 80186-80486 processors, the IMUL instruction supports three different
  6012.  operand combinations. The first syntax option allows for 16-bit multipliers
  6013.  producing a 16-bit product or 32-bit multipliers for 32-bit products on the
  6014.  80386/486. The result overwrites the destination. The syntax for this
  6015.  operation is
  6016.  
  6017.    IMUL register16, immediate
  6018.  
  6019.  Multiplication by an immediate operand is possible on the 80386/486.
  6020.  
  6021.  The second syntax option specifies three operands for IMUL. The first
  6022.  operand must be a 16-bit register operand, the second a 16-bit memory or
  6023.  register operand, and the third a 16-bit immediate operand. IMUL multiplies
  6024.  the memory (or register) and immediate operands and stores the product in
  6025.  the register operand with this syntax:
  6026.  
  6027.  IMUL register16, memory16 | register16, immediate
  6028.  
  6029.  For the 80386/486 only, a third option for IMUL allows an additional operand
  6030.  for multiplication of a register value by a register or memory value. This
  6031.  is the syntax:
  6032.  
  6033.    IMUL register,{register | memory}
  6034.  
  6035.  The destination can be any 16-bit or 32-bit register. The source must be the
  6036.  same size as the destination.
  6037.  
  6038.  In all of these options, products too large to fit in 16 or 32 bits set the
  6039.  overflow and carry flags. The following examples show these three options
  6040.  for IMUL.
  6041.  
  6042.    imul    dx, 456     ; Multiply DX times 456 on 80186-80486
  6043.            imul    ax, [bx],6  ; Multiply the value pointed to by BX
  6044.                                ;  by 6 and put the result in AX
  6045.  
  6046.            imul    dx, ax      ; Multiply DX times AX on 80386
  6047.            imul    ax, [bx]    ; Multiply AX by the value pointed to
  6048.                                ;  by BX on 80386
  6049.  
  6050.  The IMUL instruction with multiple operands can be used for either signed or
  6051.  unsigned multiplication, since the 16-bit product is the same in either
  6052.  case. To get a 32-bit result, you must use the single-operand version of MUL
  6053.  or IMUL.
  6054.  
  6055.  
  6056.  4.2.4.2  Using Division Instructions
  6057.  
  6058.  The DIV instruction divides unsigned numbers, and IDIV divides signed
  6059.  numbers. Both return a quotient and a remainder.
  6060.  
  6061.  Table 4.1 summarizes the division operations. The dividend is the number to
  6062.  be divided, and the divisor is the number to divide by. The quotient is the
  6063.  result. The divisor can be in any register or memory location except the
  6064.  registers where the quotient and remainder are returned.
  6065.  
  6066.  Table   4.1 Division Operations
  6067.  
  6068.  Size of        Dividend       Size of
  6069.  Operand        Register       Divisor        Quotient  Remainder
  6070.  ────────────────────────────────────────────────────────────────────────────
  6071.  16 bits        AX             8 bits         AL        AH
  6072.  
  6073.  32 bits        DX:AX          16 bits        AX        DX
  6074.  
  6075.  64 bits        EDX:EAX        32 bits        EAX       EDX
  6076.  (80386
  6077.  and 80486)
  6078.  
  6079.  ────────────────────────────────────────────────────────────────────────────
  6080.  
  6081.  
  6082.  Unsigned division does not require careful attention to flags. The following
  6083.  examples illustrate signed division, which can be more complex.
  6084.  
  6085.    .DATA
  6086.    mem16   SWORD   -2000
  6087.    mem32   SDWORD  500000
  6088.            .CODE
  6089.            .
  6090.            .
  6091.            .
  6092.    ; Divide 16-bit unsigned by 8-bit
  6093.            mov     ax, 700               ; Load dividend      700
  6094.            mov     bl, 36                ; Load divisor DIV    36
  6095.            div     bl                    ; Divide BL       ------
  6096.                                          ; Quotient in AL      19
  6097.                                          ; Remainder in AH          16
  6098.  
  6099.    ; Divide 32-bit signed by 16-bit
  6100.            mov     ax, WORD PTR mem32[0] ; Load into DX:AX
  6101.            mov     dx, WORD PTR mem32[2] ;                 500000
  6102.            idiv    mem16                 ;              DIV -2000
  6103.                                          ; Divide memory   ------
  6104.                                          ; Quotient in AX    -250
  6105.                                          ; Remainder in DX           0
  6106.  
  6107.    ; Divide 16-bit signed by 16-bit
  6108.            mov     ax, WORD PTR mem16    ; Load into AX     -2000
  6109.            cwd                           ; Extend to DX:AX
  6110.            mov     bx,-421               ;               DIV -421
  6111.            idiv    bx                    ; Divide by BX     -----
  6112.                                          ; Quotient in AX       4
  6113.                                          ; Remainder in DX        -316
  6114.  
  6115.  If the dividend and divisor are the same size, sign-extend or zero-extend
  6116.  the dividend so that it is the length expected by the division instruction.
  6117.  See Section 4.2.1.4, "Extending Signed and Unsigned Integers."
  6118.  
  6119.  
  6120.  4.3  Manipulating Integers at the Bit Level
  6121.  
  6122.  The instructions introduced so far in this chapter accessed integers at the
  6123.  byte or word level. The logical, shift, and rotate instructions described in
  6124.  this section, however, access the individual bits of the integers. You can
  6125.  use logical instructions to evaluate characters and do other text and screen
  6126.  operations. The shift and rotate instructions do similar tasks by shifting
  6127.  and rotating bits through registers. This section discusses some
  6128.  applications of these bit-level operations.
  6129.  
  6130.  
  6131.  4.3.1  Logical Operations
  6132.  
  6133.  The logical instructions─AND, OR, XOR, and NOT─operate on each bit in one
  6134.  operand and on the corresponding bit in the other. The following list shows
  6135.  how each instruction works. Except for NOT, these instructions require two
  6136.  integers of the same size.
  6137.  
  6138.  
  6139.  Instruction                       Sets a Bit to 1 under These Conditions
  6140.  ────────────────────────────────────────────────────────────────────────────
  6141.  AND                               Both corresponding bits in the operands
  6142.                                    have the value 1.
  6143.  
  6144.  OR                                Either of the corresponding bits in the
  6145.                                    operands has the value 1.
  6146.  
  6147.  XOR                               Either, but not both, of the
  6148.                                    corresponding bits in the operands has
  6149.                                    the value 1.
  6150.  
  6151.  NOT                               The corresponding bit in the operand is
  6152.                                    0. (This instruction takes only one
  6153.                                    operand.)
  6154.  
  6155.  
  6156.  ────────────────────────────────────────────────────────────────────────────
  6157.  NOTE
  6158.  Do not confuse logical instructions with the logical operators, which
  6159.  perform these operations at assembly time, not run time. Although the names
  6160.  are the same, the assembler recognizes the difference from context.
  6161.  ────────────────────────────────────────────────────────────────────────────
  6162.  
  6163.  The following example shows the result of the AND, OR, XOR, and NOT
  6164.  instructions operating on a value in the AX register and in a mask. A mask
  6165.  is a binary or hexadecimal number with appropriate bits set for the intended
  6166.  operation.
  6167.  
  6168.    mov     ax, 035h   ; Load value                  00110101
  6169.            and     ax, 0FBh   ; Clear bit 2             AND 11111011
  6170.                               ;                             --------
  6171.                               ; Value is now 31h            00110001
  6172.            or      ax, 016h   ; Set bits 4,2,1          OR  00010110
  6173.                               ;                             --------
  6174.                               ; Value is now 37h            00110111
  6175.            xor     ax, 0ADh   ; Toggle bits 7,5,3,2,0   XOR 10101101
  6176.                               ;                             --------
  6177.                               ; Value is now 9Ah            10011010
  6178.            not     ax         ; Value is now 65h            01100101
  6179.  
  6180.  Use AND, OR, and XOR to set or clear specific bits.
  6181.  
  6182.  You can use the AND instruction to clear the value of specific bits
  6183.  regardless of their current settings. To do this, put the target value in
  6184.  one operand and a mask of the bits you want to clear in the other. The bits
  6185.  of the mask should be 0 for any bit positions you want to clear and 1 for
  6186.  any bit positions you want to remain unchanged.
  6187.  
  6188.  You can use the OR instruction to force specific bits to 1 regardless of
  6189.  their current settings. The bits of the mask should be 1 for any bit
  6190.  positions you want to set and 0 for any bit positions you want to remain
  6191.  unchanged.
  6192.  
  6193.  You can use the XOR instruction to toggle the value of specific bits
  6194.  (reverse them from their current settings). This instruction sets a bit to 1
  6195.  if the corresponding bits are different or to 0 if they are the same. The
  6196.  bits of the mask should be 1 for any bit positions you want to toggle and 0
  6197.  for any bit positions you want to remain unchanged.
  6198.  
  6199.  The following examples show an application for each of these instructions.
  6200.  The code illustrating the AND instruction converts a "y" or "n" read from
  6201.  the keyboard to uppercase, since bit 5 is always clear in uppercase letters.
  6202.  In the example for OR, the first statement is faster and uses fewer bytes
  6203.  than  cmp bx, 0. When the operands for XOR are identical, each bit cancels
  6204.  itself, producing 0.
  6205.  
  6206.    ; Converts characters to uppercase
  6207.            mov     ah, 7           ; Get character without echo
  6208.            int     21h
  6209.            and     al, 11011111y   ; Convert to uppercase by clearing
  6210.  
  6211.                                    ;  bit 5
  6212.            cmp     al, 'Y'         ; Is it Y?
  6213.            je      yes             ; If so, do Yes actions
  6214.            .                       ;  else do No actions
  6215.            .
  6216.    yes:    .
  6217.  
  6218.    ; Compares operand to 0
  6219.            or      bx, bx          ; Compare to 0
  6220.                                    ;  2 bytes, 2 clocks on 8088
  6221.            jg      positive        ; BX is positive
  6222.            jl      negative        ; BX is negative
  6223.                                    ; else BX is zero
  6224.  
  6225.    ; Sets a register to 0
  6226.            xor     cx, cx          ; 2 bytes, 3 clocks on 8088
  6227.            sub     cx, cx          ; 2 bytes, 3 clocks on 8088
  6228.            mov     cx, 0           ; 3 bytes, 4 clocks on 8088
  6229.  
  6230.  On the 80386 and 80486, the BSF (Bit Scan Forward) and the BSR (Bit Scan
  6231.  Reverse) instructions perform operations similar to those of the logical
  6232.  instructions. They scan the contents of a register to find the first-set or
  6233.  last-set bit. You can use BSF or BSR to find the position of a set bit in a
  6234.  mask or to check if a register value is 0.
  6235.  
  6236.  
  6237.  4.3.2  Shifting and Rotating Bits
  6238.  
  6239.  The 8086-based processors provide a complete set of instructions for
  6240.  shifting and rotating bits. Shift instructions move bits a specified number
  6241.  of places to the right or left. The last bit in the direction of the shift
  6242.  goes into the carry flag, and the first bit is filled with 0 or with the
  6243.  previous value of the first bit.
  6244.  
  6245.  Rotate instructions also move bits a specified number of places to the right
  6246.  or left. For each bit rotated, the last bit in the direction of the rotate
  6247.  operation moves into the first bit position at the other end of the operand.
  6248.  With some variations, the carry bit is used as an additional bit of the
  6249.  operand. Figure 4.3 illustrates the eight variations of shift and rotate
  6250.  instructions for eight-bit operands. Notice that SHL and SAL are identical.
  6251.  
  6252.  
  6253.  (This figure may be found in the printed book.)
  6254.  
  6255.  All shift instructions use the same format. Before the instruction executes,
  6256.  the destination operand contains the value to be shifted; after the
  6257.  instruction executes, it contains the shifted operand. The source operand
  6258.  contains the number of bits to shift or rotate. It can be the immediate
  6259.  value 1 or the CL register. The 8088 and 8086 processors do not accept any
  6260.  other values or registers with these instructions.
  6261.  
  6262.  
  6263.  The shift instruction allows you to change masks during program execution.
  6264.  
  6265.  Masks for logical instructions can be shifted to new bit positions. For
  6266.  example, an operand that masks off a bit or group of bits can be shifted to
  6267.  move the mask to a different position, allowing you to mask off a different
  6268.  bit each time the mask is used. This technique, illustrated in the following
  6269.  example, is useful only if the mask value is unknown until run time.
  6270.  
  6271.  
  6272.    .DATA
  6273.    masker  BYTE    00000010y   ; Mask that may change at run time
  6274.            .CODE
  6275.            .
  6276.            .
  6277.            .
  6278.            mov     cl, 2       ; Rotate two at a time
  6279.            mov     bl, 57h     ; Load value to be changed 01010111y
  6280.            rol     masker, cl  ; Rotate two to left       00001000y
  6281.            or      bl, masker  ; Turn on masked values    ---------
  6282.                                ; New value is 05Fh        01011111y
  6283.            rol     masker, cl  ; Rotate two more          00100000y
  6284.            or      bl, masker  ; Turn on masked values    ---------
  6285.                                ; New value is 07Fh        01111111y
  6286.  
  6287.  Starting with the 80186 processor, you can use eight-bit immediate values
  6288.  larger than 1 as the source operand for shift or rotate instructions, as
  6289.  shown below:
  6290.  
  6291.    shr     bx, 4   ;  9 clocks, 3 bytes on 80286
  6292.  
  6293.  The following statements are equivalent if the program must run on the 8088
  6294.  or 8086 processor:
  6295.  
  6296.    mov     cl, 4   ;  2 clocks, 3 bytes on 80286
  6297.            shr     bx, cl  ;  9 clocks, 2 bytes on 80286
  6298.                            ; 11 clocks, 5 bytes
  6299.  
  6300.  
  6301.  4.3.3  Multiplying and Dividing with Shift Instructions
  6302.  
  6303.  You can use the shift and rotate instructions (SHR, SHL, SAR, and SAL) for
  6304.  multiplication and division. Shifting an integer right by one bit has the
  6305.  effect of dividing by two; shifting left by one bit has the effect of
  6306.  multiplying by two. You can take advantage of shifts to do fast
  6307.  multiplication and division by powers of two. For example, shifting left
  6308.  twice multiplies by four, shifting left three times multiplies by eight, and
  6309.  so on.
  6310.  
  6311.  Use SHR (Shift Right) to divide unsigned numbers. You can use SAR (Shift
  6312.  Arithmetic Right) to divide signed numbers, but SAR rounds numbers down─IDIV
  6313.  always rounds up. Division using SAR must adjust for this difference.
  6314.  Multiplication by shifting is the same for signed and unsigned numbers, so
  6315.  you can use either SAL or SHL.
  6316.  
  6317.  Use shifts instead of MUL or DIV to optimize your code.
  6318.  
  6319.  Since the multiply and divide instructions are very slow on the 8088 and
  6320.  8086 processors, using shifts instead can often speed operations by a factor
  6321.  of 10 or more. For example, on the 8088 or 8086 processor, these statements
  6322.  take only four clocks:
  6323.  
  6324.    sub     ah, ah    ; Clear AH
  6325.            shl     ax, 1     ; Multiply byte in AL by 2
  6326.  
  6327.  The following statements produce the same results, but take between 74 and
  6328.  81 clocks on the 8088 or 8086. The same statements take 15 clocks on the
  6329.  80286 and between 11 and 16 clocks on the 80386.
  6330.  
  6331.    mov     bl, 2     ; Multiply byte in AL by 2
  6332.            mul     bl
  6333.  
  6334.  You can put multiplication and division operations in macros so they can be
  6335.  changed if the constants in a program change, as shown in the two macros
  6336.  below.
  6337.  
  6338.    mul_10  MACRO   factor       ; Factor must be unsigned
  6339.            mov     ax, factor   ; Load into AX
  6340.            shl     ax, 1        ; AX = factor * 2
  6341.            mov     bx, ax       ; Save copy in BX
  6342.            shl     ax, 1        ; AX = factor * 4
  6343.            shl     ax, 1        ; AX = factor * 8
  6344.            add     ax, bx       ; AX = (factor * 8) + (factor * 2)
  6345.            ENDM                 ; AX = factor * 10
  6346.  
  6347.    div_512 MACRO   dividend     ; Dividend must be unsigned
  6348.            mov     ax, dividend ; Load into AX
  6349.            shr     ax, 1        ;  AX = dividend / 2 (unsigned)
  6350.            xchg    al, ah       ; xchg is like rotate right 8
  6351.                                 ;  AL = (dividend / 2) / 256
  6352.            cbw                  ; Clear upper byte
  6353.            ENDM                 ;  AX = (dividend / 512)
  6354.  
  6355.  Since RCR and RCL use the carry flag, clear it before multiple-register
  6356.  shifts.
  6357.  
  6358.  If you need to shift a value that is too large to fit in one register, you
  6359.  can shift each part separately. The RCR (Register Carry Right) and RCL
  6360.  (Register Carry Left) instructions carry values from the first register to
  6361.  the second by passing the leftmost or rightmost bit through the carry flag.
  6362.  
  6363.  
  6364.  This example shifts a multiword value.
  6365.  
  6366.  
  6367.    .DATA
  6368.    mem32    DWORD  500000
  6369.            .CODE
  6370.  
  6371.    ; Divide 32-bit unsigned by 16
  6372.            mov     cx, 4                ; Shift right 4        500000
  6373.    again:  shr     WORD PTR mem32[2], 1 ; Shift into carry  DIV    16
  6374.            rcr     WORD PTR mem32[0], 1 ; Rotate carry in      ------
  6375.            loop    again                ;                       31250
  6376.  
  6377.  Since the carry flag is treated as part of the operand (it's like using a
  6378.  nine-bit or 17-bit operand), the flag value before the operation is crucial.
  6379.  The carry flag can be set by a previous instruction, but you can also set it
  6380.  directly by using the CLC (Clear Carry Flag), CMC (Complement Carry Flag),
  6381.  and STC (Set Carry Flag) instructions.
  6382.  
  6383.  
  6384.  On the 80386 and 80486, an alternate method for multiplying quickly by
  6385.  constants takes advantage of the LEA (Load Effective Address) instruction
  6386.  and the scaling of indirect memory operands. By using a 32-bit value as both
  6387.  the index and the base register in an indirect memory operand, you can
  6388.  multiply by the constants 2, 3, 4, 5, 8, and 9 more quickly than you can by
  6389.  using the MUL instruction. LEA calculates the offset of the source operand
  6390.  and stores it into the destination register, EBX, as this example shows:
  6391.  
  6392.    lea     ebx, [eax*2]        ; EBX = 2 * EAX
  6393.            lea     ebx, [eax*2+eax]    ; EBX = 3 * EAX
  6394.            lea     ebx, [eax*4]        ; EBX = 4 * EAX
  6395.            lea     ebx, [eax*4+eax]    ; EBX = 5 * EAX
  6396.            lea     ebx, [eax*8]        ; EBX = 8 * EAX
  6397.            lea     ebx, [eax*8+eax]    ; EBX = 9 * EAX
  6398.  
  6399.  Section 3.2.4.3, "Indirect Memory Operands with 32-Bit Registers," discusses
  6400.  scaling of 80386 indirect memory operands, and Section 3.3.3.2, "Loading
  6401.  Addresses into Registers," introduces LEA.
  6402.  
  6403.  This chapter has covered the integer operations you use in your MASM
  6404.  programs. The next chapter looks at more complex data types─arrays, strings,
  6405.  structures, unions, and records. Many of the operations presented in this
  6406.  chapter can also be applied to the data structures discussed in Chapter 5,
  6407.  "Defining and Using Complex Data Types."
  6408.  
  6409.  
  6410.  4.4  Related Topics in Online Help
  6411.  
  6412.  Online help features additional information about the topics discussed in
  6413.  this chapter. From the "MASM 6.0 Contents" screen for MASM online help,
  6414.  select the following topics:
  6415.  
  6416. ╓┌─────────────────────────────────────┌─────────────────────────────────────╖
  6417.  Topic                                 Access
  6418.  ────────────────────────────────────────────────────────────────────────────
  6419.  BYTE, WORD, ...                       Choose "Directives" and then "Data
  6420.                                        Allocation"
  6421.  
  6422.  Bitwise logical operations            Choose "Operators" and then from the
  6423.                                        list of operators, choose "Logical
  6424.                                        and Shift"
  6425.  
  6426.  Location counter                      Choose "Predefined Symbols" for
  6427.                                        information on the $ symbol
  6428.  Topic                                 Access
  6429.  ────────────────────────────────────────────────────────────────────────────
  6430.                                       information on the $ symbol
  6431.  
  6432.  BSF, BSR, SHLD, SHRD, and SET         From the "Processor Instructions"
  6433.  condition                             categories, choose "Logical and
  6434.                                        Shift"
  6435.  
  6436.  LES,  LFS,  LGS                       From the "Processor Instructions"
  6437.                                        categories, choose "Data Transfer"
  6438.  
  6439.  .RADIX directive                      Choose "Directives" and then choose
  6440.                                        "Miscellaneous"
  6441.  
  6442.  MOD                                   Choose "Operators," and then
  6443.                                        "Arithmetic"
  6444.  
  6445.  OPATTR, .TYPE, HIGH, LOW, HIGHWORD,   Choose "Operators," then
  6446.  and  LOWWORD                          "Miscellaneous"
  6447.  
  6448.  OPTION EXPR32,                        Choose "Directives," and then
  6449.  Topic                                 Access
  6450.  ────────────────────────────────────────────────────────────────────────────
  6451. OPTION EXPR32,                        Choose "Directives," and then
  6452.  OPTION EXPR16,                        "OPTION"
  6453.  
  6454.  
  6455.  
  6456.  
  6457.  
  6458.  
  6459.  
  6460.  
  6461.  Chapter 5  Defining and Using Complex Data Types
  6462.  ────────────────────────────────────────────────────────────────────────────
  6463.  
  6464.  With the complex data types available in MASM 6.0─arrays, strings, records,
  6465.  structures, and (new to version 6.0) unions─you can access data either as a
  6466.  unit or as individual elements that make up the unit. The individual
  6467.  elements of complex data types are often the integer types discussed in
  6468.  Chapter 4, "Defining and Using Integers."
  6469.  
  6470.  Section 5.1 first discusses how to declare, reference, and initialize arrays
  6471.  and strings. This section summarizes the general steps needed to process
  6472.  arrays and strings and describes the MASM instructions for moving,
  6473.  comparing, searching, loading, and storing operations.
  6474.  
  6475.  Section 5.2 covers similar information for structures and unions: how to
  6476.  declare structure and union types, how to define structure and union
  6477.  variables, and how to reference structures and unions and their fields.
  6478.  
  6479.  Section 5.3 explains how to declare record types, define record variables,
  6480.  and use record operators.
  6481.  
  6482.  All three sections also describe how to use the LENGTHOF, SIZEOF, and TYPE
  6483.  operators with each complex data type.
  6484.  
  6485.  
  6486.  5.1  Arrays and Strings
  6487.  
  6488.  An assembly-language array is a sequence of fixed-size variables. A string
  6489.  is an array of characters. You can access the elements in an array or string
  6490.  relative to the first element.
  6491.  
  6492.  This section explains and illustrates the essential ways to handle arrays
  6493.  and strings in your programs. It covers arrays first, beginning with the two
  6494.  ways to declare an array and continuing with how to reference it. The
  6495.  section then explains the special requirements for declaring and
  6496.  initializing a string. Finally, it describes the processing of arrays and
  6497.  strings.
  6498.  
  6499.  
  6500.  5.1.1  Declaring and Referencing Arrays
  6501.  
  6502.  You can declare an array in two ways: you can specify a list of array
  6503.  elements, or you can use the DUP operator to specify a group of identical
  6504.  elements.
  6505.  
  6506.  To declare an array, you must supply a label name, a type, and a series of
  6507.  elements separated by commas. You can access each element of an array
  6508.  relative to the first. In the examples below,  warray  and  xarray  are
  6509.  arrays.
  6510.  
  6511.    warray  WORD    1, 2, 3, 4
  6512.    xarray  DWORD   OFFFh, OAAAh
  6513.  
  6514.  The assembler stores the elements consecutively in memory, with the first
  6515.  address referenced by the label name.
  6516.  
  6517.  Initializer lists can be longer than one line.
  6518.  
  6519.  Beginning with MASM 6.0, initializer lists of array declarations can span
  6520.  multiple lines. The first initializer must appear on the same line as the
  6521.  data type, all entries must be initialized, and, if you want the array to
  6522.  continue to the new line, the line must end with a comma. These examples
  6523.  show legal multiple-line array declarations:
  6524.  
  6525.    big             BYTE    21, 22, 23, 24, 25,
  6526.                            26, 27, 28
  6527.  
  6528.    somelist        WORD    10,
  6529.                            20,
  6530.                            30
  6531.  
  6532.  If you do not want to use the new LENGTHOF and SIZEOF operators discussed
  6533.  later in this section, then an array may span more than one logical line,
  6534.  although a separate type declaration is needed on each logical line:
  6535.  
  6536.    var1    BTYE    10, 20, 30
  6537.            BYTE    40, 50, 60
  6538.            BYTE    70, 80, 90
  6539.  
  6540.  
  6541.  The DUP Operator
  6542.  
  6543.  You can also declare an array with the DUP operator. This operator can be
  6544.  used with any of the data allocation directives described in Section 4.1.1.
  6545.  In the syntax
  6546.  
  6547.    count DUP (initialvalue [[,initialvalue]]...)
  6548.  
  6549.  the count value sets the number of times to repeat the last initialvalue.
  6550.  Each initial value is evaluated only once and can be any expression that
  6551.  evaluates to an integer value, a character constant, or another DUP
  6552.  operator. The initial value (or values) must always be placed within
  6553.  parentheses. For example, the statement
  6554.  
  6555.    barray  BYTE    5 DUP (1)
  6556.  
  6557.  allocates the integer  1  five times for a total of five bytes.
  6558.  
  6559.  The following examples show various ways to use the DUP operator to allocate
  6560.  data elements.
  6561.  
  6562.    array   DWORD   10 DUP (1)                    ; 10 doublewords
  6563.                                                  ;  initialized to 1
  6564.    buffer  BYTE    256 DUP (?)                   ; 256-byte buffer
  6565.  
  6566.    masks   BYTE    20 DUP (040h, 020h, 04h, 02h) ; 80-byte buffer
  6567.                                                  ;  with bit masks
  6568.    three_d DWORD   5 DUP (5 DUP (5 DUP (0)))     ; 125 doublewords
  6569.                                                  ;  initialized to 0
  6570.  
  6571.  
  6572.  Referencing Arrays
  6573.  
  6574.  Once an array is defined, you can refer to its first element by typing the
  6575.  array name (no brackets required). The array name refers to the first object
  6576.  of the given type in the list of initial values.
  6577.  
  6578.  If  warray  has been defined as
  6579.  
  6580.    warray WORD 2, 4, 6, 8, 10
  6581.  
  6582.  then referencing  warray  in your program refers to the first word─the word
  6583.  containing  2.
  6584.  
  6585.  To refer to the next element (in an array of words), use either of these two
  6586.  forms, each of which refers to the array element two bytes past the
  6587.  beginning of warray:
  6588.  
  6589.    warray+2
  6590.    warray[2]
  6591.  
  6592.  This element can be used as you would any data item:
  6593.  
  6594.    mov     ax, warray[2]
  6595.            push    warray+2
  6596.  
  6597.  When used with a variable name, brackets only add a number to the address.
  6598.  If  warray  refers to the address  2400h, then  warray[2]  refers to the
  6599.  address  2402h. The BOUND instruction (80186-80486 only) can be used to
  6600.  verify that an index value is within the bounds of an array.
  6601.  
  6602.  Array indexes are not scaled. The index is a distance in bytes.
  6603.  
  6604.  In assembly language, array indexes are zero-based and unscaled. The number
  6605.  within brackets always represents an absolute distance in bytes. In
  6606.  practical terms, the fact that indexes are unscaled means that if an element
  6607.  is larger than one byte, you must multiply the index of the element by its
  6608.  size (in the example above,  2), and then add the result to the address of
  6609.  the array. Thus, the expression  warray[4]  represents the third element,
  6610.  which is four bytes past the beginning of the array. Similarly, the
  6611.  expression  warray[6]  represents the fourth element.
  6612.  
  6613.  You can also determine an index at run time:
  6614.  
  6615.    mov     si, cx          ; CX holds index value
  6616.            shl     si, 7           ; Scale for word referencing
  6617.            mov     ax, warray[si]  ; Move element into AX
  6618.  
  6619.  The offset required to access an array element can be calculated with the
  6620.  following formula:
  6621.  
  6622.  nth element of array = array[(n-1) * size of element]
  6623.  
  6624.  
  6625.  LENGTHOF, SIZEOF, and TYPE for Arrays
  6626.  
  6627.  When applied to arrays, the LENGTHOF, SIZEOF, and TYPE operators return
  6628.  information about the length and size of the array and about the type of the
  6629.  initializers.
  6630.  
  6631.  The LENGTHOF operator returns the number of items in the definition. It can
  6632.  be applied only to an integer label. This is useful for determining the
  6633.  number of elements you need to process in an array of integers. For an array
  6634.  or string label, SIZEOF returns the number of bytes used by the initializers
  6635.  in the definition. TYPE returns the size of the elements of the array. These
  6636.  examples illustrate these operators:
  6637.  
  6638.    array   WORD    40 DUP (5)
  6639.  
  6640.    larray  EQU     LENGTHOF array    ; 40 elements
  6641.    sarray  EQU     SIZEOF   array    ; 80 bytes
  6642.    tarray  EQU     TYPE     array    ;  2 bytes per element
  6643.  
  6644.    num     DWORD   4, 5, 6, 7,
  6645.                    8, 9, 10, 11
  6646.  
  6647.    lnum    EQU     LENGTHOF num      ;  8 elements
  6648.    snum    EQU     SIZEOF   num      ; 32 bytes
  6649.    tnum    EQU     TYPE     num      ;  4 bytes per element
  6650.  
  6651.    warray  WORD    40 DUP (40 DUP (5))
  6652.  
  6653.    len     EQU     LENGTHOF warray   ; 1600 elements
  6654.    siz     EQU     SIZEOF   warray   ; 3200 bytes
  6655.    typ     EQU     TYPE     warray   ;    2 bytes per element
  6656.  
  6657.  
  6658.  5.1.2  Declaring and Initializing Strings
  6659.  
  6660.  A string is an array of bytes. Initializing a string like  "Hello, there"
  6661.  allocates and initializes one byte for each character in the string. An
  6662.  initialized string can be no longer than 255 characters.
  6663.  
  6664.  Strings declared with types other than BYTE must fit the memory space
  6665.  allocated.
  6666.  
  6667.  For data directives other than BYTE, a string may initialize only a single
  6668.  element. This element must be short enough to fit into the specified size
  6669.  and conform to the expression word size in effect (see Section
  6670.  1.2.4,"Integer Constants and Constant Expressions"), as shown in these
  6671.  examples:
  6672.  
  6673.    wstr    WORD    "OK"
  6674.    dstr    DWORD   "ADCD"  ; Legal under EXPR32 only
  6675.  
  6676.  As with arrays, string initializers can span multiple lines. The line must
  6677.  end with a comma if you want the string to continue to the next line.
  6678.  
  6679.    str1    BYTE    "This is a long string that does not ",
  6680.                    "fit on one line."
  6681.  
  6682.  You can also have an array of pointers to strings. For example:
  6683.  
  6684.    PBYTE   TYPEDEF PTR BYTE
  6685.            .DATA
  6686.    msg1    BYTE    "Operation completed successfully."
  6687.    msg2    BYTE    "Unknown command"
  6688.    msg3    BYTE    "File not found"
  6689.    pmsg1   PBYTE   msg1
  6690.    pmsg2   BPBYTE  msg2
  6691.    pmsg3   PBYTE   msg3
  6692.  
  6693.    errors  WORD    pmsg1, pmsg2, pmsg3    ; An array of pointers
  6694.                                           ;  to strings
  6695.  
  6696.  Strings must be enclosed in single (') or double (") quotation marks. To put
  6697.  a single quotation mark inside a string enclosed by single quotation marks,
  6698.  use two single quotation marks. Likewise, if you need quotation marks inside
  6699.  a string enclosed by double quotation marks, use two sets. These examples
  6700.  show the various uses of quotation marks:
  6701.  
  6702.    char    BYTE    'a'
  6703.    message BYTE    "That's the message."       ; That's the message.
  6704.    warn    BYTE    'Can''t find file.'         ; Can't find file.
  6705.    string  BYTE    "This ""value"" not found." ; This "value"
  6706.  
  6707.                                                  not found.
  6708.  
  6709.  You can always use single quotation marks inside a string enclosed by double
  6710.  quotation marks, as the initialization for  message  shows, and vice versa.
  6711.  
  6712.  
  6713.  
  6714.  The ? Initializer
  6715.  
  6716.  The actual values stored when you use ? depend on the other data in your
  6717.  program.
  6718.  
  6719.  You do not have to initialize all elements in an array to a value. If there
  6720.  is no initial value, you can initialize the array elements with the ?
  6721.  operator. The ? operator either is treated as a zero or causes a byte to be
  6722.  left unspecified in the object file. Object files contain records for
  6723.  initialized data. An unspecified byte left in the object file means that no
  6724.  records contain initialized data for that address.
  6725.  
  6726.  The actual values stored in arrays allocated with ? depend on certain
  6727.  conditions. The ? initializer is treated as a zero in a DUP statement that
  6728.  contains initializers in addition to the ? initializer. An unspecified byte
  6729.  is left in the object file if the ? initializer does not appear in a DUP
  6730.  statement, or if the DUP statement contains only ? initializers for nested
  6731.  DUP statements.
  6732.  
  6733.  
  6734.  Length-Specified Strings
  6735.  
  6736.  Often there are reasons to know the length of a string. To use the DOS
  6737.  functions for writing to a file, for example, CX must contain the length of
  6738.  the string before the interrupt is called, as shown in this example.
  6739.  
  6740.    msg     BYTE    "This is a length-specified string"
  6741.            .
  6742.            .
  6743.            .
  6744.            mov     ah, 40h
  6745.            mov     bx, 1
  6746.            mov     cx, LENGTHOF msg
  6747.            mov     dx, OFFSET msg
  6748.            int     21h
  6749.  
  6750.  Some high-level languages also expect strings passed to procedures to have a
  6751.  certain format. For example, Pascal procedures require the first byte of a
  6752.  string passed as a parameter to contain the length of the string. You can
  6753.  write this length into the first byte with
  6754.  
  6755.    msg     BYTE    LENGTHOF msg - 1, "This is a Pascal string"
  6756.  
  6757.  Interfacing with high-level languages requires special techniques with
  6758.  strings.
  6759.  
  6760.  Other languages such as Basic have string descriptions─a kind of structure
  6761.  containing both the length and the address of the string. For example, this
  6762.  structure  DESC  could be used in a procedure accessed from Basic:
  6763.  
  6764.    DESC    STRUCT
  6765.      len   WORD    ?       ; Length of string1
  6766.      off   WORD    ?       ; Offset of string1
  6767.    DESC    ENDS
  6768.  
  6769.    string1 BYTE    "This string goes in a string descriptor"
  6770.    msg     DESC    {LENGTHOF string1, string1}
  6771.  
  6772.  See Section 5.2, "Structures and Unions."
  6773.  
  6774.  
  6775.  Null-Terminated and $-Terminated Strings
  6776.  
  6777.  Null-terminated and $-terminated strings have a special use with DOS
  6778.  functions. Strings in modules shared with C need to end with a null
  6779.  character (0).
  6780.  
  6781.    str1    BYTE    "This string ends with a null character", 0
  6782.  
  6783.  DOS file names also require a null character at the end. This example opens
  6784.  a file named  "MYFILE.ASM".
  6785.  
  6786.    name1   BYTE    "MYFILE.ASM", 0
  6787.            .
  6788.            .
  6789.            .
  6790.            mov     ah, 3Dh
  6791.            mov     dx, OFFSET name1
  6792.            int     21h
  6793.  
  6794.  DOS function 9 requires a string to end with a dollar sign ($) so that it
  6795.  can recognize the end of the string to write to the screen, as shown in this
  6796.  example.
  6797.  
  6798.    msg     BYTE    "This is a dollar-terminated string$"
  6799.            .
  6800.            .
  6801.            .
  6802.            mov     ah, 09h
  6803.            mov     dx, OFFSET msg
  6804.            int     21h
  6805.  
  6806.  
  6807.  LENGTHOF, SIZEOF, and TYPE for Strings
  6808.  
  6809.  Because the assembler considers strings as simply arrays of byte elements,
  6810.  the LENGTHOF and SIZEOF operators return the same values for strings as they
  6811.  do for arrays, as illustrated in this example. The TYPE operator considers
  6812.  msg  to be one data unit and returns 1.
  6813.  
  6814.    msg     BYTE    "This string extends ",
  6815.                    "over three ",
  6816.                    "lines."
  6817.  
  6818.    lmsg    EQU     LENGTHOF msg      ; 37 elements
  6819.    smsg    EQU     SIZEOF   msg      ; 37 bytes
  6820.    tmsg    EQU     TYPE     msg      ;  1 byte per element
  6821.  
  6822.  
  6823.  5.1.3  Processing Arrays and Strings
  6824.  
  6825.  The 8086-family instruction set has seven string instructions for fast and
  6826.  efficient processing of entire strings and arrays. The term "string" in
  6827.  "string instructions" refers to a sequence of elements, not just character
  6828.  strings. These instructions work directly only on arrays of bytes and words
  6829.  on the 8086-80486 and on arrays of bytes, words, and doublewords on the
  6830.  80386 and 80486. Processing larger elements must be done indirectly with
  6831.  loops.
  6832.  
  6833.  
  6834.  The following list gives capsule descriptions of the five instructions
  6835.  discussed in this section. Two additional instructions not described here
  6836.  are the INS and OUTS instructions that transfer values to and from a memory
  6837.  port.
  6838.  
  6839.  Instruction   Description
  6840.  ────────────────────────────────────────────────────────────────────────────
  6841.  MOVS          Copies a string from one location to another
  6842.  STOS          Stores values from the accumulator register to a string
  6843.  CMPS          Compares values in one string with values in another
  6844.  LODS          Loads values from a string to the accumulator register
  6845.  SCAS          Scans a string for a specified value
  6846.  
  6847.  All of these instructions use registers in a similar way and have a similar
  6848.  syntax. Most are used with the repeat instruction prefixes REP, REPE (or
  6849.  REPZ), and REPNE (or REPNZ). REPZ is a synonym for REPE (Repeat While Equal)
  6850.  and REPNZ is a synonym for REPNE (Repeat While Not Equal).
  6851.  
  6852.  
  6853.  This section first explains the general procedures for using all string
  6854.  instructions. It then illustrates each instruction with an example.
  6855.  
  6856.  
  6857.  5.1.3.1  Overview of String Operations
  6858.  
  6859.  The string instructions have specific requirements for the location of
  6860.  strings and the use of registers. To operate on any string, follow these
  6861.  three steps:
  6862.  
  6863.  All string operations follow three basic steps.
  6864.  
  6865.  
  6866.    1.  Set the direction flag to indicate the direction in which you want to
  6867.        process the string. The STD instruction sets the flag, while CLD
  6868.        clears it.
  6869.  
  6870.        If the direction flag is clear, the string is processed upward (from
  6871.        low addresses to high addresses, which is from left to right through
  6872.        the string). If the direction flag is set, the string is processed
  6873.        downward (from high addresses to low addresses, or from right to
  6874.        left). Under DOS, the direction flag is normally clear if your program
  6875.        has not changed it.
  6876.  
  6877.    2.  Load the number of iterations for the string instruction into the CX
  6878.        register.
  6879.  
  6880.        If you want to process a 100-byte string, move 100 into CX. If you
  6881.        wish the string instruction to terminate conditionally (for example,
  6882.        during a search when a match is found), load the maximum number of
  6883.        iterations that can be performed without an error.
  6884.  
  6885.    3.  Load the starting offset address of the source string into DS:SI and
  6886.        the start-ing address of the destination string into ES:DI. Some
  6887.        string instructions take only a destination or source, not both (see
  6888.        Table 5.1).
  6889.  
  6890.        Normally, the segment address of the source string should be DS, but
  6891.        you can use a segment override to specify a different segment for the
  6892.        source operand. You cannot override the segment address for the
  6893.        destination string. Therefore, you may need to change the value of ES.
  6894.        See Section 3.1 for information on changing segment registers.
  6895.  
  6896.  ────────────────────────────────────────────────────────────────────────────
  6897.  NOTE
  6898.  Although you can use a segment override on the source operand, a segment
  6899.  override combined with a repeat prefix can cause problems in certain
  6900.  situations on all processors except the 80386/486. If an interrupt occurs
  6901.  during the string operation, the segment override is lost and the rest of
  6902.  the string operation processes incorrectly. Segment overrides can be used
  6903.  safely when interrupts are turned off or with an 80386/486
  6904.  processor.───────────────────────────────────────────────────────────────────
  6905.  
  6906.  
  6907.  
  6908.  You can adapt these steps to the requirements of any particular string
  6909.  operation. The syntax for the string instructions is:
  6910.  
  6911.    «prefix» CMPS «segmentregister:»
  6912.    source, «ES:» destination
  6913.                   LODS «segmentregister:» source
  6914.    «prefix» MOVS «ES:» destination,
  6915.    «segmentregister:» source
  6916.    «prefix» SCAS «ES:» destination
  6917.    «prefix» STOS «ES:« destination
  6918.  
  6919.  Some instructions have special forms for byte, word, or doubleword operands.
  6920.  If you use the form of the instruction that ends in B (BYTE), W (WORD), or D
  6921.  (DWORD) with LODS, SCAS, and STOS, the assembler knows whether the element
  6922.  is in the AL, AX, or EAX register. Therefore, these instruction forms do not
  6923.  require operands.
  6924.  
  6925.  Table 5.1 lists each string instruction with the type of repeat prefix it
  6926.  uses and indicates whether the instruction works on a source, a destination,
  6927.  or both.
  6928.  
  6929.  Table 5.1  Requirements for String Instructions
  6930.  
  6931. ╓┌─────────────┌───────────────┌───────────────────┌─────────────────────────╖
  6932.  Instruction   Repeat Prefix   Source/Destination  Register Pair
  6933.  ────────────────────────────────────────────────────────────────────────────
  6934.  MOVS          REP             Both                DS:SI, ES:DI
  6935.  SCAS          REPE/REPNE      Destination         ES:DI
  6936.  CMPS          REPE/REPNE      Both                DS:SI, ES:DI
  6937.  LODS          None            Source              DS:SI
  6938.  STOS          REP             Destination         ES:DI
  6939.  INS           REP             Destination         ES:DI
  6940.  OUTS          REP             Source              DS:SI
  6941.  ────────────────────────────────────────────────────────────────────────────
  6942.  
  6943.  
  6944.  The instruction automatically increments DI or SI.
  6945.  
  6946.  The repeat prefix causes the instruction that follows it to repeat for the
  6947.  number of times specified in the count register or until a condition becomes
  6948.  true. After each iteration, the instruction increments or decrements SI and
  6949.  DI so that it points to new array elements. The string instructions work on
  6950.  these elements. The direction flag determines whether SI and DI are
  6951.  incremented (flag clear) or decremented (flag set). The size of the
  6952.  instruction determines whether SI and DI are altered by one, two, or four
  6953.  bytes each time.
  6954.  
  6955.  These are the conditions that determine the number of repetitions specified
  6956.  by a prefix.
  6957.  
  6958.  Prefix                            Description
  6959.  ────────────────────────────────────────────────────────────────────────────
  6960.  REP                               Repeats instruction CX times
  6961.  
  6962.  REPE, REPZ                        Repeats instruction CX times, or as long
  6963.                                    as elements are equal, whichever is
  6964.                                    fewer
  6965.  
  6966.  REPNE, REPNZ                      Repeats instruction CX times, or as long
  6967.                                    as elements are not equal, whichever is
  6968.                                    fewer
  6969.  
  6970.  
  6971.  The prefixes apply to only one string instruction at a time. To repeat a
  6972.  block of instructions, use a loop construction (see Section 7.2, "Loops").
  6973.  
  6974.  At run time, if a string instruction is preceded by a repeat sequence, the
  6975.  processor takes the following steps:
  6976.  
  6977.  
  6978.    1.  Checks the CX register and exits if CX is 0. If the REPE prefix is
  6979.        used, the loop exits if the zero flag is set; if REPNE is used, the
  6980.        loop exits if the zero flag is clear.
  6981.  
  6982.    2.  Performs the string operation once.
  6983.  
  6984.    3.  Increases SI and/or DI if the direction flag is clear. Decreases SI
  6985.        and/or DI if the direction flag is set. The amount of increase or
  6986.        decrease is 1 for byte operations, 2 for word operations, and 4 for
  6987.        doubleword operations (80386/486 only).
  6988.  
  6989.    4.  Decrements CX (no flags are modified).
  6990.  
  6991.    5.  Checks the zero flag at this point if the REPE or REPNE prefix is used
  6992.        (for SCAS or CMPS). If the repeat condition does not hold, execution
  6993.        proceeds to the next instruction.
  6994.  
  6995.    6.  Proceeds to the next iteration and repeats from step 1.
  6996.  
  6997.  
  6998.  At loop end, SI and DI point to the element immediately after the match.
  6999.  
  7000.  When the repeat loop ends, SI (or DI) points to the position following a
  7001.  match (when using SCAS or CMPS), so you need to decrement or increment DI or
  7002.  SI to point to the element where the match occurred.
  7003.  
  7004.  Although string instructions (except LODS) are most often used with repeat
  7005.  prefixes, they can also be used by themselves. In this case, the SI and/or
  7006.  DI registers are adjusted as specified by the direction flag and the size of
  7007.  operands. However, you must decrement the CX register and set up a loop for
  7008.  the repeated action.
  7009.  
  7010.  
  7011.  5.1.3.2  String Instructions
  7012.  
  7013.  To use the 8086-family string instructions, apply the steps outlined in the
  7014.  previous section. Examples in this section illustrate each instruction.
  7015.  
  7016.  You can also use the techniques in this section with structures and unions,
  7017.  since arrays and strings can be fields in structures and unions (see Section
  7018.  5.2).
  7019.  
  7020.  Moving Array Data - The MOVS instruction copies data from one area of memory
  7021.  to another. To move data, first load the count and the source and
  7022.  destination addresses into the appropriate registers. Then use REP with the
  7023.  MOVS instruction.
  7024.  
  7025.    .MODEL  small
  7026.            .DATA
  7027.    source  BYTE    10 DUP ('0123456789')
  7028.    destin  BYTE    100 DUP (?)
  7029.            .CODE
  7030.            mov     ax, @data           ; Load same segment
  7031.            mov     ds, ax              ;  to both DS
  7032.            mov     es, ax              ;  and ES
  7033.            .
  7034.            .
  7035.            .
  7036.            cld                         ; Work upward
  7037.            mov     cx, LENGTHOF source ; Set iteration count to 100
  7038.            mov     si, OFFSET source   ; Load address of source
  7039.            mov     di, OFFSET destin   ; Load address of destination
  7040.            rep     movsb               ; Move 100 bytes
  7041.  
  7042.  Storing Data in Arrays - The STOS instruction stores a specified value in
  7043.  each position of a string. The string is the destination, so it must be
  7044.  pointed to by ES:DI. The value to store must be in the accumulator.
  7045.  
  7046.  This example stores the character  'a'  in each byte of a 100-byte string.
  7047.  Notice that it does this by storing 50 words rather than 100 bytes. This
  7048.  makes the code faster by reducing the number of iterations. To fill an odd
  7049.  number of bytes, you would have to adjust for the last byte.
  7050.  
  7051.    .MODEL  small, C
  7052.            .DATA
  7053.    destin  BYTE    100 DUP (?)
  7054.    ldestin EQU     (LENGTHOF destin) / 2
  7055.            .CODE
  7056.            .                           ; Assume ES = DS
  7057.            .
  7058.            .
  7059.            cld                         ; Work upward
  7060.            mov     ax, 'aa'            ; Load character to fill
  7061.            mov     cx, ldestin         ; Load length of string
  7062.            mov     di, OFFSET destin   ; Load address of destination
  7063.            rep     stosw               ; Store 'aa' into array
  7064.  
  7065.  Comparing Arrays - The CMPS instruction compares two strings and points to
  7066.  the address after which a match or nonmatch occurs. If the values are the
  7067.  same, the zero flag is set. Either string can be considered as the
  7068.  destination or the source unless a segment override is used.
  7069.  
  7070.  This example using CMPSB assumes that the strings are in different segments.
  7071.  Both segments must be initialized to the appropriate segment register.
  7072.  
  7073.    .MODEL  large, C
  7074.            .DATA
  7075.    string1 BYTE    "The quick brown fox jumps over the lazy dog"
  7076.            .FARDATA
  7077.    string2 BYTE    "The quick brown dog jumps over the lazy fox"
  7078.    lstring EQU     LENGTHOF string2
  7079.            .CODE
  7080.            mov     ax, @data           ; Load data segment
  7081.            mov     ds, ax              ;  into DS
  7082.            mov     ax, @fardata        ; Load far data segment
  7083.            mov     es, ax              ;  into ES
  7084.            .
  7085.            .
  7086.            .
  7087.            cld                         ; Work upward
  7088.            mov     cx, lstring         ; Load length of string
  7089.            mov     si, OFFSET string1  ; Load offset of string1
  7090.            mov     di, OFFSET string2  ; Load offset of string2
  7091.            repe    cmpsb               ; Compare
  7092.            jcxz    allmatch            ; CX is 0 if no nonmatch
  7093.            .
  7094.            .
  7095.            .
  7096.    allmatch:                           ; Special case for all match
  7097.  
  7098.  Loading Data from Arrays - The LODS instruction loads a value from a string
  7099.  into a register. The string is the source; the value is in the accumulator.
  7100.  This instruction normally is not used with a repeat instruction prefix,
  7101.  since something must be done with each element before going on to the next.
  7102.  
  7103.  The code in this example loads, processes, and displays each byte in a
  7104.  string of bytes.
  7105.  
  7106.    .DATA
  7107.    info    BYTE    0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  7108.    linfo   WORD    LENGTHOF info
  7109.            .CODE
  7110.            .
  7111.            .
  7112.            .
  7113.            cld                       ; Work upward
  7114.            mov     cx, linfo         ; Load length
  7115.            mov     si, OFFSET info   ; Load offset of source
  7116.            mov     ah, 2             ; Display character function
  7117.  
  7118.    get:
  7119.            lodsb                     ; Get a character
  7120.            add     al, '0'           ; Convert to ASCII
  7121.            mov     dl, al            ; Move to DL
  7122.            int     21h               ; Call DOS to display character
  7123.            loop    get               ; Repeat
  7124.  
  7125.  Searching Arrays - The SCAS instruction scans a string for a specified
  7126.  value. As the loop executes, this instruction compares the value pointed to
  7127.  by DI with the value in the accumulator. If values are the same, the zero
  7128.  flag is set.
  7129.  
  7130.  After a REPNE SCAS, the zero flag is cleared if no match was found. After a
  7131.  REPE SCAS, the zero flag is set if all values matched.
  7132.  
  7133.  This example assumes that ES is not the same as DS and that the address of
  7134.  the string is stored in a pointer variable. The LES instruction loads the
  7135.  far address of the string into ES:DI.
  7136.  
  7137.    .DATA
  7138.    string  BYTE    "The quick brown fox jumps over the lazy dog"
  7139.    pstring PBYTE   string             ; Far pointer to string
  7140.    lstring EQU     LENGTHOF string    ; Length of string
  7141.            .CODE
  7142.            .
  7143.            .
  7144.            .
  7145.            cld                        ; Work upward
  7146.            mov     cx, lstring        ; Load length of string
  7147.            les     di, pstring        ; Load address of string
  7148.            mov     al, 'z'            ; Load character to find
  7149.            repne   scasb              ; Search
  7150.            jcxz    notfound           ; CX is 0 if not found
  7151.            .                          ; ES:DI points to character
  7152.            .                          ;  after first 'z'
  7153.            .
  7154.    notfound:                          ; Special case for not found
  7155.  
  7156.  
  7157.  5.2  Structures and Unions
  7158.  
  7159.  A structure is a group of possibly dissimilar data types and variable
  7160.  declarations that can be accessed as a unit or by any of its components. The
  7161.  fields within the structure can have different sizes and data types.
  7162.  
  7163.  Unions are identical to structures, except that the fields of a union
  7164.  overlap in memory, which allows you to define different data formats for the
  7165.  same memory space. Unions can store different types of data depending on the
  7166.  situation. They can also store data as one data type and retrieve it as
  7167.  another data type.
  7168.  
  7169.  Whereas each field in a structure has an offset relative to the first byte
  7170.  of the structure, all the fields in a union start at the same offset. The
  7171.  size of a structure is the sum of its components, while the size of a union
  7172.  is the length of the longest field.
  7173.  
  7174.  A MASM structure is similar to a struct in the C language, a STRUCTURE in
  7175.  FORTRAN, and a RECORD in Pascal. Unions in MASM are similar to unions in C
  7176.  and FORTRAN, and to variant records in Pascal.
  7177.  
  7178.  Follow these steps when using structures and unions:
  7179.  
  7180.  
  7181.    1.  Declare a structure (or union) type.
  7182.  
  7183.    2.  Define one or more variables having that type.
  7184.  
  7185.    3.  Reference the fields directly or indirectly with the field (dot)
  7186.        operator.
  7187.  
  7188.  
  7189.  You can use the entire structure or union variable or just the individual
  7190.  fields as operands in assembler statements. This section explains the
  7191.  allocating, initializing, and nesting of structures and unions.
  7192.  
  7193.  MASM 6.0 extends the functionality of structures and also makes some changes
  7194.  to MASM 5.1 behavior. You can still retain MASM 5.1 behavior if you prefer
  7195.  by specifying OPTION OLDSTRUCTS in your program. See Section 1.3.2 for
  7196.  information about the OPTION directive, and Section 5.2.3 for information
  7197.  about referencing structures and unions.
  7198.  
  7199.  
  7200.  5.2.1  Declaring Structure and Union Types
  7201.  
  7202.  When you declare a structure or union type, you create a template for data
  7203.  that contains the sizes and, optionally, the initial values for fields in
  7204.  the structure or union but that allocates no memory.
  7205.  
  7206.  The STRUCT keyword marks the beginning of a type declaration for a
  7207.  structure. (STRUCT and STRUC are synonyms.) STRUCT and UNION type
  7208.  declarations have the following format:
  7209.  
  7210.    name {STRUCT | UNION}  «alignment»
  7211.    «,NONUNIQUE »
  7212.    fielddeclarations
  7213.    name ENDS
  7214.  
  7215.  The fielddeclarations are a series of one or more variable declarations. You
  7216.  can declare default initial values individually or with the DUP operator
  7217.  (see Section 5.2.2, "Defining Structure and Union Variables"). Section
  7218.  5.2.3, "Referencing Structures, Unions, and Fields," explains the NONUNIQUE
  7219.  keyword. Structures and unions can also be nested in MASM 6.0 (see Section
  7220.  5.2.4).
  7221.  
  7222.  
  7223.  Initializing Fields
  7224.  
  7225.  If you provide initializers for the fields of a structure or union when you
  7226.  declare the type, these initializers become the default value for the fields
  7227.  when you define a variable of that type. Section 5.2.2 explains default
  7228.  initializers.
  7229.  
  7230.  When you initialize the fields of a union type, the type and value of the
  7231.  first field become the default value and type for the union. In this example
  7232.  of an initialized union declaration, the default type for the union is
  7233.  DWORD:
  7234.  
  7235.    DWB     UNION
  7236.      d     DWORD   00FFh
  7237.      w     WORD    ?
  7238.      b     BYTE    ?
  7239.    DWB     ENDS
  7240.  
  7241.  If the size of the first member is less than the size of the union, the
  7242.  assembler initializes the rest of the union to zeros. When initializing
  7243.  strings in a type, make sure the initial values are long enough to
  7244.  accommodate the largest possible string.
  7245.  
  7246.  
  7247.  Field Names
  7248.  
  7249.  Structure and union field names in MASM 6.0 must be unique within a given
  7250.  nesting level because they represent the offset from the beginning of the
  7251.  structure to the corresponding field.
  7252.  
  7253.  A nested structure has its own level.
  7254.  
  7255.  In MASM 6.0, a label and a structure field may have the same name, but not a
  7256.  text macro and a field name. Also, field names between structures need not
  7257.  be unique. Field names do need to be unique if you place OPTION M510 or
  7258.  OPTION OLDSTRUCTS in your code or use the /Zm option from the command line,
  7259.  since versions of MASM prior to 6.0 require unique field names (see Appendix
  7260.  A).
  7261.  
  7262.  
  7263.  Alignment Value and Offsets for Structures
  7264.  
  7265.  Data access to structures is faster on aligned fields than on unaligned
  7266.  fields. Therefore, alignment gains speed at the cost of space. Alignment
  7267.  improves access on 16-bit processors but makes no difference on code
  7268.  executing on an 8-bit 8088 processor.
  7269.  
  7270.  The way the assembler aligns structure fields determines the amount of space
  7271.  required to store a variable of that type. Each field in a structure has an
  7272.  offset relative to 0. If you specify an alignment in the structure
  7273.  declaration (or with the /Zpn command-line option), the offset for each
  7274.  field may be modified by the alignment (or n).
  7275.  
  7276.  The only values accepted for alignment are 1, 2, and 4. The default is 1. If
  7277.  the type declaration includes an alignment, the fields are aligned to the
  7278.  minimum of the field's size and the alignment. Any padding required to reach
  7279.  the correct offset for the field is added prior to allocating the field. The
  7280.  padding consists of zeros and always precedes the field.
  7281.  
  7282.  If the number of bytes in the field is greater than the alignment value, the
  7283.  element will be padded such that the offset of the element is divisible by
  7284.  the alignment value. If the number of bytes is greater than or equal to the
  7285.  alignment value, the offset of the element is padded such that it is
  7286.  divisible by the element size.
  7287.  
  7288.  The size of the structure must also be evenly divisible by the structure
  7289.  alignment value, so zeros may be added at the end of the structure.
  7290.  
  7291.  If neither the alignment nor the /Zp command-line option is used, the offset
  7292.  is incremented by the size of each data directive. This is the same as a
  7293.  default alignment equal to 1. The alignment specified in the type
  7294.  declaration overrides the /Zp command-line option.
  7295.  
  7296.  These examples show how offsets are determined:
  7297.  
  7298.    STUDENT2    STRUCT  2   ; Alignment value is 2
  7299.      score     WORD    1   ; Offset is  0
  7300.      id        BYTE    2   ; Offset is  2
  7301.      year      DWORD   3   ; Offset is  4; one byte padding added
  7302.      sname     BYTE    4   ; Offset is  8
  7303.    STUDENT2    ENDS
  7304.  
  7305.  One byte of padding is added at the end of the first byte-sized field.
  7306.  Otherwise the offset of the  year  field would be 3, which is not divisible
  7307.  by the alignment value of 2. The size of this structure is now 9 bytes.
  7308.  Since 9 is not evenly divisible by 2, one byte of padding is added at the
  7309.  end of  student2.
  7310.  
  7311.    STUDENT4    STRUCT  4            ; Alignment value is 4
  7312.      sname     BYTE    1            ; Offset is  0
  7313.      score     WORD    10 DUP (100) ; Offset is  2
  7314.      year      BYTE    2            ; Offset is 22; 1 byte padding
  7315.                                     ;  added so offset of next field
  7316.                                     ;  is divisible by 4
  7317.      id        DWORD   3            ; Offset is 24
  7318.    STUDENT4    ENDS
  7319.  
  7320.  The alignment value affects memory allocation of structure variables.
  7321.  
  7322.  The alignment value affects the alignment of structure variables, so adding
  7323.  an alignment value affects memory usage. This feature provides compatibility
  7324.  with structures in Microsoft C.
  7325.  
  7326.  With MASM 6.0, C programmers can use the H2INC utility to translate C
  7327.  structures to MASM (see Chapter 16).
  7328.  
  7329.  
  7330.  5.2.2  Defining Structure and Union Variables
  7331.  
  7332.  Once you have declared a structure or union type, variables of that type can
  7333.  be defined. For each variable defined, memory is allocated in the current
  7334.  segment in the format declared by the type. The syntax for defining a
  7335.  structure or union variable is:
  7336.  
  7337.    [[name]] typename < [[initializer
  7338.    [[,initializer]]...]] >
  7339.  
  7340.    [[name]] typename { [[initializer
  7341.    [[,initializer]]...]] }
  7342.  
  7343.    [[name]] typename constant
  7344.    DUP ({ [[initializer [[,initializer]]...]]
  7345.    })
  7346.  
  7347.  The name is the label assigned to the variable. If no name is given, the
  7348.  assembler allocates space for the variable but does not give it a symbolic
  7349.  name. The typename is the name of a previously declared structure or union
  7350.  type.
  7351.  
  7352.  An initializer can be given for each field. The type of each initializer
  7353.  must be the type of the corresponding field defined in the type declaration.
  7354.  For unions, the type of the initializer must be the same as the type for the
  7355.  first field. An initialization list can also be repeated using the DUP
  7356.  operator.
  7357.  
  7358.  The list of initializers can be broken only after a comma unless you use a
  7359.  line continuation character (\) at the end of the line. The last curly brace
  7360.  or angle bracket must appear on the same line as the last initializer. You
  7361.  can also use the line continuation character to extend a line as shown in
  7362.  the  Item4 declaration below. Angle brackets and curly braces can be
  7363.  intermixed in an initialization as long as they match. This example using
  7364.  the  ITEMS  structure illustrates the options for initializing lists:
  7365.  
  7366.    ITEMS       STRUCT
  7367.      Iname     BYTE      'Item Name'
  7368.      Inum      WORD      ?
  7369.      ITYPE     UNION
  7370.        oldtype BYTE      0
  7371.        newtype WORD      ?
  7372.      ENDS
  7373.    ITEMS       ENDS
  7374.            .
  7375.            .
  7376.            .
  7377.            .DATA
  7378.    Item1   ITEMS   < >              ; Accepts default initializers
  7379.    Item2   ITEMS   { }              ; Accepts default initializers
  7380.    Item3   ITEMS   <'Bolts', 126>   ; Overrides default value of first
  7381.                                     ;  2 fields; use default of
  7382.                                     ;  the third field
  7383.    Item4   ITEMS   { \
  7384.                     'Bolts',        ; Item name
  7385.                     126 \           ; Part number
  7386.                    }
  7387.  
  7388.  The angle brackets or curly braces are required even if no initial value is
  7389.  given, as in  Item1  and  Item2  in the example. If initial values are given
  7390.  for more than one field, the values must be separated by commas, as shown in
  7391.   Item3.
  7392.  
  7393.  You need not initialize all fields in a structure. If an initial value is
  7394.  blank, the assembler automatically uses the default initial value of the
  7395.  field, which was originally provided in the structure type declaration. If
  7396.  there is no default value, the field is undefined.
  7397.  
  7398.  For nested structures or unions (see Section 5.2.4), however, these are
  7399.  equivalent:
  7400.  
  7401.    Item5   ITEMS   {'Bolts', ,     }
  7402.    Item6   ITEMS   {'Bolts', , { } }
  7403.  
  7404.  A variable and an array of union type  WB  look like this:
  7405.  
  7406.    WB      UNION
  7407.      w     WORD    ?
  7408.      b     BYTE    ?
  7409.    WB      ENDS
  7410.  
  7411.    num     WB      {0Fh}                       ; Store 0Fh
  7412.    array   WB      (40 / SIZEOF WB) DUP ({2})  ; Allocates and
  7413.                                                ;  initializes 10 unions
  7414.  
  7415.  (This figure may be found in the printed book.)
  7416.  
  7417.  In MASM 6.0, control structures (such as IF, macros, and directives) are
  7418.  also allowed within structure and union declarations.
  7419.  
  7420.  
  7421.  Arrays as Field Initializers
  7422.  
  7423.  Default initializers for string or array fields set the size for the field.
  7424.  
  7425.  
  7426.  The length of the array that can override the contents of a field in a
  7427.  variable definition is fixed by the size of the initializer. The override
  7428.  cannot contain more elements than the default. Specifying fewer override
  7429.  array elements changes the first n values of the default where n is the
  7430.  number of values in the override. The rest of the array elements take their
  7431.  default values from the initializer.
  7432.  
  7433.  
  7434.  Strings as Field Initializers
  7435.  
  7436.  If the override is shorter, the assembler pads the override with spaces to
  7437.  equal the length of the initializer. If the initializer is a string and the
  7438.  override value is not a string, the override value must be enclosed in angle
  7439.  brackets or curly braces.
  7440.  
  7441.  A string may be used to override any member of type BYTE (or SBYTE). The
  7442.  string does not need to be enclosed in angle brackets or curly braces unless
  7443.  mixed with other override methods.
  7444.  
  7445.  The string fields for structure variables are the length defined by the type
  7446.  declaration.
  7447.  
  7448.  If a structure has an initialized string field or an array of bytes, any new
  7449.  string assigned to a variable of the field that is smaller than the default
  7450.  is padded with spaces. The assembler adds four spaces at the end of  'Bolts'
  7451.   in the variables of type  ITEMS  above. The  Iname  field in the  ITEMS
  7452.  structure cannot contain a field initializer longer than  'Item Name'.
  7453.  
  7454.  
  7455.  Structures as Field Initializers
  7456.  
  7457.  Initializers for structure variables must be enclosed in curly braces or
  7458.  angle brackets, but you can specify overrides with fewer elements than the
  7459.  defaults.
  7460.  
  7461.  This example illustrates the use of default values with structures as field
  7462.  initializers:
  7463.  
  7464.    DISKDRIVES      STRUCT
  7465.      a1            BYTE ?
  7466.      b1            BYTE ?
  7467.      c1            BYTE ?
  7468.    DISKDRIVES      ENDS
  7469.  
  7470.    INFO            STRUCT
  7471.      buffer        BYTE    100 DUP (?)
  7472.      crlf          BYTE    13, 10
  7473.      query         BYTE    'Filename: ' ; String <= can override
  7474.      endmark       BYTE    36
  7475.      drives        DISKDRIVES <0, 1, 1>
  7476.    INFO            ENDS
  7477.  
  7478.    info1   INFO    { , , 'Dir' }
  7479.  
  7480.    ; Illegal since name in query field is too long
  7481.    ; and a string cannot initialize a field defined with DUP:
  7482.    ; info2  INFO    {"TESTFILE", , "DirectoryName",}
  7483.  
  7484.    lotsof  INFO    { , , 'file1', , {0,0,0} },
  7485.                    { , , 'file2', , {0,0,1} },
  7486.                    { , , 'file3', , {0,0,2} }
  7487.  
  7488.  The diagram below shows how the assembler stores  info1.
  7489.  
  7490.  (This figure may be found in the printed book.)
  7491.  
  7492.  The initialization for  drives  gives default values for all three fields of
  7493.  the structure. The fields left blank in  info1  use the default values for
  7494.  those fields. The  info2  declaration is illegal since  "DirectoryName"  is
  7495.  longer than the initial string for that field, and the  "TESTFILE"  string
  7496.  cannot initialize a field defined with DUP.
  7497.  
  7498.  
  7499.  Arrays of Structures and Unions
  7500.  
  7501.  You can define an array of structures using the DUP operator (see Section
  7502.  5.1.1, "Declaring and Referencing Arrays") or by creating a list of
  7503.  structures. For example, you can define an array of structure variables like
  7504.  this:
  7505.  
  7506.    Item7   ITEMS    30 DUP ({,,{10}})
  7507.  
  7508.  The  Item7  array defined here has 30 elements of type  ITEMS, with the
  7509.  third field of each element (the union) initialized to  10.
  7510.  
  7511.  You can also list array elements as shown in this example:
  7512.  
  7513.    Item8   ITEMS    {'Bolts', 126, 10},
  7514.                     {'Pliers',139, 10},
  7515.                     {'Saws',  414, 10}
  7516.  
  7517.  
  7518.  Structure Redefinition
  7519.  
  7520.  The assembler generates an error for a structure redefinition unless all of
  7521.  the following are the same:
  7522.  
  7523.  
  7524.    ■   Field names
  7525.  
  7526.    ■   Offsets of named fields
  7527.  
  7528.    ■   Initialization lists
  7529.  
  7530.    ■   Field alignment value
  7531.  
  7532.  
  7533.  Additionally, all fields must be present and at the same offset.
  7534.  
  7535.  
  7536.  LENGTHOF, SIZEOF, and TYPE for Structures
  7537.  
  7538.  The size of a structure determined by SIZEOF is the offset of the last
  7539.  field, plus the size of the last field, plus any padding required for proper
  7540.  alignment (see Section 5.2.1 for information about alignment). This example,
  7541.  using the data declarations above, shows how to use the LENGTHOF, SIZEOF,
  7542.  and TYPE operators with structures:
  7543.  
  7544.    INFO            STRUCT
  7545.      buffer        BYTE    100 DUP (?)
  7546.      crlf          BYTE    13, 10
  7547.      query         BYTE    'Filename: '
  7548.      endmark       BYTE    36
  7549.      drives        DISKDRIVES <0, 1, 1>
  7550.    INFO            ENDS
  7551.  
  7552.    info1   INFO    { , , 'Dir' }
  7553.    lotsof  INFO    { , , 'file1', , {0,0,0} },
  7554.                    { , , 'file2', , {0,0,1} },
  7555.                    { , , 'file3', , {0,0,2} }
  7556.  
  7557.    sinfo1  EQU     SIZEOF    info1  ; 116 = number of bytes in
  7558.  
  7559.                                     ;  initializers
  7560.    linfo1  EQU     LENGTHOF  info1  ; 1 = number of items
  7561.    tinfo1  EQU     TYPE      info1  ; 116 = same as size
  7562.  
  7563.    slotsof EQU     SIZEOF    lotsof ; 116 * 3 = number of bytes in
  7564.                                     ;  initializers
  7565.    llotsof EQU     LENGTHOF  lotsof ; 3 = number of items
  7566.    tlotsof EQU     TYPE      lotsof ; 116 = same as size for structure
  7567.  
  7568.                                     ;  of type INFO
  7569.  
  7570.  
  7571.  LENGTHOF, SIZEOF, and TYPE for Unions
  7572.  
  7573.  The size of a union determined by SIZEOF is the size of the longest field
  7574.  plus any padding required. The length of a union variable determined by
  7575.  LENGTHOF equals the number of initializers defined inside angle brackets or
  7576.  curly braces. TYPE returns a value indicating the type of the longest field.
  7577.  
  7578.  
  7579.    DWB     UNION
  7580.      d     DWORD   ?
  7581.      w     WORD    ?
  7582.      b     BYTE    ?
  7583.    DWB     ENDS
  7584.  
  7585.    num     DWB     {0FFFFh}
  7586.    array   DWB     (100 / SIZEOF DWB) DUP ({0})
  7587.  
  7588.    snum    EQU     SIZEOF   num      ; = 4
  7589.    lnum    EQU     LENGTHOF num      ; = 1
  7590.    tnum    EQU     TYPE     num      ; = 4
  7591.    sarray  EQU     SIZEOF   array    ; = 100 (4*25)
  7592.    larray  EQU     LENGTHOF array    ; = 25
  7593.    tarray  EQU     TYPE     array    ; = 4
  7594.  
  7595.  
  7596.  5.2.3  Referencing Structures, Unions, and Fields
  7597.  
  7598.  Like other variables, structure variables can be accessed by name. You can
  7599.  access fields within structure variables with this syntax:
  7600.  
  7601.    variable.field
  7602.  
  7603.  In MASM 6.0, references to fields must always be fully qualified, with both
  7604.  the structure or union name and the dot operator preceding the field name.
  7605.  Also, in MASM 6.0, the dot operator can be used only with structure fields,
  7606.  not as an alternative to the plus operator; nor can the plus operator be
  7607.  used as an alternative to the dot operator.
  7608.  
  7609.  This example shows several ways to reference the fields of a structure
  7610.  called  date.
  7611.  
  7612.    DATE    STRUCT                            ; Defines structure
  7613.    type
  7614.      month BYTE    ?
  7615.      day   BYTE    ?
  7616.      year  WORD    ?
  7617.    DATE    ENDS
  7618.  
  7619.    yesterday       DATE    {9, 30, 1987}     ; Declare structure
  7620.                                              ;  variable
  7621.            .
  7622.            .
  7623.            .
  7624.            mov     al, yesterday.day         ; Use structure variables
  7625.            mov     bx, OFFSET yesterday      ; Load structure address
  7626.            mov     al, (DATE PTR [bx]).month ; Use as indirect operand
  7627.            mov     al, [bx].date.month       ; This is necessary if
  7628.                                              ;  month were already a
  7629.  
  7630.                                              ;  field in a different
  7631.                                              ;  structure
  7632.  
  7633.  Under OPTION M510 or OPTION OLDSTRUCTS, unique structure names do not need
  7634.  to be qualified. See Section 1.3.2 for information on the OPTION directive.
  7635.  
  7636.  
  7637.  If the NONUNIQUE keyword appears in a structure definition, all fields of
  7638.  the structure must be fully qualified when referenced, even if the OPTION
  7639.  OLDSTRUCTS directive appears in the code. Also, in MASM 6.0, all references
  7640.  to a field must be qualified.
  7641.  
  7642.  Even if the initialized union is the size of a WORD or DWORD, members of
  7643.  structures or unions are accessible only through the field's names.
  7644.  
  7645.  In the following example, the two MOV statements show how you can access the
  7646.  elements of an array of structures.
  7647.  
  7648.    WB      UNION
  7649.      w     WORD    ?
  7650.      b     BYTE    ?
  7651.    WB      ENDS
  7652.  
  7653.    array   WB      (100 / SIZEOF WB) DUP ({0})
  7654.  
  7655.            mov     array[12].w, 40
  7656.            mov     array[32].b,  2
  7657.  
  7658.  (This figure may be found in the printed book.)
  7659.  
  7660.  The  WB  union cannot be used directly as a WORD variable. However, you can
  7661.  define a union containing both the structure and a WORD variable and access
  7662.  either field. (The next section discusses nested structures and unions.)
  7663.  
  7664.  You can use unions to access the same data in more than one form. For
  7665.  example, one application of structures and unions is to simplify the task of
  7666.  reinitializing a far pointer. If you have a far pointer declared as
  7667.  
  7668.    FPWORD  TYPEDEF FAR PTR WORD
  7669.  
  7670.            .DATA
  7671.    BoxB    FPWORD ?
  7672.    BoxA    FPWORD ?
  7673.    BoxB2   uptr   < >
  7674.  
  7675.  you must follow these steps to point  BoxB  to  BoxA:
  7676.  
  7677.    mov     bx,  OFFSET BoxA
  7678.            mov     WORD PTR BoxB[2], ds
  7679.            mov     WORD PTR BoxB, bx
  7680.  
  7681.  When you do this, you must remember whether the segment or the offset is
  7682.  stored first. However, if your program contains this union:
  7683.  
  7684.    uptr      UNION
  7685.      dwptr   FPWORD   0
  7686.      STRUCT
  7687.        offs  WORD     0
  7688.        segm  WORD     0
  7689.      ENDS
  7690.    uptr      ENDS
  7691.  
  7692.  you can initialize a far pointer with these steps:
  7693.  
  7694.    mov     BoxB2.segm, ds
  7695.            mov     BoxB2.offs, bx
  7696.            lds     si, BoxB2.dwptr
  7697.  
  7698.  This code moves the segment and the offset into the pointer and then moves
  7699.  the pointer into a register with the other field of the union. Although this
  7700.  technique does not reduce the code size, it avoids confusion about the order
  7701.  for loading the segment and offset.
  7702.  
  7703.  
  7704.  5.2.4  Nested Structures and Unions
  7705.  
  7706.  Structures and unions in MASM 6.0 can be nested in several ways. This
  7707.  section explains how to refer to the fields in a nested structure or union.
  7708.  The example below illustrates the four techniques for nesting and how to
  7709.  reference the fields. Note the syntax for nested structures. The discussion
  7710.  of these techniques follows the example.
  7711.  
  7712.    ITEMS           STRUCT
  7713.      Inum          WORD    ?
  7714.      Iname         BYTE    'Item Name'
  7715.    ITEMS           ENDS
  7716.  
  7717.    INVENTORY       STRUCT
  7718.      UpDate        WORD    ?
  7719.      oldItem       ITEMS   { \
  7720.                            ?,
  7721.                            'AF8' \       ; Named variable of
  7722.                            }             ;  existing structure
  7723.                    ITEMS   { ?, '94C' }  ; Unnamed variable of
  7724.                                          ;  existing type
  7725.      STRUCT ups                          ; Named nested structure
  7726.        source      WORD    ?
  7727.        shipmode    BYTE    ?
  7728.      ENDS
  7729.      STRUCT                              ; Unnamed nested structure
  7730.        f1          WORD    ?
  7731.        f2          WORD    ?
  7732.      ENDS
  7733.    INVENTORY       ENDS
  7734.  
  7735.            .DATA
  7736.  
  7737.    yearly  INVENTORY       { }
  7738.  
  7739.    ; Referencing each type of data in the yearly structure:
  7740.  
  7741.            mov     ax, yearly.oldItem.Inum
  7742.            mov     yearly.ups.shipmode, 'A'
  7743.            mov     yearly.Inum, 'C'
  7744.            mov     ax, yearly.f1
  7745.  
  7746.  To nest structures and unions, you can use any of these techniques:
  7747.  
  7748.  
  7749.    ■   The field of a structure or union can be a named variable of an
  7750.        existing structure or union type, as in the  oldItem  field. The field
  7751.        names in  oldItem  are not unique, so the full field names must be
  7752.        used when referencing those fields in the statement
  7753.  
  7754.        mov     ax, yearly.oldItem.Inum
  7755.  
  7756.  
  7757.    ■   To declare a named structure or union inside another structure or
  7758.        union, give the STRUCT or UNION keyword first and then define a label
  7759.        for it. Fields of the nested structure or union must always be
  7760.        qualified, as shown in this example:
  7761.  
  7762.        mov     yearly.ups.shipmode, 'A'
  7763.  
  7764.  
  7765.    ■   As shown in the  Items  field of  Inventory, you can also use unnamed
  7766.        variables of existing structures or unions inside another structure or
  7767.        union. In this case you can reference its fields directly, as shown in
  7768.        this example:
  7769.  
  7770.        mov     yearly.Inum, 'C'
  7771.                       mov     ax, yearly.f1
  7772.  
  7773.  
  7774.  
  7775.  Offsets of nested structures are relative to the nested structure, not the
  7776.  root structure. In the example above, the offset of  yearly.ups.shipmode  is
  7777.   (current address of yearly) + 8 + 2. It is relative to the  ups  structure,
  7778.  not the  yearly  structure.
  7779.  
  7780.  
  7781.  5.3  Records
  7782.  
  7783.  Records are similar to structures, except that fields in records are bit
  7784.  strings. Each bit field in a record variable can be used separately in
  7785.  constant operands or expressions. The processor cannot access bits
  7786.  individually at run time, but it can access bit fields with instructions
  7787.  that manipulate bits.
  7788.  
  7789.  Record fields are bits, not bytes or words.
  7790.  
  7791.  Records are bytes, words, or doublewords in which the individual bits or
  7792.  groups of bits are considered fields. In general, the three steps for using
  7793.  record variables are the same as those for other complex data types:
  7794.  
  7795.  
  7796.    1.  Declare a record type.
  7797.  
  7798.    2.  Define one or more variables having the record type.
  7799.  
  7800.    3.  Reference record variables using shifts and masks.
  7801.  
  7802.  
  7803.  Once defined, the record variable can be used as an operand in assembler
  7804.  statements.
  7805.  
  7806.  This section explains the record declaration syntax and the use of the MASK
  7807.  and WIDTH operators. It also shows a few applications of record variables
  7808.  and constants.
  7809.  
  7810.  
  7811.  5.3.1  Declaring Record Types
  7812.  
  7813.  A record type creates a template for data with the sizes and, optionally,
  7814.  the initial values for bit fields in the record, but it does not allocate
  7815.  memory space for the record.
  7816.  
  7817.  The RECORD directive declares a record type for an 8-bit, 16-bit, or 32-bit
  7818.  record that contains one or more bit fields. The maximum size is based on
  7819.  the expression word size. See OPTION EXPR16 and OPTION EXPR32 in Section
  7820.  1.3.2. The syntax is
  7821.  
  7822.    recordname RECORD field [[,field]]...
  7823.  
  7824.  The field declares the name, width, and initial value for the field. The
  7825.  syntax for each field is:
  7826.  
  7827.    fieldname:width[[=expression]]
  7828.  
  7829.  Global labels, macro names, and record field names must all be unique, but
  7830.  record field names can have the same names as structure field names or
  7831.  global labels. Width is the number of bits in the field, and expression is a
  7832.  constant giving the initial (or default) value for the field. Record
  7833.  definitions can span more than one line if the continued lines end with
  7834.  commas.
  7835.  
  7836.  If expression is given, it declares the initial value for the field. The
  7837.  assembler generates an error message if an initial value is too large for
  7838.  the width of its field.
  7839.  
  7840.  The assembler shifts bits in a record to the right if all bits are not used.
  7841.  
  7842.  
  7843.  The first field in the declaration always goes into the most significant
  7844.  bits of the record. Subsequent fields are placed to the right in the
  7845.  succeeding bits. If the fields do not total exactly 8, 16, or 32 bits as
  7846.  appropriate, the entire record is shifted right, so the last bit of the last
  7847.  field is the lowest bit of the record. Unused bits in the high end of the
  7848.  record are initialized to 0.
  7849.  
  7850.  The following example creates a byte record type  color  having four fields:
  7851.   blink,  back,  intense, and  fore. The contents of the record type are
  7852.  shown after the example. Since no initial values are given, all bits are set
  7853.  to 0. Note that this is only a template maintained by the assembler. No data
  7854.  is created.
  7855.  
  7856.    COLOR   RECORD  blink:1, back:3, intense:1, fore:3
  7857.  
  7858.  (This figure may be found in the printed book.)
  7859.  
  7860.  The next example creates a record type  cw  having six fields. Each record
  7861.  declared with this type occupies 16 bits of memory. Initial (default) values
  7862.  are given for each field. They can be used when data is declared for the
  7863.  record. The bit diagram after the example shows the contents of the record
  7864.  type.
  7865.  
  7866.    CW      RECORD  r1:3=0, ic:1=0, rc:2=0, pc:2=3, r2:2=1, masks:6=63
  7867.  
  7868.  (This figure may be found in the printed book.)
  7869.  
  7870.  
  7871.  5.3.2  Defining Record Variables
  7872.  
  7873.  Once you have declared a record type, you can define record variables of
  7874.  that type. For each variable, memory is allocated to the object file in the
  7875.  format declared by the type. The syntax is
  7876.  
  7877.    [[name]] recordname <[[initializer
  7878.    [[,initializer]]...]] > <$IAngle
  7879.    brackets (<< \ra);records>
  7880.  
  7881.    [[name]] recordname {
  7882.    [[initializer [[,initializer]]...]]
  7883.    }
  7884.  
  7885.    [[name]] recordname constant
  7886.     DUP ( [[initializer [[,initializer]]...]]
  7887.    )
  7888.  
  7889.  The recordname is the name of a record type that was previously declared by
  7890.  using the RECORD directive.
  7891.  
  7892.  A fieldlist for each field in the record can be a list of integers,
  7893.  character constants, or expressions that correspond to a value compatible
  7894.  with the size of the field. Curly braces or angle brackets are required even
  7895.  if no initial value is given.
  7896.  
  7897.  If you use the DUP operator (see Section 5.1.1, "Declaring and Referencing
  7898.  Arrays") to initialize multiple record variables, only the angle brackets
  7899.  and initial values, if given, need to be enclosed in parentheses. For
  7900.  example, you can define an array of record variables with
  7901.  
  7902.    xmas    COLOR   50 DUP ( <1, 2, 0, 4> )
  7903.  
  7904.  You do not have to initialize all fields in a record. If an initial value is
  7905.  blank, the assembler automatically stores the default initial value of the
  7906.  field. If there is no default value, the assembler clears each bit in the
  7907.  field.
  7908.  
  7909.  The definition in the example below creates a variable named  warning  whose
  7910.  type is given by the record type  color. The initial values of the fields in
  7911.  the
  7912.  
  7913.  variable are set to the values given in the record definition. The initial
  7914.  values override any default record values, had any been given in the
  7915.  declaration.
  7916.  
  7917.    COLOR   RECORD  blink:1,back:3,intense:1,fore:3 ; Record
  7918.                                                    ;  declaration
  7919.    warning COLOR   <1, 0, 1, 4>                    ; Record
  7920.                                                    ;  definition
  7921.  
  7922.  (This figure may be found in the printed book.)
  7923.  
  7924.  
  7925.  LENGTHOF, SIZEOF, and TYPE with Records
  7926.  
  7927.  The SIZEOF and TYPE operators applied to a record name return the number of
  7928.  bytes used by the record. SIZEOF for a record variable returns the number of
  7929.  bytes used by the variable. You cannot use LENGTHOF with record types, but
  7930.  you can with the variables of that type. LENGTHOF returns the number of
  7931.  items in an initializer. The record can be used as an operand. The value of
  7932.  the operand is a bit mask of the defined record. This example illustrates
  7933.  these points.
  7934.  
  7935.    ; Record definition
  7936.    ; 9 bits stored in 2 bytes
  7937.    RGBCOLOR        RECORD  red:3,  green:3,  blue:3
  7938.  
  7939.            mov     ax, RGBCOLOR          ; Equivalent to "mov ax,
  7940.                                          ;  01FFh"
  7941.    ;       mov     ax, LENGTHOF RGBCOLOR ; Illegal since LENGTHOF can
  7942.                                          ;  apply only to data label
  7943.            mov     ax, SIZEOF   RGBCOLOR ; Equivalent to "mov ax, 2"
  7944.  
  7945.            mov     ax, TYPE     RGBCOLOR ; Equivalent to "mov ax, 2"
  7946.  
  7947.  
  7948.    ; Record instance
  7949.    ; 8 bits stored in 1 byte
  7950.    RGBCOLOR2       RECORD red:3, green:3, blue:2
  7951.    rgb             RGBCOLOR2 <1, 1, 1>     ; Initialize to 025h
  7952.  
  7953.            mov     ax, RGBCOLOR2           ; Equivalent to "mov ax,
  7954.                                            ;  00FFhh"
  7955.            mov     ax, LENGTHOF rgb        ; Equivalent to "mov ax,
  7956.    1"
  7957.            mov     ax, SIZEOF   rgb        ; Equivalent to "mov ax,
  7958.    1"
  7959.            mov     ax, TYPE     rgb        ; Equivalent to "mov ax,
  7960.    1"
  7961.  
  7962.  
  7963.  5.3.3  Record Operators
  7964.  
  7965.  The WIDTH operator (which is used only with records) returns the width in
  7966.  bits of a record or record field. The MASK operator returns a bit mask for
  7967.  the bit positions occupied by the given record field. A bit in the mask
  7968.  contains a 1 if that bit corresponds to a bit field. The example below shows
  7969.  how to use MASK and WIDTH.
  7970.  
  7971.    .DATA
  7972.    COLOR           RECORD  blink:1, back:3, intense:1, fore:3
  7973.    message         COLOR   <1, 5, 1, 1>
  7974.    wblink  EQU     WIDTH blink         ; "wblink"     = 1
  7975.    wback   EQU     WIDTH back          ; "wback"      = 3
  7976.    wintense EQU    WIDTH intense       ; "wintense"   = 1
  7977.    wfore   EQU     WIDTH fore          ; "wfore"      = 3
  7978.    wcolor  EQU     WIDTH color         ; "wcolor"     = 8
  7979.            .CODE
  7980.            .
  7981.            .
  7982.            .
  7983.            mov     ah, message         ; Load initial   0101 1001
  7984.            and     ah, NOT MASK back   ; Turn off   AND 1000 1111
  7985.                                        ; "back"         ---------
  7986.                                        ;                0000 1001
  7987.            or      ah, MASK blink      ; Turn on     OR 1000 0000
  7988.                                        ; "blink"        ---------
  7989.                                        ;                1000 1001
  7990.            xor     ah, MASK intense    ; Toggle     XOR 0000 1000
  7991.                                        ; "intense"      ---------
  7992.                                        ;                1000 0001
  7993.            .
  7994.            IF      (WIDTH color) GE 8  ; If color is 16 bit, load
  7995.            mov     ax, message         ;  into 16-bit register
  7996.            ELSE                        ; else
  7997.            mov     al, message         ;  load into low 8-bit register
  7998.            xor     ah, ah              ;  and clear high 8-bits
  7999.            ENDIF
  8000.  
  8001.  This example illustrates several ways in which record fields can be used as
  8002.  operands and in expressions.
  8003.  
  8004.    ; Rotate "back" of "cursor" without changing other
  8005.    values
  8006.  
  8007.                mov     al, cursor       ; Load value from memory
  8008.                mov     ah, al           ; Save a copy for work      1101
  8009.    1001=ah/al
  8010.                and     al, NOT MASK back; Mask out old bits     AND
  8011.    1000 1111=mask
  8012.                                         ;  to save old cursor       ---------
  8013.                                         ;                           1000
  8014.    1001=al
  8015.                mov     cl, back         ; Load bit position
  8016.                shr     ah, cl           ; Shift to right            0000
  8017.    1101=ah
  8018.                inc     ah               ; Increment                 0000
  8019.    1110=ah
  8020.  
  8021.                shl     ah, cl           ; Shift left again          1110
  8022.    0000=ah
  8023.                and     ah, MASK back    ; Mask off extra bits   AND
  8024.    0111 0000=mask
  8025.                                         ;  to get new cursor        ---------
  8026.                                         ;                           0110
  8027.    0000 ah
  8028.                or      ah, al           ; Combine old and new    OR
  8029.    1000 1001 al
  8030.                                         ;                           ---------
  8031.                mov     cursor, ah       ; Write back to memory      1110
  8032.    1001 ah
  8033.  
  8034.  Record variables are often used with the logical operators to perform
  8035.  logical operations on the bit fields of the record, as in the previous
  8036.  example using the MASK operator.
  8037.  
  8038.  
  8039.  5.4  Related Topics in Online Help
  8040.  
  8041.  In addition to information on all the instructions and directives mentioned
  8042.  in this chapter, information on the following topics can be found in online
  8043.  help, starting at the "MASM 6.0 Contents" screen:
  8044.  
  8045.  Topic                             Access
  8046.  ────────────────────────────────────────────────────────────────────────────
  8047.  INS, OUTS                         Choose "Processor Instructions" and then
  8048.                                    "System and I/O Access"
  8049.  
  8050.  LABEL                             Choose "Directives" and then "Code
  8051.                                    Labels"
  8052.  
  8053.  RECORD, UNION, STRUCT, MASK, ORG   Choose "Directives" and then choose
  8054.  , WIDTH, and ALIGN                "Complex Data Types"
  8055.  
  8056.  SHRD, SHLD, BSF, and BSR          From "Processor Instructions," choose
  8057.                                    "Logical and Shifts"
  8058.  
  8059.  BOUND                             From "Processor Instructions," choose
  8060.                                    "Data
  8061.                                    Transfer"
  8062.  
  8063.  
  8064.  
  8065.  
  8066.  
  8067.  
  8068.  
  8069.  
  8070.  Chapter 6  Using Floating-Point and Binary Coded Decimal Numbers
  8071.  ────────────────────────────────────────────────────────────────────────────
  8072.  
  8073.  MASM requires different techniques for handling floating-point (real)
  8074.  numbers and binary coded decimal (BCD) numbers than for handling integers.
  8075.  You have two choices for working with real numbers─a math coprocessor or
  8076.  emulation routines.
  8077.  
  8078.  Math coprocessors─the 8087, 80287, and 80387 chips─work with the main
  8079.  processor to handle real-number calculations. The 80486 processor performs
  8080.  floating-point operations directly. All information in this chapter
  8081.  pertaining to the 80387 coprocessor applies to the 80486 processor as well.
  8082.  
  8083.  
  8084.  This chapter begins with a summary of the directives and formats of
  8085.  floating-point data; you need to use these to allocate memory storage and
  8086.  initialize variables before you can work with floating-point numbers.
  8087.  
  8088.  The chapter then explains how to use a math coprocessor for floating-point
  8089.  operations. It covers these areas:
  8090.  
  8091.  
  8092.    ■   The architecture of the registers
  8093.  
  8094.    ■   The operands for the coprocessor instruction formats
  8095.  
  8096.    ■   The coordination of coprocessor and main processor memory access
  8097.  
  8098.    ■   The basic groups of coprocessor instructions─for loading and storing
  8099.        data, doing arithmetic calculations, and controlling program flow
  8100.  
  8101.  
  8102.  The next main section describes emulation libraries. With the emulation
  8103.  routines provided with all Microsoft high-level languages, you can use
  8104.  coprocessor instructions as though your computer had a math coprocessor.
  8105.  However, some coprocessor instructions are not handled by emulation, as this
  8106.  section explains.
  8107.  
  8108.  Finally, because math coprocessor and emulation routines can also operate on
  8109.  BCD numbers, this chapter discusses the instruction set for these numbers.
  8110.  
  8111.  
  8112.  6.1  Using Floating-Point Numbers
  8113.  
  8114.  Before using floating-point data in your program, you need to allocate the
  8115.  memory storage for the data. You can then initialize variables either as
  8116.  real numbers in decimal form or as encoded hexadecimals. The assembler
  8117.  stores allocated data in 10-byte IEEE format. This section looks at
  8118.  floating-point declarations and floating-point data formats.
  8119.  
  8120.  
  8121.  6.1.1  Declaring Floating-Point Variables and Constants
  8122.  
  8123.  You can allocate real constants using the REAL4, REAL8, and REAL10
  8124.  directives. The list below shows the size of the floating-point number each
  8125.  of these directives allocates.
  8126.  
  8127.  Directive       Size
  8128.  ────────────────────────────────────────────────────────────────────────────
  8129.  REAL4           Short (32-bit) real numbers
  8130.  REAL8           Long (64-bit) real numbers
  8131.  REAL10          10-byte (80-bit) real numbers and BCD numbers
  8132.  
  8133.  The possible ranges for floating-point variables are given in Table 6.1.
  8134.  
  8135.  Table   6.1 Ranges of Floating-Point Variables
  8136.  
  8137.                       Significant
  8138.  Data Type     Bits   Digits             Approximate Range
  8139.  ────────────────────────────────────────────────────────────────────────────
  8140.  Short real    32     6-7                ±1.18 x 10-38 to ±3.40 x 10(38)
  8141.  
  8142.  Long real     64     15-16              ±2.23 x 10-308 to ±1.79 x 10(308)
  8143.  
  8144.  10-byte real  80     19                 ±3.37 x 10-4932 to ±1.18 x 10
  8145.                                          (4932)
  8146.  
  8147.  ────────────────────────────────────────────────────────────────────────────
  8148.  
  8149.  
  8150.  With previous versions of MASM, the DD, DQ, and DT directives could be used
  8151.  to allocate real constants. These directives are still supported by MASM
  8152.  6.0, but this means that the variables are integers rather than
  8153.  floating-point values. Although this makes no difference in the assembly
  8154.  code, CodeView displays the values incorrectly.
  8155.  
  8156.  There are two forms for specifying floatingpoint numbers.
  8157.  
  8158.  You can specify floating-point constants either as decimal constants or as
  8159.  encoded hexadecimal constants. You can express decimal real-number constants
  8160.  in the form
  8161.  
  8162.    [[+ | -]] integer.[[fraction]][[E]][[[[+
  8163.    | -]]exponent]]
  8164.  
  8165.  For example, the numbers  2.523E1  and  -3.6E-2  are written in the correct
  8166.  decimal format. These numbers can be used as initializers for real-number
  8167.  variables.
  8168.  
  8169.  Digits of real numbers are always evaluated as base 10. During assembly, the
  8170.  assembler converts real-number constants given in decimal format to a binary
  8171.  format. The sign, exponent, and mantissa of the real number are encoded as
  8172.  bit fields within the number.
  8173.  
  8174.  You can also specify the encoded format directly with hexadecimal digits
  8175.  (0-9 plus A-F). The number must begin with a decimal digit (0-9) and a
  8176.  leading zero if necessary, and end with the real-number designator (R). It
  8177.  cannot be signed.
  8178.  
  8179.  For example, the hexadecimal number  3F800000r  can be used as an
  8180.  initializer for a doubleword-sized variable.
  8181.  
  8182.  The maximum range of exponent values and the number of digits required in
  8183.  the hexadecimal number depend on the directive. The number of digits for
  8184.  encoded numbers used with REAL4, REAL8, and REAL10 must be 8, 16, and 20
  8185.  digits, respectively. If the number has a leading zero, the number must be
  8186.  9, 17, or 21 digits.
  8187.  
  8188.  Examples of decimal constant and hexadecimal specifications are shown here:
  8189.  
  8190.  
  8191.    ; Real numbers
  8192.    short   REAL4    25.23              ; IEEE format
  8193.    double  REAL8    2.523E1            ; IEEE format
  8194.    tenbyte REAL10   2523.0E-2          ; 10-byte real format
  8195.  
  8196.    ; Encoded as hexadecimals
  8197.    ieeeshort       REAL4    3F800000r             ; 1.0 as IEEE short
  8198.    ieeedouble      REAL8    3FF0000000000000r     ; 1.0 as IEEE long
  8199.    temporary       REAL10   3FFF8000000000000000r ; 1.0 as 10-byte
  8200.                                                   ;  real
  8201.  
  8202.  Section 6.1.2, "Storing Numbers in Floating-Point Format," explains the IEEE
  8203.  formats--the way the assembler actually stores the data.
  8204.  
  8205.  Pascal or C programmers may prefer to create language-specific TYPEDEF
  8206.  declarations, as illustrated in this example:
  8207.  
  8208.    ; C-language specific
  8209.    float           TYPEDEF REAL4
  8210.    double          TYPEDEF REAL8
  8211.    long_double     TYPEDEF REAL10
  8212.    ; Pascal-language specific
  8213.    SINGLE          TYPEDEF REAL4
  8214.    DOUBLE          TYPEDEF REAL8
  8215.    EXTENDED        TYPEDEF REAL10
  8216.  
  8217.  For applications of TYPEDEF other than aliasing, see Section 3.3.1,
  8218.  "Defining Pointer Types with TYPEDEF."
  8219.  
  8220.  
  8221.  6.1.2  Storing Numbers in Floating-Point Format
  8222.  
  8223.  The assembler stores real numbers in the IEEE format.
  8224.  
  8225.  The assembler stores the floating-point variables in the IEEE format. MASM
  8226.  6.0 does not support .MSFLOAT and Microsoft binary format, which are
  8227.  available in previous versions.
  8228.  
  8229.  Figure 6.1 illustrates the IEEE format for encoding short (four-byte), long
  8230.  (eight-byte), and 10-byte real numbers. Although this figure places the
  8231.  most-significant bit first for illustration, low bytes actually appear first
  8232.  in memory.
  8233.  
  8234.  (This figure may be found in the printed book.)
  8235.  
  8236.  This is how the parts of a real number are stored in the IEEE format:
  8237.  
  8238.  
  8239.    1.  Sign bit (0 for positive or 1 for negative) in the upper bit of the
  8240.        first byte.
  8241.  
  8242.    2.  Exponent in the next bits in sequence (8 bits for a short real number,
  8243.        11 bits for a long real number, and 15 bits for a 10-byte real
  8244.        number).
  8245.  
  8246.    3.  Mantissa in the remaining bits. The first bit is always assumed to be
  8247.        1. The length is 23 bits for short real numbers, 52 bits for long real
  8248.        numbers, and 63 bits for 10-byte reals.
  8249.  
  8250.  
  8251.  The exponent field represents a multiplier 2n. To accommodate negative
  8252.  exponents (such as 2-6), the value in the exponent field is biased; that is,
  8253.  the actual exponent is determined by subtracting the appropriate bias value
  8254.  from the value in the exponent field. For example, the bias for short reals
  8255.  is 127. If the value in the exponent field is 130, the exponent represents a
  8256.  value of 2130-127, or 23. The bias for long reals is 1,023. The bias for
  8257.  10-byte reals is 16,383.
  8258.  
  8259.  Notice that the 10-byte real format stores the integer part of the mantissa.
  8260.  This differs from the 4-byte and 8-byte formats, in which the integer part
  8261.  is implicit.
  8262.  
  8263.  Once you have declared floating-point data for your program, you can use
  8264.  coprocessor or emulator instructions to access the data. The next section
  8265.  focuses on the coprocessor architecture, instructions, and operands required
  8266.  for floating-point operations.
  8267.  
  8268.  
  8269.  6.2  Using a Math Coprocessor
  8270.  
  8271.  When used with real numbers, packed BCD numbers, or long integers,
  8272.  coprocessors (the 8087, 80287, 80387, and 80486) calculate many times faster
  8273.  than the 8086-based processors. The coprocessor handles data with its own
  8274.  registers. The organization of these registers reflects four possible
  8275.  formats for using operands (as explained in Section 6.2.2, "Instruction and
  8276.  Operand Formats").
  8277.  
  8278.  This section also describes how the coprocessor performs various tasks:
  8279.  transferring data to and from the coprocessor, coordinating processor and
  8280.  coprocessor operations, and controlling program flow.
  8281.  
  8282.  
  8283.  6.2.1  Coprocessor Architecture
  8284.  
  8285.  The coprocessor accesses memory as the CPU does, but it has its own data and
  8286.  control registers--eight data registers organized as a stack and seven
  8287.  control registers similar to the 8086 flag registers. The coprocessor's
  8288.  instruction set provides direct access to these registers.
  8289.  
  8290.  The eight coprocessor data registers form a stack.
  8291.  
  8292.  The eight 80-bit data registers of the 8087-based coprocessors are organized
  8293.  as a stack although they need not be used as a stack. As data items are
  8294.  pushed into the top register, previous data items move into higher-numbered
  8295.  registers, which are lower on the stack. Register 0 is the top of the stack;
  8296.  register 7 is the bottom. The syntax for specifying registers is shown
  8297.  below:
  8298.  
  8299.    ST «(number)»
  8300.  
  8301.  The number must be a digit between 0 and 7 or a constant expression that
  8302.  evaluates to a number from 0 to 7. ST is another way to refer to ST(0).
  8303.  
  8304.  All coprocessor data is stored in registers in the 10-byte real format. The
  8305.  registers and the register format are shown in Figure 6.2.
  8306.  
  8307.  (This figure may be found in the printed book.)
  8308.  
  8309.  Internally, all calculations are done on numbers of the same type. Since
  8310.  10-byte real numbers have the greatest precision, lower-precision numbers
  8311.  are guaranteed not to lose precision as a result of calculations. The
  8312.  instructions that transfer values between the main memory and the
  8313.  coprocessor automatically convert numbers to and from the 10-byte real
  8314.  format.
  8315.  
  8316.  
  8317.  6.2.2  Instruction and Operand Formats
  8318.  
  8319.  Because of the stack organization of registers, you can consider registers
  8320.  either as elements on a stack or as registers much like 8086-family
  8321.  registers. Table 6.2 lists the four main groups of coprocessor instructions
  8322.  and the general syntax for each. The names given to the instruction format
  8323.  reflect the way the instruction uses the coprocessor registers. The
  8324.  instruction operands are placed in the coprocessor data registers before the
  8325.  instruction executes.
  8326.  
  8327.  Table 6.2  Coprocessor Operand Formats
  8328.  
  8329.  Instruction                           Implied Operands
  8330.  Format             Syntax                               Example
  8331.  ────────────────────────────────────────────────────────────────────────────
  8332.  Classical stack    Faction            ST, ST(1)         fadd
  8333.  
  8334.  Memory             Faction memory     ST                fadd memloc
  8335.  
  8336.  Register           Faction  ST(num),  ─                 fadd st(5), st
  8337.                     ST                                   fadd st, st(3)
  8338.                     Faction  ST, ST(
  8339.                     num)
  8340.  
  8341.  Register pop       FactionP  ST(num    ─                 faddp st(4), st
  8342.                     ), ST
  8343.  
  8344.  ────────────────────────────────────────────────────────────────────────────
  8345.  
  8346.  
  8347.  All coprocessor instructions begin with F.
  8348.  
  8349.  You can easily recognize coprocessor instructions because, unlike all
  8350.  8086-family instruction mnemonics, they start with the letter F. Coprocessor
  8351.  instructions can never have immediate operands and, with the exception of
  8352.  the FSTSW instruction, they cannot have processor registers as operands.
  8353.  
  8354.  
  8355.  6.2.2.1  Classical-Stack Format
  8356.  
  8357.  Instructions in the classical-stack format treat the coprocessor registers
  8358.  like items on a stack─thus its name. Items are pushed onto or popped off the
  8359.  top elements of the stack. Since only the top item can be accessed on a
  8360.  traditional stack, there is no need to specify operands. The first (top)
  8361.  register (and the second if the instruction needs two operands) is always
  8362.  assumed.
  8363.  
  8364.  In coprocessor arithmetic operations, the top of the stack (ST) is the
  8365.  source operand and the second register [ST(1)] is the destination. The
  8366.  result of the operation goes into the destination operand, and the source is
  8367.  popped off the stack. The result is left at the top of the stack.
  8368.  
  8369.  Instructions that load constants are one example of instructions that
  8370.  require the classical-stack format. In this case, the constant created by
  8371.  the instruction is the implied source, and the top of the stack is the
  8372.  destination.
  8373.  
  8374.  This example illustrates the classical-stack format, and Figure 6.3 shows
  8375.  the status of the register stack after each instruction:
  8376.  
  8377.    fld1               ; Push 1 into first position
  8378.                fldpi              ; Push pi into first position
  8379.                fadd               ; Add pi and 1 and pop
  8380.  
  8381.  (This figure may be found in the printed book.)
  8382.  
  8383.  
  8384.  6.2.2.2  Memory Format
  8385.  
  8386.  Instructions using the memory format, such as data transfer instructions,
  8387.  also treat coprocessor registers like items on a stack. However, with this
  8388.  format, items are pushed from memory onto the top element of the stack or
  8389.  popped from the top element to memory. You must specify the memory operand.
  8390.  
  8391.  
  8392.  Some coprocessor instructions operate on integers or BCDs.
  8393.  
  8394.  Some instructions that use the memory format specify how a memory operand is
  8395.  to be interpreted─as an integer (I) or as a binary coded decimal (B). The
  8396.  letter I or B follows the initial F in the syntax. For example, FILD
  8397.  interprets its operand as an integer and FBLD interprets its operand as a
  8398.  BCD number. If the instruction name does not include a type letter, the
  8399.  instruction works on real numbers.
  8400.  
  8401.  You can also use memory operands in calculation instructions that operate on
  8402.  two values (see Section 6.2.4, "Using Coprocessor Instructions"). The memory
  8403.  operand is always the source. The stack top (ST) is always the implied
  8404.  destination. The result of the operation replaces the destination without
  8405.  changing its stack position, as shown in this example and Figure 6.4:
  8406.  
  8407.    .DATA
  8408.    m1       REAL4  1.0
  8409.    m2       REAL4  2.0
  8410.             .CODE
  8411.             .
  8412.             .
  8413.             .
  8414.             fld    m1      ; Push m1 into first position
  8415.             fld    m2      ; Push m2 into first position
  8416.             fadd   m1      ; Add m2 to first position
  8417.             fstp   m1      ; Pop first position into m1
  8418.             fst    m2      ; Copy first position to m2
  8419.  
  8420.  (This figure may be found in the printed book.)
  8421.  
  8422.  
  8423.  6.2.2.3  Register Format
  8424.  
  8425.  Instructions using the register format treat coprocessor registers as
  8426.  registers rather than as stack elements. Instructions that use this format
  8427.  require two register operands; one of them must be the stack top (ST).
  8428.  
  8429.  In the register format, specify all operands by name. The first operand is
  8430.  the destination; its value is replaced with the result of the operation. The
  8431.  second operand is the source; it is not affected by the operation. The stack
  8432.  position of the operands does not change.
  8433.  
  8434.  The only instructions using the register operand format are the FXCH
  8435.  instruction and the arithmetic instructions that do calculations on two
  8436.  values. With the FXCH instruction, the stack top is implied and need not be
  8437.  specified, as shown in this example and Figure 6.5:
  8438.  
  8439.    fadd    st(1), st   ; Add second position to first -
  8440.                                ;  result goes in second position
  8441.            fadd    st, st(2)   ; Add first position to third -
  8442.                                ;  result goes in first position
  8443.            fxch    st(1)       ; Exchange first and second positions
  8444.  
  8445.  (This figure may be found in the printed book.)
  8446.  
  8447.  
  8448.  6.2.2.4  Register-Pop Format
  8449.  
  8450.  The register-pop format treats coprocessor registers as a modified stack.
  8451.  The source register must always be the stack top. Specify the destination
  8452.  with the register's name.
  8453.  
  8454.  Instructions with this format place the result of the operation into the
  8455.  destination operand, and the stack top pops off the stack. The effect is
  8456.  that both values being operated on are lost and the result of the operation
  8457.  is saved in the specified destination register. The register-pop format is
  8458.  used only for instructions that do calculations on two values, as in this
  8459.  example and Figure 6.6:
  8460.  
  8461.    faddp   st(2), st ; Add first and third positions and
  8462.    pop -
  8463.                              ;  first position destroyed;
  8464.                              ;  third moves to second and holds result
  8465.  
  8466.  (This figure may be found in the printed book.)
  8467.  
  8468.  
  8469.  6.2.3  Coordinating Memory Access
  8470.  
  8471.  The math coprocessor works simultaneously with the main processor. However,
  8472.  since the coprocessor cannot handle device input or output, data originates
  8473.  in the main processor.
  8474.  
  8475.  The processor and coprocessor exchange data through memory.
  8476.  
  8477.  The main processor and the coprocessor have their own registers, which are
  8478.  completely separate and inaccessible to each other. They usually exchange
  8479.  data through memory, since memory is available to both.
  8480.  
  8481.  When using the coprocessor, follow these three steps:
  8482.  
  8483.  
  8484.    1.  Load data from memory to coprocessor registers.
  8485.  
  8486.    2.  Process the data.
  8487.  
  8488.    3.  Store the data from coprocessor registers back to memory.
  8489.  
  8490.  
  8491.  Step 2, processing the data, can occur while the main processor is handling
  8492.  other tasks. Steps 1 and 3 must be coordinated with the main processor so
  8493.  that the processor and coprocessor do not try to access the same memory at
  8494.  the same time; otherwise, problems of coordinating memory access can occur.
  8495.  Since the processor and coprocessor work independently, they may not finish
  8496.  working on memory in the order in which you give instructions. Two potential
  8497.  timing conflicts can occur; they are handled in different ways.
  8498.  
  8499.  One timing conflict results if a coprocessor instruction follows a processor
  8500.  instruction. The processor may have to wait until the coprocessor finishes
  8501.  if the next processor instruction requires the result of the coprocessor's
  8502.  calculation. You do not have to write your code to avoid this conflict,
  8503.  however. The assembler coordinates this timing automatically for the 8088
  8504.  and 8086 processors, and the processor coordinates it automatically on the
  8505.  80186-80486 processors. This is the first case shown in the example later in
  8506.  this section.
  8507.  
  8508.  Another conflict results if a processor instruction that accesses memory
  8509.  follows a coprocessor instruction that accesses the same memory. The
  8510.  processor can try to load a variable that is still being used by the
  8511.  coprocessor. You need careful synchronization to control the timing, and
  8512.  this synchronization is not automatic on the 8087 coprocessor. For code to
  8513.  run correctly on the 8087, you must include the WAIT or FWAIT instruction
  8514.  (they are mnemonics for the same instruction) to ensure that the coprocessor
  8515.  finishes before the processor begins, as shown in the second example. In
  8516.  this situation, the processor does not generate the FWAIT instruction
  8517.  automatically.
  8518.  
  8519.    ; Processor instruction first - No wait needed
  8520.            mov     WORD PTR mem32[0], ax   ; Load memory
  8521.            mov     WORD PTR mem32[2], dx
  8522.            fild    mem32                   ; Load to register
  8523.  
  8524.    ; Coprocessor instruction first - Wait needed (for 8087)
  8525.            fist    mem32                   ; Store to memory
  8526.            fwait                           ; Wait until coprocessor
  8527.                                            ;  is done
  8528.            mov     ax, WORD PTR mem32[0]   ; Move to register
  8529.            mov     dx, WORD PTR mem32[2]
  8530.  
  8531.  When generating code for the 8087 coprocessor, the assembler automatically
  8532.  inserts a WAIT instruction before the coprocessor instruction. However, if
  8533.  you use the .286 or .386 directive, the compiler assumes that the
  8534.  coprocessor instructions are for the 80287 or 80387 and does not insert the
  8535.  WAIT instruction.
  8536.  
  8537.  If your code does not need to run on an 8086 or 8088 processor, you can make
  8538.  your programs shorter and more efficient by using the .286 or .386
  8539.  directive.
  8540.  
  8541.  
  8542.  6.2.4  Using Coprocessor Instructions
  8543.  
  8544.  The 8087 family of coprocessors has separate instructions for each of the
  8545.  following operations:
  8546.  
  8547.  
  8548.    ■   Loading and storing data
  8549.  
  8550.    ■   Doing arithmetic calculations
  8551.  
  8552.    ■   Controlling program flow
  8553.  
  8554.  
  8555.  The following sections explain the available instructions and show how to
  8556.  use them for each of the operations listed above. See Section 6.2.2,
  8557.  "Instruction and Operand Formats," for general syntax information.
  8558.  
  8559.  
  8560.  6.2.4.1  Loading and Storing Data
  8561.  
  8562.  Data-transfer instructions transfer data between main memory and the
  8563.  coprocessor registers or between different coprocessor registers. Two
  8564.  principles govern data transfers:
  8565.  
  8566.  
  8567.    ■   The choice of instruction determines whether a value in memory is
  8568.        considered an integer, a BCD number, or a real number. The value is
  8569.        always considered a 10-byte real number once it is transferred to the
  8570.        coprocessor.
  8571.  
  8572.    ■   The size of the operand determines the size of a value in memory.
  8573.        Values in the coprocessor always take up 10 bytes.
  8574.  
  8575.  
  8576.  Load commands transfer data, and store commands remove data.
  8577.  
  8578.  You can transfer data to stack registers using load commands. These commands
  8579.  push data onto the stack from memory or from coprocessor registers. Store
  8580.  commands remove data. Some store commands pop data off the register stack
  8581.  into memory or coprocessor registers; others simply copy the data without
  8582.  changing it on the stack.
  8583.  
  8584.  If you use constants as operands, you cannot load them directly into
  8585.  coprocessor registers. You must allocate memory and initialize a variable to
  8586.  a constant value. That variable can then be loaded by using one of the load
  8587.  instructions listed below.
  8588.  
  8589.  A few special instructions are provided for loading certain constants. You
  8590.  can load 0, 1, pi, and several common logarithmic values directly. Using
  8591.  these instructions is faster and often more precise than loading the values
  8592.  from initialized variables.
  8593.  
  8594.  All instructions that load constants have the stack top as the implied
  8595.  destination operand. The constant to be loaded is the implied source
  8596.  operand.
  8597.  
  8598.  The coprocessor data area, or parts of it, can also be moved to memory and
  8599.  later loaded back. You may want to do this to save the current state of the
  8600.  coprocessor before executing a procedure. After the procedure ends, restore
  8601.  the previous status. Saving coprocessor data is also useful when you want to
  8602.  modify coprocessor behavior by writing certain data to main memory,
  8603.  operating on the data with 8086-family instructions, and then loading it
  8604.  back to the coprocessor data area.
  8605.  
  8606.  You can use the following instructions for transferring numbers to and from
  8607.  registers:
  8608.  
  8609. ╓┌──────────────────────┌────────────────────────────────────────────────────╖
  8610.  Instruction(s)         Description
  8611.  ────────────────────────────────────────────────────────────────────────────
  8612.  Instruction(s)         Description
  8613.  ────────────────────────────────────────────────────────────────────────────
  8614.  FLD, FST, FSTP         Loads and stores real numbers
  8615.  FILD, FIST, FISTP      Loads and stores binary integers
  8616.  FBLD                   Loads BCD
  8617.  FBSTP                  Stores BCD
  8618.  FXCH                   Exchanges register values
  8619.  FLDZ                   Pushes 0 into ST
  8620.  FLD1                   Pushes 1 into ST
  8621.  FLDPI                  Pushes the value of pi into ST
  8622.  FLDCW mem2byte         Loads the control word into the coprocessor
  8623.  F«N»STCW mem2byte      Stores the control word in memory
  8624.  FLDENV mem14byte       Loads environment from memory
  8625.  F«N»STENV mem14byte    Stores environment in memory
  8626.  FRSTOR mem94byte       Restores state from memory
  8627.  F«N»SAVE mem94byte     Saves state in memory
  8628.  FLDL2E                 Pushes the value of log2e into ST
  8629.  FLDL2T                 Pushes log210 into ST
  8630.  FLDLG2                 Pushes log102 into ST
  8631.  FLDLN2                 Pushes loge2 into ST
  8632.  
  8633.  
  8634.  The following example and Figure 6.7 illustrate some of these instructions:
  8635.  
  8636.  
  8637.    .DATA
  8638.    m1      REAL4   1.0
  8639.    m2      REAL4   2.0
  8640.            .CODE
  8641.            fld     m1      ; Push m1 into first item
  8642.            fld     st(2)   ; Push third item into first
  8643.            fst     m2      ; Copy first item to m2
  8644.            fxch    st(2)   ; Exchange first and third items
  8645.            fstp    m1      ; Pop first item into m1
  8646.  
  8647.  (This figure may be found in the printed book.)
  8648.  
  8649.  
  8650.  6.2.4.2  Doing Arithmetic Calculations
  8651.  
  8652.  Most of the coprocessor instructions for doing arithmetic operations have
  8653.  several forms, depending on the operand used. You do not need to specify the
  8654.  operand type in the instruction if both operands are stack registers, since
  8655.  register values are always 10-byte real numbers. The arithmetic instructions
  8656.  are listed below. In most cases, the result replaces the destination
  8657.  register.
  8658.  
  8659. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  8660.  Instruction                       Description
  8661.  ────────────────────────────────────────────────────────────────────────────
  8662.  FADD                              Adds the source and destination
  8663.  
  8664.  FSUB                              Subtracts the source from the
  8665.                                    destination
  8666.  
  8667.  FSUBR                             Subtracts the destination from the
  8668.                                    source
  8669.  
  8670.  FMUL                              Multiplies the source and the
  8671.                                    destination
  8672.  
  8673.  FDIV                              Divides the destination by the source
  8674.  
  8675.  Instruction                       Description
  8676.  ────────────────────────────────────────────────────────────────────────────
  8677. 
  8678.  FDIVR                             Divides the source by the destination
  8679.  
  8680.  FABS                              Sets the sign of ST to positive
  8681.  
  8682.  FCHS                              Reverses the sign of ST
  8683.  
  8684.  FRNDINT                           Rounds ST to an integer
  8685.  
  8686.  FSQRT                             Replaces the contents of ST with its
  8687.                                    square root
  8688.  
  8689.  FSCALE                            Multiplies the stack-top value by 2 to
  8690.                                    the power contained in ST(1)
  8691.  
  8692.  FPREM                             Calculates the remainder of ST divided
  8693.                                    by ST(1)
  8694.  
  8695.  
  8696.  
  8697.  
  8698.  80387 Only
  8699.  
  8700. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  8701.  Instruction                       Description
  8702.  ────────────────────────────────────────────────────────────────────────────
  8703.  FSIN                              Calculates the sine of the value in ST
  8704.  
  8705.  FCOS                              Calculates the cosine of the value in ST
  8706.  
  8707.  FSINCOS                           Calculates the sine and cosine of the
  8708.                                    value in ST
  8709.  
  8710.  FPREM1                            Calculates the partial remainder by
  8711.                                    performing modulo division on the top
  8712.                                    two stack registers
  8713.  
  8714.  FXTRACT                           Breaks a number down into its exponent
  8715.                                    and mantissa and pushes the mantissa
  8716.                                    onto the register stack
  8717.  Instruction                       Description
  8718.  ────────────────────────────────────────────────────────────────────────────
  8719.                                   onto the register stack
  8720.  
  8721.  F2XM1                             Calculates 2(x)-1
  8722.  
  8723.  FYL2X                             Calculates Y * log2 X
  8724.  
  8725.  FYL2XP1                           Calculates Y * log2 (X+1)
  8726.  
  8727.  FPTAN                             Calculates the tangent of the value in
  8728.                                    ST
  8729.  
  8730.  FPATAN                            Calculates the arctangent of the ratio Y
  8731.                                    /X
  8732.  
  8733.  F«N»INIT                          Resets the coprocessor and restores all
  8734.                                    the default conditions in the control
  8735.                                    and status words
  8736.  
  8737.  F«N»CLEX                          Clears all exception flags and the busy
  8738.  Instruction                       Description
  8739.  ────────────────────────────────────────────────────────────────────────────
  8740. F«N»CLEX                          Clears all exception flags and the busy
  8741.                                    flag of the status word
  8742.  
  8743.  FINCSTP                           Adds 1 to the stack pointer in the
  8744.                                    status word
  8745.  
  8746.  FDECSTP                           Subtracts 1 from the stack pointer in
  8747.                                    the status word
  8748.  
  8749.  FFREE                             Marks the specified register as empty
  8750.  
  8751.  
  8752.  
  8753.  The following example illustrating several arithmetic instructions solves
  8754.  quadratic equations. It does no error checking and fails for some values
  8755.  because it attempts to find the square root of a negative number. You could
  8756.  revise the code using the FTST (Test for Zero) instruction to check for a
  8757.  negative number or 0 before the square root is calculated. If  b2 - 4ac  is
  8758.  negative or 0, the code can jump to routines that handle these two special
  8759.  cases.
  8760.  
  8761.    .DATA
  8762.    a       REAL4   3.0
  8763.    b       REAL4   7.0
  8764.    cc      REAL4   2.0
  8765.    posx    REAL4   0.0
  8766.    negx    REAL4   0.0
  8767.  
  8768.            .CODE
  8769.            .
  8770.            .
  8771.            .
  8772.    ; Solve quadratic equation - no error checking
  8773.    ; The formula is: -b +/- squareroot(b2 - 4ac) / (2a)
  8774.            fld1               ; Get constants 2 and 4
  8775.            fadd    st,st      ; 2 at bottom
  8776.            fld     st         ; Copy it
  8777.            fmul    a          ; = 2a
  8778.  
  8779.            fmul    st(1),st   ; = 4a
  8780.            fxch               ; Exchange
  8781.            fmul    cc         ; = 4ac
  8782.  
  8783.            fld     b          ; Load b
  8784.            fmul    st,st      ; = b2
  8785.            fsubr              ; = b2 - 4ac
  8786.                               ; Negative value here produces error
  8787.            fsqrt              ; = square root(b2 - 4ac)
  8788.            fld     b          ; Load b
  8789.            fchs               ; Make it negative
  8790.            fxch               ; Exchange
  8791.  
  8792.            fld     st         ; Copy square root
  8793.            fadd    st,st(2)   ; Plus version = -b + root(b2 -
  8794.    4ac)
  8795.            fxch               ; Exchange
  8796.            fsubp   st(2),st   ; Minus version = -b - root(b2 -
  8797.    4ac)
  8798.  
  8799.            fdiv    st,st(2)   ; Divide plus version
  8800.            fstp    posx       ; Store it
  8801.            fdivr              ; Divide minus version
  8802.            fstp    negx       ; Store it
  8803.  
  8804.  The examples in online help contain an enhanced version of this procedure.
  8805.  
  8806.  
  8807.  6.2.4.3  Controlling Program Flow
  8808.  
  8809.  The math coprocessors have several instructions that set control flags in
  8810.  the status word. The 8087-family control flags can be used with conditional
  8811.  jumps to direct program flow in the same way that 8086-family flags are
  8812.  used. Since the coprocessor does not have jump instructions, you must
  8813.  transfer the status word to memory so that the flags can be used by
  8814.  8086-family instructions.
  8815.  
  8816.  An easy way to use the status word with conditional jumps is to move its
  8817.  upper byte into the lower byte of the processor flags, as shown in this
  8818.  example:
  8819.  
  8820.    fstsw   mem16      ; Store status word in memory
  8821.            fwait              ; Make sure coprocessor is done
  8822.            mov     ax, mem16  ; Move to AX
  8823.            sahf               ; Store upper word in flags
  8824.  
  8825.  The SAHF (Store AH into Flags) instruction in the example above transfers AH
  8826.  into the low bits of the flags register.
  8827.  
  8828.  You can save several steps by loading the status word directly to AX on the
  8829.  80287 with the FSTSW and FNSTSW instructions. This is the only case in which
  8830.  data can be transferred directly between processor and coprocessor
  8831.  registers, as shown in this example:
  8832.  
  8833.    fstsw   ax
  8834.  
  8835.  The coprocessor control flags and their relationship to the status word are
  8836.  described in Section 6.2.4.4, "Control Registers."
  8837.  
  8838.  The 8087-family coprocessors provide several instructions for comparing
  8839.  operands and testing control flags. All these instructions compare the stack
  8840.  top (ST) to a source operand, which may either be specified or implied as
  8841.  ST(1).
  8842.  
  8843.  The compare instructions affect the C3, C2, and C0 control flags, but not
  8844.  the C1 flag. Table 6.3 shows the flags set for each possible result of a
  8845.  comparison or test.
  8846.  
  8847.  Table 6.3  Control-Flag Settings after Comparison or Test
  8848.  
  8849.  After FCOM        After FTEST                         C3  C2  C0
  8850.  ────────────────────────────────────────────────────────────────────────────
  8851.  ST > source       ST is positive                      0   0   0
  8852.  ST < source       ST is negative                      0   0   1
  8853.  ST = source       ST is 0                             1   0   0
  8854.  Not comparable    ST is NAN or  projective infinity   1   1   1
  8855.  ────────────────────────────────────────────────────────────────────────────
  8856.  
  8857.  Variations on the compare instructions allow you to pop the stack once or
  8858.  twice and to compare integers and zero. For each instruction, the stack top
  8859.  is always the implied destination operand. If you do not give an operand,
  8860.  ST(1) is the implied source. With some compare instructions, you can specify
  8861.  the source as a memory or register operand.
  8862.  
  8863.  All instructions summarized in the following list have implied operands:
  8864.  either ST as a single-destination operand or ST as the destination and ST(1)
  8865.  as the source. These are the instructions for comparing and testing flags.
  8866.  
  8867.  Some instructions have a wait version and a no-wait version. The no-wait
  8868.  versions have N as the second letter.
  8869.  
  8870. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  8871.  Instruction                       Description
  8872.  ────────────────────────────────────────────────────────────────────────────
  8873.  FCOM                              Compares the stack top to the source.
  8874.                                    The
  8875.                                    source and destination are unaffected by
  8876.                                    the comparison.
  8877.  
  8878.  FTST                              Compares ST to 0.
  8879.  
  8880.  FCOMP                             Compares the stack top to the source and
  8881.                                    then pops the stack.
  8882.  
  8883.  FUCOM, FUCOMP, FUCOMPP            Compare the source to ST and set the
  8884.                                    condition codes of the status word
  8885.  Instruction                       Description
  8886.  ────────────────────────────────────────────────────────────────────────────
  8887.                                   condition codes of the status word
  8888.                                    according to the result (80386/486 only).
  8889.  
  8890.  F«N»STSW mem2byte                 Stores the status word in memory.
  8891.  
  8892.  FXAM                              Sets the value of the control flags
  8893.                                    based on the type of the number in ST.
  8894.  
  8895.  FPREM                             Finds a correct remainder for large
  8896.                                    operands. It uses the C2 flag to
  8897.                                    indicate whether the remainder returned
  8898.                                    is partial (C2 is set) or complete (C2
  8899.                                    is clear). (If the bit is set, the
  8900.                                    operation should be repeated. It also
  8901.                                    returns the least-significant three bits
  8902.                                    of the quotient in C0, C3, and C1.)
  8903.  
  8904.  FNOP                              Copies the stack top onto itself, thus
  8905.                                    padding the executable file and taking
  8906.  Instruction                       Description
  8907.  ────────────────────────────────────────────────────────────────────────────
  8908.                                   padding the executable file and taking
  8909.                                    up processing time without having any
  8910.                                    effect on registers or memory.
  8911.  
  8912.  FDISI, FNDISI, FENI, FNENI        Enables or disables interrupts (8087
  8913.                                    only).
  8914.  
  8915.  FSETPM                            Sets protected mode. Requires a .286P or
  8916.                                    .386P directive (80287, 80387, and 80486
  8917.                                    only).
  8918.  
  8919.  
  8920.  
  8921.  The following example illustrates some of these instructions. Notice how
  8922.  conditional blocks are used to enhance 80287 code.
  8923.  
  8924.    .DATA
  8925.    down    REAL4   10.35      ; Sides of a rectangle
  8926.    across  REAL4   13.07
  8927.    diamtr  REAL4   12.93      ; Diameter of a circle
  8928.    status  WORD    ?
  8929.    P287    EQU     (@Cpu AND 00111y)
  8930.            .CODE
  8931.            .
  8932.            .
  8933.            .
  8934.    ; Get area of rectangle
  8935.            fld     across     ; Load one side
  8936.            fmul    down       ; Multiply by the other
  8937.  
  8938.    ; Get area of circle:  Area = PI * (D/2)2
  8939.            fld1               ; Load one and
  8940.            fadd    st, st     ;  double it to get constant 2
  8941.            fdivr   diamtr     ; Divide diameter to get radius
  8942.            fmul    st, st     ; Square radius
  8943.            fldpi              ; Load pi
  8944.            fmul               ; Multiply it
  8945.  
  8946.    ; Compare area of circle and rectangle
  8947.            fcompp             ; Compare and throw both away
  8948.            IF      p287
  8949.            fstsw   ax         ; (For 287+, skip memory)
  8950.            ELSE
  8951.            fnstsw  status     ; Load from coprocessor to memory
  8952.            mov     ax, status ; Transfer memory to register
  8953.            ENDIF
  8954.            sahf               ; Transfer AH to flags register
  8955.            jp      nocomp     ; If parity set, can't compare
  8956.            jz      same       ; If zero set, they're the same
  8957.            jc      rectangle  ; If carry set, rectangle is bigger
  8958.            jmp     circle     ;  else circle is bigger
  8959.  
  8960.    nocomp:                    ; Error handler
  8961.            .
  8962.            .
  8963.            .
  8964.    same:                      ; Both equal
  8965.            .
  8966.            .
  8967.            .
  8968.    rectangle:                 ; Rectangle bigger
  8969.            .
  8970.            .
  8971.            .
  8972.    circle:                    ; Circle bigger
  8973.  
  8974.  Additional instructions for the 80387/486 are FLDENVD and FLDENVW for
  8975.  loading the environment; FNSTENVD, FNSTENVW, FSTENVD, and FSTENVW for
  8976.  storing the environment state; FNSAVED, FNSAVEW, FSAVED, and FSAVEW for
  8977.  saving the coprocessor state; and FRSTORD and FRSTORW for restoring the
  8978.  coprocessor state.
  8979.  
  8980.  The size of the code segment, not the operand size, determines the number of
  8981.  bytes loaded or stored with these instructions. The instructions ending with
  8982.  W store the 16-bit form of the control register data, and the instructions
  8983.  ending with D store the 32-bit form. For example, in 16-bit mode FSAVEW
  8984.  saves the 16-bit control register data. If you need to store the 32-bit form
  8985.  of the control register data, use FSAVED.
  8986.  
  8987.  
  8988.  6.2.4.4  Control Registers
  8989.  
  8990.  Some of the flags of the seven 16-bit control registers control coprocessor
  8991.  operations, while others maintain the current status of the coprocessor. In
  8992.  this sense, they are much like the 8086-family flags registers (see Figure
  8993.  6.8).
  8994.  
  8995.  (This figure may be found in the printed book.)
  8996.  
  8997.  Of the control registers, only the status word register is commonly used
  8998.  (the others are used mostly by systems programmers). The format of the
  8999.  status word register is shown in Figure 6.9, which shows how the coprocessor
  9000.  control flags align with the processor flags. C3 overwrites the zero flag,
  9001.  C2 overwrites the parity flag, and C0 overwrites the carry flag. C1
  9002.  overwrites an undefined bit, so it cannot be used directly with conditional
  9003.  jumps, although you can use the TEST instruction to check C1 in memory or in
  9004.  a register. The status word register also overwrites the sign and
  9005.  auxiliary-carry flags, so you cannot count on their being unchanged after
  9006.  the operation.
  9007.  
  9008.  (This figure may be found in the printed book.)
  9009.  
  9010.  
  9011.  6.3  Using Emulator Libraries
  9012.  
  9013.  If you do not have a math coprocessor or an 80486 processor, you can do most
  9014.  floating-point operations by writing assembly-language procedures and
  9015.  accessing the emulator from a high-level language. All Microsoft high-level
  9016.  languages come with the emulator library.
  9017.  
  9018.  However, you cannot use a Microsoft emulator library with stand-alone
  9019.  assembler programs, since the library depends on the high-level-language
  9020.  start-up code.
  9021.  
  9022.  With emulator libraries, you can use most floating-point instructions.
  9023.  
  9024.  To use the emulator, first write the procedure using coprocessor
  9025.  instructions. Then assemble it using the /FPi option of your compiler.
  9026.  Finally, link it with your high-level-language modules. In MASM 6.0 you can
  9027.  enter options in the Programmer's WorkBench (PWB) environment, or you can
  9028.  use the OPTION EMULATOR in your source code.
  9029.  
  9030.  In emulation mode, the assembler generates instructions for the linker that
  9031.  the Microsoft emulator can use. The form of the OPTION directive in the
  9032.  example below tells the assembler to use emulation mode. This option
  9033.  (introduced in Section 1.3.2) can be defined only once in a module.
  9034.  
  9035.    OPTION EMULATOR
  9036.  
  9037.  Emulator libraries do not allow for all of the coprocessor instructions. The
  9038.  following floating-point instructions are not emulated:
  9039.  
  9040.  (This figure may be found in the printed book.)
  9041.  
  9042.  The set of emulated instructions is different under OS/2 2.x. If you use a
  9043.  coprocessor instruction that is not emulated, your program generates a
  9044.  run-time error when it tries to execute the unemulated instruction.
  9045.  
  9046.  See Chapter 20, "Mixed-Language Programming," for information about writing
  9047.  assembly-language procedures for high-level languages.
  9048.  
  9049.  
  9050.  6.4  Using Binary Coded Decimal Numbers
  9051.  
  9052.  Binary coded decimal (BCD) numbers allow calculations on large numbers
  9053.  without rounding errors. The 8087-family coprocessors can do fast
  9054.  calculations with packed BCD numbers. See Section 6.4.2.2 for details. The
  9055.  8086-family processors can also do some calculations with packed BCD
  9056.  numbers, but the process is slower and more complicated. See Section 6.4.2
  9057.  for details.
  9058.  
  9059.  This section explains how to define BCD numbers and then how to use them in
  9060.  calculations.
  9061.  
  9062.  
  9063.  6.4.1  Defining BCD Constants and Variables
  9064.  
  9065.  Unpacked BCD numbers are made up of bytes containing a single decimal digit
  9066.  in the lower four bits of each byte. Packed BCD numbers are made up of bytes
  9067.  containing two decimal digits: one in the upper four bits and one in the
  9068.  lower four bits. The leftmost digit holds the sign (0 for positive, 1 for
  9069.  negative).
  9070.  
  9071.  Packed BCD numbers are encoded in the 8087 coprocessor's packed BCD format.
  9072.  They can be up to 18 digits long, packed two digits per byte. The assembler
  9073.  zero-pads BCDs initialized with fewer than 18 digits. Digit 20 is the sign
  9074.  bit, and digit 19 is reserved.
  9075.  
  9076.  The TBYTE directive allocates packed BCD constants.
  9077.  
  9078.  When you define an integer constant with the TBYTE directive and the current
  9079.  radix is decimal (t), the assembler interprets the number as a packed BCD
  9080.  number.
  9081.  
  9082.  The syntax for specifying packed BCDs is exactly the same as for other
  9083.  integers.
  9084.  
  9085.    pos1    TBYTE   1234567890  ; Encoded as 00000000001234567890h
  9086.    neg1    TBYTE   -1234567890 ; Encoded as 80000000001234567890h
  9087.  
  9088.  Unpacked BCD numbers are stored one digit to a byte, with the value in the
  9089.  lower four bits. They can be defined using the BYTE directive. For example,
  9090.  an unpacked BCD number could be defined and initialized as shown below:
  9091.  
  9092.    unpackedr      BYTE    1,5,8,2,5,2,9   ; Initialized to 9,252,851
  9093.    unpackedf      BYTE    9,2,5,2,8,5,1   ; Initialized to 9,252,851
  9094.  
  9095.  Least-significant digits can come either first or last, depending on how you
  9096.  write the calculation routines that handle the numbers.
  9097.  
  9098.  
  9099.  6.4.2  Calculating with BCDs
  9100.  
  9101.  When you use the processor to calculate with BCDs, the result is not correct
  9102.  unless you use the ASCII-adjust instructions to convert the result into the
  9103.  valid BCD integer.
  9104.  
  9105.  
  9106.  6.4.2.1  Unpacked BCD Numbers
  9107.  
  9108.  Instructions for unpacked BCDs allow accurate BCD calculations.
  9109.  
  9110.  To do processor arithmetic on unpacked BCD numbers, you must do the
  9111.  eight-bit arithmetic calculations on each digit separately and assign the
  9112.  result to the AL register. After each operation, use the corresponding BCD
  9113.  instruction to adjust the result. The ASCII-adjust instructions do not take
  9114.  an operand. They always work on the value in the AL register.
  9115.  
  9116.  When a calculation using two one-digit values produces a two-digit result,
  9117.  the AAA, AAS, AAM, and AAD instructions put the first digit in AL and the
  9118.  second in AH. If the digit in AL needs to carry to or borrow from the digit
  9119.  in AH, the instructions set the carry and auxiliary carry flags.
  9120.  
  9121.  These instructions get their names from Intel mnemonics that use the term
  9122.  "ASCII" to refer to unpacked BCD numbers and "decimal" to refer to packed
  9123.  BCD numbers. The four ASCII-adjust instructions for unpacked BCDs are
  9124.  described below:
  9125.  
  9126.  Instruction                       Description
  9127.  ────────────────────────────────────────────────────────────────────────────
  9128.  AAA                               Adjusts after an addition operation.
  9129.  
  9130.  AAS                               Adjusts after a subtraction operation.
  9131.  
  9132.  AAM                               Adjusts after a multiplication operation.
  9133.                                    Always use with MUL, not with IMUL.
  9134.  
  9135.  AAD                               Adjusts before a division operation.
  9136.                                    Unlike other BCD instructions, AAD
  9137.                                    converts a BCD value to a binary value
  9138.                                    before the operation. After the
  9139.                                    operation, use AAM to adjust the
  9140.                                    quotient. The remainder is lost. If you
  9141.                                    need the remainder, save it in another
  9142.                                    register before adjusting the quotient.
  9143.                                    Then move it back to AL and adjust if
  9144.                                    necessary.
  9145.  
  9146.  
  9147.  The following examples show how to use each of these instructions in BCD
  9148.  addition, subtraction, multiplication, and division.
  9149.  
  9150.    ; To add 9 and 3 as BCDs:
  9151.            mov     ax, 9       ; Load 9
  9152.            mov     bx, 3       ;  and 3 as unpacked BCDs
  9153.            add     al, bl      ; Add 09h and 03h to get 0Ch
  9154.            aaa                 ; Adjust 0Ch in AL to 02h,
  9155.                                ;  increment AH to 01h, set carry
  9156.                                ; Result 12 (unpacked BCD in AX)
  9157.  
  9158.    ; To subtract 4 from 13:
  9159.            mov     ax, 103h    ; Load 13
  9160.            mov     bx, 4       ;  and 4 as unpacked BCDs
  9161.            sub     al, bl      ; Subtract 4 from 3 to get FFh (-1)
  9162.            aas                 ; Adjust 0FFh in AL to 9,
  9163.                                ;  decrement AH to 0, set carry
  9164.                                ; Result 9 (unpacked BCD in AX)
  9165.  
  9166.    ; To multiply 9 times 3:
  9167.            mov     ax, 903h    ; Load 9 and 3 as unpacked BCDs
  9168.            mul     ah          ; Multiply 9 and 3 to get 1Bh
  9169.            aam                 ; Adjust 1Bh in AL
  9170.                                ;  to get 27 (unpacked BCD in AX)
  9171.  
  9172.    ; To divide 25 by 2:
  9173.            mov     ax, 205h    ; Load 25
  9174.            mov     bl, 2       ;  and 2 as unpacked BCDs
  9175.            aad                 ; Adjust 0205h in AX
  9176.                                ;  to get 19h in AX
  9177.            div     bl          ; Divide by 2 to get
  9178.                                ;  quotient 0Ch in AL
  9179.                                ;  remainder 1 in AH
  9180.            aam                 ; Adjust 0Ch in AL
  9181.                                ;  to 12 (unpacked BCD in AX)
  9182.                                ;  (remainder destroyed)
  9183.  
  9184.  If you process multidigit BCD numbers in loops, each digit is processed and
  9185.  adjusted in turn.
  9186.  
  9187.  
  9188.  6.4.2.2  Packed BCD Numbers
  9189.  
  9190.  Packed BCD numbers are made up of bytes containing two decimal digits: one
  9191.  in the upper four bits and one in the lower four bits. The 8086-family
  9192.  processors provide instructions for adjusting packed BCD numbers after
  9193.  addition and subtraction. You must write your own routines to adjust for
  9194.  multiplication and division.
  9195.  
  9196.  To do processor calculations on packed BCD numbers, you must do the
  9197.  eight-bit arithmetic calculations on each byte separately. The result should
  9198.  always be in the AL register. After each operation, use the corresponding
  9199.  BCD instruction to adjust the result. The decimal-adjust instructions do not
  9200.  take an operand. They always work on the value in the AL register.
  9201.  
  9202.  The 8086-family processors provide DAA (Decimal Adjust after Addition) and
  9203.  DAS (Decimal Adjust after Subtraction) for adjusting packed BCD numbers
  9204.  after addition and subtraction.
  9205.  
  9206.  These examples show DAA and DAS used for adding and subtracting BCDs.
  9207.  
  9208.    ;To add 88 and 33:
  9209.            mov     ax, 8833h   ; Load 88 and 33 as packed BCDs
  9210.            add     al, ah      ; Add 88 and 33 to get 0BBh
  9211.            daa                 ; Adjust 0BBh to 121 (packed BCD:)
  9212.                                ;  1 in carry and 21 in AL
  9213.  
  9214.    ;To subtract 38 from 83:
  9215.            mov     ax, 3883h   ; Load 83 and 38 as packed BCDs
  9216.            sub     al, ah      ; Subtract 38 from 83 to get 04Bh
  9217.            das                 ; Adjust 04Bh to 45 (packed BCD:)
  9218.                                ;  0 in carry and 45 in AL
  9219.  
  9220.  Unlike the ASCII-adjust instructions, the decimal-adjust instructions never
  9221.  affect AH. The assembler sets the auxiliary carry flag if the digit in the
  9222.  lower four bits carries to or borrows from the digit in the upper four bits,
  9223.  and it sets the carry flag if the digit in the upper four bits needs to
  9224.  carry to or borrow from another byte.
  9225.  
  9226.  Multidigit BCD numbers are usually processed in loops. Each byte is
  9227.  processed and adjusted in turn.
  9228.  
  9229.  
  9230.  6.5  Related Topics in Online Help
  9231.  
  9232.  In addition to information on the instructions and directives mentioned in
  9233.  this chapter, information on the following topics can be found in online
  9234.  help, starting from the "MASM 6.0 Contents" screen.
  9235.  
  9236.  Topic                             Access
  9237.  ────────────────────────────────────────────────────────────────────────────
  9238.  Control registers                 Choose "Language Overview," and then
  9239.                                    choose "Coprocessor Status Word,"
  9240.                                    "Coprocessor
  9241.                                    Control Word," or "Coprocessor
  9242.                                    Environment"
  9243.  
  9244.  ML options                        Choose "ML Command Line"
  9245.  
  9246.  Coprocessor instructions          Choose "Coprocessor Instructions"
  9247.  
  9248.  MATHDEMO.ASM                      Choose "Example Code" and then "Map of
  9249.                                    Demos"
  9250.  
  9251.  
  9252.  
  9253.  
  9254.  
  9255.  
  9256.  
  9257.  
  9258.  
  9259.  Chapter 7  Controlling Program Flow
  9260.  ────────────────────────────────────────────────────────────────────────────
  9261.  
  9262.  Very few programs actually execute all lines sequentially from .STARTUP to
  9263.  .EXIT. Rather, complex program logic and efficiency dictate that you control
  9264.  the flow of your program─jumping from one point to another, repeating an
  9265.  action until a condition is reached, and passing control to procedures. This
  9266.  chapter describes various means for controlling program flow and several
  9267.  features that simplify coding program-control constructs.
  9268.  
  9269.  The first section covers jumps from one point in the program to another. It
  9270.  explains how MASM 6.0 optimizes both unconditional and conditional jumps
  9271.  under certain circumstances, so that you do not have to specify every
  9272.  attribute. The section also describes instructions you can use to test
  9273.  conditional jumps.
  9274.  
  9275.  The next section describes loop and decision structures that repeat actions
  9276.  or evaluate conditions. They discuss some new MASM directives, such as
  9277.  .WHILE and .REPEAT, that generate appropriate compare, loop, and jump
  9278.  instructions for you, and the new .IF, .ELSE, and .ELSEIF directives that
  9279.  generate jump instructions.
  9280.  
  9281.  A number of improvements to procedure automation are covered in Section 7.3.
  9282.  These include extended functionality for PROC, a PROTO directive that lets
  9283.  you write procedure prototypes similar to those used in C, an INVOKE
  9284.  directive that automates parameter passing, and new options for the
  9285.  stack-frame setup inside procedures.
  9286.  
  9287.  Finally, the last section explains how to pass control to an interrupt
  9288.  routine.
  9289.  
  9290.  
  9291.  7.1  Jumps
  9292.  
  9293.  Jumps are the most direct method for changing program control from one
  9294.  location to another. At the processor level, jumps work by changing the
  9295.  value of the IP (Instruction Pointer) register from the address of the
  9296.  current instruction to a target address, by changing the CS register for far
  9297.  jumps, and by changing the CS register for far jumps. The many forms of the
  9298.  jump instructions handle jumps based on conditions, flags, and bit settings.
  9299.  
  9300.  
  9301.  This section first describes unconditional jumps, including the new jump
  9302.  optimization features of MASM 6.0 and the use of indirect operands to
  9303.  specify the jump's destination and to construct jump tables. The section
  9304.  then discusses conditional jumps─extending jumps, jumps based on bit or flag
  9305.  status, anonymous jumps, labels for jump targets, and decision directives
  9306.  that generate conditional jumps.
  9307.  
  9308.  
  9309.  7.1.1  Unconditional Jumps
  9310.  
  9311.  Jumps in assembler programs are either conditional or unconditional. The
  9312.  assembler executes conditional jumps only when the jump condition is true.
  9313.  You use the JMP instruction to jump unconditionally to a specified address.
  9314.  Its single operand contains the target address, which can be short, near, or
  9315.  far.
  9316.  
  9317.  Unconditional jumps are often used to skip over code that should not be
  9318.  executed, as shown in this example.
  9319.  
  9320.    ; Handle one case
  9321.    label1: .
  9322.            .
  9323.            .
  9324.            jmp continue
  9325.    ; Handle second case
  9326.    label2: .
  9327.            .
  9328.            .
  9329.            jmp continue
  9330.            .
  9331.            .
  9332.            .
  9333.    continue:
  9334.  
  9335.  The distance of the target from the jump instruction and the size of the
  9336.  operand determine the assembler's encoding of the instruction. The larger
  9337.  the distance, the more bytes the assembler uses to code the instruction. In
  9338.  previous versions of MASM, unconditional NEAR jumps sometimes generate
  9339.  inefficient code. Unspecified FAR jumps result in phase errors.
  9340.  
  9341.  
  9342.  7.1.1.1  Jump Optimizing
  9343.  
  9344.  Beginning with MASM 6.0, the assembler determines the smallest encoding
  9345.  possible for the direct unconditional jump. You do not specify a distance
  9346.  operator, so you do not have to determine the correct distance of the jump.
  9347.  If you do specify a distance, however, and it is too short, the assembler
  9348.  generates an error. A specified distance that is too long causes a less
  9349.  efficient jump to be generated than the assembler would generate if the
  9350.  distance had not been specified.
  9351.  
  9352.  MASM 6.0 optimizes jumps if the following conditions are met:
  9353.  
  9354.  
  9355.    ■   You do not specify SHORT, NEAR, FAR, NEAR16, NEAR32, FAR16, FAR32, or
  9356.        PROC as the distance of the target.
  9357.  
  9358.    ■   The target of the jump is not external and is in the same segment as
  9359.        the jump instruction. If the target is in a different segment (but in
  9360.        the same group), it is treated as if external.
  9361.  
  9362.  
  9363.  If these two conditions are met, MASM uses the instruction, distance, and
  9364.  size of the operand to determine how best to optimize the encoding for the
  9365.  jump. No syntax changes are necessary.
  9366.  
  9367.  ────────────────────────────────────────────────────────────────────────────
  9368.  NOTE
  9369.  This information about jump optimizing also applies to conditional jumps on
  9370.  the 80386/486.
  9371.  ────────────────────────────────────────────────────────────────────────────
  9372.  
  9373.  
  9374.  7.1.1.2  Indirect Operands
  9375.  
  9376.  Indirect operands specify a register or data memory location that holds the
  9377.  address of the jump's destination. Indirect operands differ from the
  9378.  operands of direct jumps by being a memory expression instead of an
  9379.  immediate expression. For indirect jumps, you can specify the encoding for
  9380.  the instruction by giving the size (WORD, DWORD, or FWORD) attributes for
  9381.  the operand.
  9382.  
  9383.  The default rules are based on the .MODEL and the default segment size.
  9384.  
  9385.    jmp     [bx]          ; Uses .MODEL and segment size
  9386.                                  ;  defaults
  9387.            jmp     WORD PTR [bx] ; A NEAR16 indirect call
  9388.  
  9389.  If the indirect operand is a register, the jump is always a NEAR16 jump for
  9390.  a 16-bit register, and FAR32 for a 32-bit register:
  9391.  
  9392.    jmp     bx            ; NEAR16 jump
  9393.            jmp     ebx           ; FAR32  jump
  9394.  
  9395.  A DWORD indirect operand, however, is an ambiguous case:
  9396.  
  9397.    jmp     DWORD PTR [var] ; A NEAR32 jump in a 32-bit
  9398.    segment;
  9399.                                    ;  a FAR16 jump in a 16-bit segment
  9400.  
  9401.  In this case, you must define a type with TYPEDEF to specify the indirect
  9402.  operand.
  9403.  
  9404.    NFP     TYPEDEF PTR NEAR32
  9405.    FFP     TYPEDEF PTR FAR16
  9406.            jmp     NFP PTR [var] ; NEAR32 indirect jump
  9407.            jmp     FFP PTR [var] ; FAR16  indirect jump
  9408.  
  9409.  You can use an unconditional jump as a form of conditional jump by
  9410.  specifying the address in a register or indirect memory operand. Also, you
  9411.  can use indirect memory operands to construct jump tables that work like C
  9412.  switch statements,
  9413.  
  9414.  Pascal CASE statements, or Basic ON GOTO, ON GOSUB, or SELECT CASE
  9415.  statements, as shown in this example:
  9416.  
  9417.    NPVOID  TYPEDEF NEAR PTR VOID
  9418.            .DATA
  9419.    ctl_tbl NPVOID  extended,    ; Null key (extended code)
  9420.                    ctrla,       ; Address of CONTROL-A key routine
  9421.                    ctrlb        ; Address of CONTROL-B key routine
  9422.            .CODE
  9423.            .
  9424.            .
  9425.            .
  9426.            mov     ah, 8h       ; Get a key
  9427.            int     21h
  9428.            cbw                  ; Stretch AL into AX
  9429.            mov     bx, ax       ; Copy
  9430.            shl     bx, 1        ; Convert to address
  9431.            jmp     ctl_tbl[bx]  ; Jump to key routine
  9432.  
  9433.    extended:
  9434.            mov     ah, 8h       ; Get second key of extended key
  9435.            int     21h
  9436.            .                    ; Use another jump table
  9437.            .                    ;  for extended keys
  9438.            .
  9439.            jmp     next
  9440.    ctrla:  .                    ; CONTROL-A code here
  9441.            .
  9442.            .
  9443.            jmp     next
  9444.    ctrlb:  .                    ; CONTROL-B code here
  9445.            .
  9446.            .
  9447.            jmp     next
  9448.            .
  9449.            .
  9450.    next:   .                    ; Continue
  9451.  
  9452.  In this example, the indirect memory operands point to addresses of routines
  9453.  for handling different keystrokes.
  9454.  
  9455.  
  9456.  7.1.2  Conditional Jumps
  9457.  
  9458.  The most common way to transfer control in assembly language is with a
  9459.  conditional jump. This is a two-step process: first test the condition, and
  9460.  then jump if the condition is true or continue if it is false.
  9461.  
  9462.  The conditional jump instructions check flag status.
  9463.  
  9464.  Conditional-jump instructions (except JCXZ) use the status of one or more
  9465.  flags as their condition. Thus, any statement that sets a flag under
  9466.  specified conditions can be the test statement. The most common test
  9467.  statements use the CMP or TEST instructions. The jump statement can be any
  9468.  one of 31 conditional-jump instructions. Conditional-jump instructions take
  9469.  a single operand containing the target address.
  9470.  
  9471.  
  9472.  7.1.2.1  Jump Extending
  9473.  
  9474.  In earlier versions of MASM, the NEAR and FAR operators cannot be used with
  9475.  conditional jumps on the 8086-80286 processors. MASM 6.0 automatically
  9476.  expands the jump instruction to include an unconditional jump to the
  9477.  destination, as long as a distance or size other than SHORT is specified or
  9478.  implicitly required from the operands. That is, MASM now generates the code
  9479.  that previously you had to write.
  9480.  
  9481.  Conditional jumps cannot refer to labels more than 128 bytes away.
  9482.  Therefore, in versions of MASM prior to 6.0, they are often combined with
  9483.  unconditional jumps, which have no such limitation. For example, the
  9484.  following statement is valid as long as  target  is not far away:
  9485.  
  9486.    ; Jump to target less than 128 bytes away
  9487.            jz      target  ; If previous operation resulted in
  9488.                            ;  zero, jump to target
  9489.  
  9490.  However, once  target  becomes too distant, the following sequence is
  9491.  necessary to enable a longer jump. Note that this sequence is logically
  9492.  equivalent to the example above:
  9493.  
  9494.    ; Jumps to distant targets previously required two steps
  9495.            jnz     skip    ; If previous operation result is
  9496.                            ;  NOT zero, jump to "skip"
  9497.            jmp     target  ;  Otherwise, jump to target
  9498.    skip:
  9499.  
  9500.  If the instruction is any of the conditional-jump instructions (except JCXZ
  9501.  and JECXZ ) and the target is greater than 128 bytes or is in a far segment,
  9502.  then jump-extending for an instruction such as  je target  generates two
  9503.  instructions to replace it:
  9504.  
  9505.  
  9506.    1.  The logical negation of the jump instruction, with a destination that
  9507.        skips over the second line it generates
  9508.  
  9509.    2.  An unconditional jump to the target destination
  9510.  
  9511.  
  9512.  For example, if  target  is more than 128 bytes away, MASM generates these
  9513.  lines of code for  je target:
  9514.  
  9515.    jne $ + 2 + (length in bytes of the next instruction)
  9516.             jmp NEAR PTR target
  9517.  
  9518.  Now the conditional jump executes correctly.
  9519.  
  9520.  The assembler generates this same code sequence if you specify the distance
  9521.  with NEAR PTR, FAR PTR, or SHORT. Therefore,
  9522.  
  9523.    jz      NEAR PTR target
  9524.  
  9525.  becomes
  9526.  
  9527.    jne     $ + 5
  9528.             jmp     NEAR PTR target
  9529.  
  9530.  even if  target  is nearby.
  9531.  
  9532.  When  skip  is more than 128 bytes away, this example
  9533.  
  9534.    mov     ax, cx
  9535.            jz      skip     ; Skip is more than 128 bytes away
  9536.            .
  9537.            .                ; (additional code here)
  9538.            .
  9539.    skip:
  9540.  
  9541.  generates code that looks like this:
  9542.  
  9543.    7327:0000 8BC1           MOV       AX,CX
  9544.    7327:0002 7503           JNZ       0007
  9545.    7327:0004 E9C000         JMP       00C7
  9546.    7327:0007                (more code here)
  9547.  
  9548.  MASM 6.0 enables this jump expansion feature by default, but you can turn it
  9549.  off with the NOLJMP form of the OPTION directive. See Section 1.3.2 for
  9550.  information about the OPTION directive.
  9551.  
  9552.  If the assembler generates code to extend a conditional jump, it issues a
  9553.  level 3 warning saying that the conditional jump has been lengthened. You
  9554.  can set the warning level to 1 for development and to level 3 for a final
  9555.  optimizing pass to see if you can shorten jumps by reorganizing.
  9556.  
  9557.  If you specify the distance for the jump and the target is out of range for
  9558.  that distance, a "Jump out of Range" error results.
  9559.  
  9560.  Since the JCXZ and JECXZ instructions do not have logical negations,
  9561.  expansion of the jump instruction to handle targets with unspecified
  9562.  distances cannot be performed for those instructions. Therefore the distance
  9563.  must always be short.
  9564.  
  9565.  The size and distance of the target operand determines the encoding for
  9566.  conditional or unconditional jumps to externals or targets in different
  9567.  segments. The new jump-extending and optimization features do not apply in
  9568.  this case.
  9569.  
  9570.  ────────────────────────────────────────────────────────────────────────────
  9571.  NOTE
  9572.  
  9573.  Conditional jumps on the 80386 and 80486 processors can be to targets up to
  9574.  32K bytes away, so jump extension occurs only for targets greater than that
  9575.  distance.
  9576.  ────────────────────────────────────────────────────────────────────────────
  9577.  
  9578.  
  9579.  7.1.2.2  Jumps Based on Comparisons
  9580.  
  9581.  The CMP instruction is specifically designed to test for conditional jumps.
  9582.  It does not change the destination operand─it compares two values without
  9583.  changing either of them. Instructions that change operands (such as SUB or
  9584.  AND) can also be used to test conditions.
  9585.  
  9586.  SUB and CMP set the same flags.
  9587.  
  9588.  Internally, the CMP instruction is the same as the SUB instruction, except
  9589.  that CMP does not change the destination operand. Both set flags according
  9590.  to the result that the subtraction generates.
  9591.  
  9592.  Table 7.1 lists conditional-jump instructions for each comparison
  9593.  relationship and shows the flags that are tested to see if the relationship
  9594.  is true. Note the difference in instructions depending on the sign of the
  9595.  operands. Some of these are equivalent to instructions listed in the
  9596.  previous section.
  9597.  
  9598.  Table   7.1 Conditional-Jump Instructions Used after Compare Instruction
  9599.  
  9600. ╓┌──────────────┌──────────────┌──────────────┌──────────────┌───────────────╖
  9601.  Jump           Signed         Flags Tested   Unsigned       Flags Tested
  9602.  Condition      Compare        (Jump if True)  Compare        (Jump if True)
  9603.  ────────────────────────────────────────────────────────────────────────────
  9604.  =    (Equal)   JE             ZF = 1         JE             ZF = 1
  9605.  
  9606.  (Not equal)    JNE            ZF = 0         JNE            ZF = 0
  9607.  
  9608.  >    (Greater  JG or JNLE     ZF = 0 and     JA or JNBE     CF = 0 and
  9609.  than)                         SF = 0F                       ZF = 0
  9610.  
  9611.  <=   (Less     JLE or JNG     ZF = 1 or      JBE or JNA     CF = 1 or
  9612.  than                          SF  0F                        ZF = 1
  9613.         or
  9614.  equal to)
  9615.  
  9616.  <    (Less     JL or JNGE     SF  0F         JB or JNAE     CF = 1
  9617.  than)
  9618.  
  9619.  >=  (Greater   JGE or JNL     SF = 0F        JAE or JNB     CF = 0
  9620.  Jump           Signed         Flags Tested   Unsigned       Flags Tested
  9621.  Condition      Compare        (Jump if True)  Compare        (Jump if True)
  9622.  ────────────────────────────────────────────────────────────────────────────
  9623. >=  (Greater   JGE or JNL     SF = 0F        JAE or JNB     CF = 0
  9624.  than
  9625.         or
  9626.  equal to)
  9627.  
  9628.  ────────────────────────────────────────────────────────────────────────────
  9629.  
  9630.  
  9631.  
  9632.  In the CMP instruction, the mnemonic names always refer to the relationship
  9633.  of the first operand to the second operand. For instance, in this example JG
  9634.  tests whether the first operand is greater than the second.
  9635.  
  9636.    cmp     ax, bx  ; Compares ax and bx
  9637.            jg      contin  ; Equivalent to:  If ( ax > bx ) goto
  9638.                            ;  contin
  9639.            jl      next    ; Equivalent to:  If ( ax < bx ) goto next
  9640.  
  9641.  Several conditional instructions have two names. For example, JG and JNLE
  9642.  (Jump if Not Less or Equal) are equivalent. You can use whichever name seems
  9643.  more mnemonic in context.
  9644.  
  9645.  
  9646.  7.1.2.3  Testing Bits and Jumping
  9647.  
  9648.  Using CMP is not the only way to check a condition prior to a jump. You can
  9649.  also check the status of bits in the operands using the TEST instruction.
  9650.  This instruction tests for conditions prior to jumps by comparing specific
  9651.  bits rather than entire operands. Jump execution depends on whether certain
  9652.  bits are on or off.
  9653.  
  9654.  Pairs of operands cannot be both registers or both memory locations.
  9655.  
  9656.  The TEST instruction is the same as the AND instruction, except that TEST
  9657.  changes neither operand. If the result of the operation is 0, the zero flag
  9658.  is set, but the 0 is not actually written to the destination operand. The
  9659.  following example shows an application of TEST.
  9660.  
  9661.    .DATA
  9662.    bits    BYTE    ?
  9663.            .CODE
  9664.            .
  9665.            .
  9666.            .
  9667.    ; If bit 2 or bit 4 is set, then call task_a
  9668.                                 ; Assume "bits" is 0D3h    11010011
  9669.            test    bits, 10100y ; If 2 or 4 is set     AND 00010100
  9670.            jz      skip1        ;                          --------
  9671.            call    task_a       ; Then call task_a         00010000
  9672.    skip1:                       ; Jump taken
  9673.            .
  9674.            .
  9675.            .
  9676.    ; If bits 2 and 4 are clear, then call task_b
  9677.                                 ; Assume "bits" is 0E9h    11101001
  9678.            test    bits, 10100y ; If 2 and 4 are clear AND 00010100
  9679.            jnz     skip2        ;                          --------
  9680.            call    task_b       ; Then call task_b         00000000
  9681.    skip2:                       ; Jump taken
  9682.  
  9683.  Generally, when you use TEST, one of the operands is a mask in which the
  9684.  bits to be tested are the only bits set. The other operand contains the
  9685.  value to be tested. If all the bits set in the mask are clear in the operand
  9686.  being tested, the zero flag is set. If any of the flags set in the mask are
  9687.  also set in the operand, the zero flag is cleared.
  9688.  
  9689.  
  9690.  7.1.2.4  Jumping Based on Flag Status
  9691.  
  9692.  Your code can jump based on the condition of flags rather than on the
  9693.  relationships of operands. Use the following conditional-jump instructions:
  9694.  
  9695.  
  9696. ╓┌───────────────────┌───────────────────────────────────────────────────────╖
  9697.  Instruction         Jumps if
  9698.  ────────────────────────────────────────────────────────────────────────────
  9699.  JO                  The overflow flag is set
  9700.  
  9701.  JNO                 The overflow flag is clear
  9702.  
  9703.  JC                  The carry flag is set (same as JB)
  9704.  Instruction         Jumps if
  9705.  ────────────────────────────────────────────────────────────────────────────
  9706. JC                  The carry flag is set (same as JB)
  9707.  
  9708.  JNC                 The carry flag is clear (same as JAE)
  9709.  
  9710.  JZ                  The zero flag is set (same as JE)
  9711.  
  9712.  JNZ                 The zero flag is clear (same as JNE)
  9713.  
  9714.  JS                  The sign flag is set
  9715.  
  9716.  JNS                 The sign flag is clear
  9717.  
  9718.  JP                  The parity flag is set
  9719.  
  9720.  JNP                 The parity flag is clear
  9721.  
  9722.  JPE                 Parity is even (parity flag set)
  9723.  
  9724.  JPO                 Parity is odd (parity flag clear)
  9725.  Instruction         Jumps if
  9726.  ────────────────────────────────────────────────────────────────────────────
  9727. JPO                 Parity is odd (parity flag clear)
  9728.  
  9729.  JCXZ                CX is 0
  9730.  
  9731.  JECXZ               ECX is 0
  9732.  (80386/486 only)
  9733.  
  9734.  
  9735.  
  9736.  The following example shows two ways to use the instructions from the list
  9737.  above:
  9738.  
  9739.    ; Uses JO to handle overflow condition
  9740.            add     ax, bx      ; Add two values
  9741.            jo      overflow    ; If value too large, adjust
  9742.  
  9743.    ; Uses JNZ to check for zero as the result of subtraction
  9744.            sub     ax, bx      ; Subtract
  9745.            jnz     skip        ; If the result is not zero, continue
  9746.            call    zhandler    ; Else do special case
  9747.  
  9748.  
  9749.  7.1.2.5  Anonymous Labels
  9750.  
  9751.  Anonymous labels are alternatives to named labels.
  9752.  
  9753.  Coding jumps in assembly language requires that you invent many label names.
  9754.  One alternative to continually thinking up new label names is using
  9755.  anonymous labels, which you can use anywhere in your program. But because
  9756.  anonymous labels do not provide meaningful names, they are best used for
  9757.  conditionally testing a few lines of code. You should mark major divisions
  9758.  of a program with actual named labels.
  9759.  
  9760.  Use two at signs (@) followed by a colon (:) as an anonymous label. To jump
  9761.  to the nearest preceding anonymous label, use @B (back) in the jump
  9762.  instruction's operand field; to jump to the nearest following anonymous
  9763.  label, use @F (forward) in the operand field.
  9764.  
  9765.  The jump in the example below uses an anonymous label:
  9766.  
  9767.    ; DX is 20, unless CX is less than -20, then make DX 30
  9768.            mov     dx, 20
  9769.            cmp     cx, -20
  9770.            jge     @F
  9771.            mov     dx, 30
  9772.    @:
  9773.  
  9774.  The items  @B  and  @F  always refer to the nearest occurrences of @:, so
  9775.  there is never any conflict between different anonymous labels.
  9776.  
  9777.  
  9778.  7.1.2.6  Decision Directives
  9779.  
  9780.  The high-level structures you can use for decision-making are the .IF,
  9781.  .ELSEIF, and .ELSE statements. These directives generate conditional jumps.
  9782.  The expression following the .IF directive is evaluated, and if true, the
  9783.  following instructions are executed until the next .ENDIF, .ELSE, or .ELSEIF
  9784.  directive is reached. The .ELSE statements execute if the expression is
  9785.  false. Using the .ELSEIF directive puts a new expression to be evaluated
  9786.  inside the alternative part of the original .IF statement. The syntax is
  9787.  
  9788.    .IF condition1
  9789.    statements
  9790.    «.ELSEIF condition2
  9791.    statements»
  9792.    «.ELSE
  9793.    statements»
  9794.    .ENDIF
  9795.  
  9796.  The decision structure
  9797.  
  9798.    .IF     cx = 20
  9799.            mov     dx, 20
  9800.            .ELSE
  9801.            mov     dx, 30
  9802.            .ENDIF
  9803.  
  9804.  generates this code:
  9805.  
  9806.    .IF  cx == 20
  9807.    0017  83 F9 14        *         cmp    cx, 014h
  9808.    001A  75 05           *         jne    @C0001
  9809.    001C  BA 0014                   mov    dx, 20
  9810.                               .ELSE
  9811.    001F  EB 03           *         jmp    @C0003
  9812.    0021                  *@C0001:
  9813.    0021  BA 001E                   mov   dx, 30
  9814.                               .ENDIF
  9815.    0024                  *@C0003:
  9816.  
  9817.  
  9818.  7.2  Loops
  9819.  
  9820.  Loops repeat an action until a termination condition is reached. This
  9821.  condition can be a counter or the result of an expression's evaluation. MASM
  9822.  6.0 offers many ways to set up loops in your programs. The following list
  9823.  compares MASM loop structures.
  9824.  
  9825.  Instructions                      Action
  9826.  ────────────────────────────────────────────────────────────────────────────
  9827.  LOOP                              Automatically decrements CX. When CX = 0,
  9828.                                    the loop ends. The top of the loop
  9829.                                    cannot be greater than 128 bytes from
  9830.                                    the LOOP instruction. (This is true for
  9831.                                    all LOOP instructions.)
  9832.  
  9833.  LOOPE, LOOPZ, LOOPNE, LOOPNZ      Loops while equal (or not equal). Checks
  9834.                                    CX and a condition. The loop ends when
  9835.                                    the condition is true. Set CX to a
  9836.                                    number out of range if you don't want a
  9837.                                    count to control the loop.
  9838.  
  9839.  JCXZ, JECXZ                       Branches to a label only if CX = 0 (ECX
  9840.                                    on the 80386). Useful for testing
  9841.                                    condition of CX before beginning loop.
  9842.                                    If CX = 0 before entering the loop, CX
  9843.                                    decrements to -1 on the first iteration
  9844.                                    and then must be decremented 65,535
  9845.                                    times before it reaches 0 again. Unlike
  9846.                                    conditional-jump instructions, which can
  9847.                                    jump to either a near or a short label
  9848.                                    under the 80386 or 80486, the loop
  9849.                                    instructions JCXZ and JECXZ always jump
  9850.                                    to a short label.
  9851.  
  9852.  Conditional jumps                 Acts only if certain conditions met.
  9853.                                    Necessary if several conditions must be
  9854.                                    tested. See Section 7.1.2, "Conditional
  9855.                                    Jumps."
  9856.  
  9857.  The following examples illustrate these loop constructions.
  9858.  
  9859.    ; The LOOP instruction: For 200 to 0 do task
  9860.            mov     cx, 200         ; Set counter
  9861.    next:   .                       ; Do the task here
  9862.            .
  9863.            .
  9864.            loop    next            ; Do again
  9865.                                    ; Continue after loop
  9866.  
  9867.    ; The LOOPNE instruction: While AX is not 'Y', do task
  9868.            mov     cx, 256         ; Set count too high to interfere
  9869.    wend:   .                       ; But don't do more than 256 times
  9870.            .                       ; Some statements that change AX
  9871.            .
  9872.            cmp     al, 'Y'         ; Is it Y or too many times?
  9873.            loopne  wend            ; No? Repeat
  9874.                                    ; Yes? Continue
  9875.  
  9876.    ; Using JCXZ:  For 0 to CX do task
  9877.                                    ; CX counter set previously
  9878.            jcxz    done            ; Check for 0
  9879.    next:   .                       ; Do the task here
  9880.            .
  9881.            .
  9882.            loop    next            ; Do again
  9883.    done:                           ; Continue after loop
  9884.  
  9885.  
  9886.  7.2.1  Loop-Generating Directives
  9887.  
  9888.  These directives are new to MASM 6.0.
  9889.  
  9890.  The high-level control structures new to MASM 6.0 generate loop structures
  9891.  for you. These new directives are similar to the while and repeat loops of C
  9892.  or Pascal. They can make your assembly programs less repetitive and easier
  9893.  to code, as well as easier to read. The assembler generates the appropriate
  9894.  assembly code. The .BREAK and .CONTINUE directives are also implemented to
  9895.  interrupt loop execution. These directives are summarized in the following
  9896.  list:
  9897.  
  9898.  Directives                        Action
  9899.  ────────────────────────────────────────────────────────────────────────────
  9900.  .WHILE, .ENDW                     The statements between .WHILE condition
  9901.                                    and .ENDW execute while the condition is
  9902.                                    true.
  9903.  
  9904.  .REPEAT, .UNTIL                   The loop executes at least once and
  9905.                                    continues until the condition given
  9906.                                    after .UNTIL is true. Generates
  9907.                                    conditional jumps.
  9908.  
  9909.  .REPEAT, .UNTILCXZ                Compares label to an expression and
  9910.                                    generates appropriate loop instructions.
  9911.  
  9912.  
  9913.  These constructs work much as they do in a high-level language such as C or
  9914.  Pascal. Keep in mind the following points:
  9915.  
  9916.  
  9917.    ■   These directives generate appropriate processor instructions. They are
  9918.        not new instructions.
  9919.  
  9920.    ■   They require proper use of signed and unsigned data declarations.
  9921.  
  9922.  
  9923.  These directives cause a set of instructions to execute based on the
  9924.  evaluation of some condition. This condition can be an expression that
  9925.  evaluates to a negative or nonnegative value, an expression using the binary
  9926.  operators in C (&&, ||, or !), or the state of a flag. See Section 7.2.2.1
  9927.  for more information about expression operators.
  9928.  
  9929.  The evaluation of the condition requires the assembler to know if the
  9930.  operands in the condition are signed or unsigned. To state explicitly that a
  9931.  named memory location contains a signed integer, use the signed data
  9932.  allocation directives: SBYTE, SWORD, and SDWORD.
  9933.  
  9934.  
  9935.  7.2.1.1  .WHILE Loops
  9936.  
  9937.  As with while loops in C or Pascal, the test condition for .WHILE is checked
  9938.  before the statements inside the loop execute. If the test condition is
  9939.  false, the loop does not execute. While the condition is true, the
  9940.  statements inside the loop repeat.
  9941.  
  9942.  Use the .ENDW directive to mark the end of the .WHILE loop. When the
  9943.  condition becomes false, program execution begins at the first statement
  9944.  following the .ENDW directive. The .WHILE directive generates appropriate
  9945.  compare and jump statements. The syntax is
  9946.  
  9947.  .WHILE condition statements .ENDW
  9948.  
  9949.  For example, this loop copies one buffer to another until a `$' character
  9950.  (marking the end of the string) is found:
  9951.  
  9952.    .DATA
  9953.            buf1    BYTE "This is a string",'$'
  9954.            buf2    BYTE 100 DUP (?)
  9955.            .CODE
  9956.            sub     bx, bx            ; Zero out bx
  9957.            .WHILE  (buf1[bx] != '$')
  9958.            mov     al, buf1[bx]      ; Get a character
  9959.            mov     buf2[bx], al      ; Move it to buffer 2
  9960.            inc     bx                ; Count forward
  9961.            .ENDW
  9962.  
  9963.  
  9964.  7.2.1.2  .REPEAT Loops
  9965.  
  9966.  MASM's .REPEAT directive allows for loop constructions like the do loop of C
  9967.  and the REPEAT loop of Pascal. The loop executes until the condition
  9968.  following the .UNTIL (or .UNTILCXZ) directive becomes true. Since the
  9969.  condition is checked at the end of the loop, the loop always executes at
  9970.  least once. The .REPEAT directive generates conditional jumps. The syntax
  9971.  is:
  9972.  
  9973.    .REPEAT
  9974.    statements
  9975.    .UNTIL condition
  9976.  
  9977.    .REPEAT
  9978.    statements
  9979.    .UNTILCXZ «condition»
  9980.  
  9981.  A condition is optional with .UNTILCXZ.
  9982.  
  9983.  where condition can also be expr1 == expr2 or expr1 != expr2. When two
  9984.  conditions are used, expr2 can be an immediate expression, a register, or
  9985.  (if expr1 is a register) a memory location.
  9986.  
  9987.  For example, the following code fills up a buffer with characters typed at
  9988.  the keyboard. The loop ends when the ENTER key (character 13) is pressed:
  9989.  
  9990.    .DATA
  9991.    buffer  BYTE    100 DUP (0)
  9992.            .CODE
  9993.            sub     bx, bx             ; Zero out bx
  9994.            .REPEAT
  9995.            mov     ah, 01h
  9996.            int     21h                ; Get a key
  9997.            mov     buffer[bx], al     ; Put it in the buffer
  9998.            inc     bx                 ; Increment the count
  9999.            .UNTIL (al == 13)          ; Continue until al is 13
  10000.  
  10001.  The .UNTIL directive generates conditional jumps, but the .UNTILCXZ
  10002.  directive generates a LOOP instruction, as shown by the listing file code
  10003.  for these examples. In a listing file, assembler-generated code is preceded
  10004.  by an asterisk.
  10005.  
  10006.    ASSUME  bx:PTR SomeStruct
  10007.  
  10008.                .REPEAT
  10009.           *@C0001:
  10010.                     inc    ax
  10011.                .UNTIL  ax==6
  10012.           *         cmp    ax, 006h
  10013.           *         jne    @C0001
  10014.  
  10015.    .REPEAT
  10016.           *@C0003:
  10017.                     mov    ax, 1
  10018.                .UNTILCXZ
  10019.           *         loop   @C0003
  10020.  
  10021.                .REPEAT
  10022.           *@C0004:
  10023.                .UNTILCXZ   [bx].field != 6
  10024.           *         cmp    [bx].field, 006h
  10025.           *         loope  @C0004
  10026.  
  10027.  
  10028.  7.2.1.3  .BREAK and .CONTINUE Directives
  10029.  
  10030.  .BREAK and .CONTINUE interrupt loop execution.
  10031.  
  10032.  The .BREAK and .CONTINUE directives can be used to terminate a .REPEAT or
  10033.  .WHILE loop prematurely. These directives allow an optional .IF clause for
  10034.  conditional breaks. The syntax is
  10035.  
  10036.    .BREAK «.IF condition»
  10037.    .CONTINUE «.IF condition»
  10038.  
  10039.  Note that .ENDIF is not used with the .IF forms of .BREAK and .CONTINUE in
  10040.  this context. The .BREAK and .CONTINUE directives work the same way as the
  10041.  break and continue instructions in C. Execution continues at the instruction
  10042.  following the .UNTIL, .UNTILCXZ, or .ENDW of the nearest enclosing loop.
  10043.  
  10044.  Instead of causing the loop execution to end as .BREAK does, .CONTINUE
  10045.  causes loop execution to jump directly to the code that evaluates the loop
  10046.  condition of the nearest enclosing loop.
  10047.  
  10048.  The following loop accepts only the keys in the range `0' to `9' and
  10049.  terminates when ENTER is pressed.
  10050.  
  10051.    .WHILE 1                ; Loop forever
  10052.            mov     ah, 08h         ; Get key without echo
  10053.            int     21h
  10054.            .BREAK .IF al == 13     ; If ENTER, break out of the loop
  10055.            .CONTINUE .IF (al < '0') || (al > '9')
  10056.                                    ; If not a digit, continue looping
  10057.            mov     dl, al          ; Save the character for processing
  10058.            mov     ah, 02h         ; Output the character
  10059.            int     21h
  10060.            .ENDW
  10061.  
  10062.  If you assemble the source code above with the /Fl and /Sg command-line
  10063.  options and then view the results in the listing file, you would see this
  10064.  code:
  10065.  
  10066.    .WHILE 1
  10067.     0017                    *@C0001:
  10068.     0017  B4 08                       mov    ah, 08h
  10069.     0019  CD 21                       int    21h
  10070.                                .BREAK .IF al == 13
  10071.     001B  3C 0D             *         cmp    al, 00Dh
  10072.     001D  74 10             *         je     @C0002
  10073.                                .CONTINUE .IF (al  '0') || (al  '9')
  10074.     001F  3C 30             *         cmp    al, '0'
  10075.     0021  72 F4             *         jb     @C0001
  10076.     0023  3C 39             *         cmp    al, '9'
  10077.     0025  77 F0             *         ja     @C0001
  10078.     0027  8A D0                       mov    dl, al
  10079.     0029  B4 02                       mov    ah, 02h
  10080.     002B  CD 21                       int    21h
  10081.                                .ENDW
  10082.     002D  EB E8             *         jmp    @C0001
  10083.     002F                    *@C0002:
  10084.  
  10085.  The high-level control structures can be nested. That is, .REPEAT or .WHILE
  10086.  loops can contain .REPEAT or .WHILE loops as well as .IF statements.
  10087.  
  10088.  If the code generated by a .WHILE loop, .REPEAT loop, or .IF statement
  10089.  generates a conditional or unconditional jump, MASM uses the jump extension
  10090.  and jump optimization techniques described in Sections 7.1.1, "Unconditional
  10091.  Jumps," and 7.1.2, "Conditional Jumps," to encode the jump appropriately.
  10092.  
  10093.  
  10094.  7.2.2  Writing Loop Conditions
  10095.  
  10096.  You can express the conditions of the .IF, .REPEAT, and .WHILE directives
  10097.  using relational operators, and you can express the attributes of the
  10098.  operand with the PTR operator. To write loop conditions, you also need to
  10099.  know how the assembler evaluates the operators and operands in the
  10100.  condition. This section explains the operators, attributes, precedence
  10101.  level, and expression evaluation order for the conditions used with
  10102.  loop-generating directives.
  10103.  
  10104.  
  10105.  7.2.2.1  Expression Operators
  10106.  
  10107.  The binary relational operators in MASM 6.0 high-level control structures
  10108.  are listed below. The same binary operators are used in C. These operators
  10109.  generate MASM compare, test, and conditional jump instructions.
  10110.  
  10111. ╓┌──────────────────────┌────────────────────────────────────────────────────╖
  10112.  Operator               Meaning
  10113.  ────────────────────────────────────────────────────────────────────────────
  10114.  ==                     Equal
  10115.  !=                     Not equal
  10116.  >                      Greater than
  10117.  >=                     Greater than or equal to
  10118.  <                      Less than
  10119.  <=                     Less than or equal to
  10120.  &                      Bit test
  10121.  !                      Logical NOT
  10122.  &&                     Logical AND
  10123.  ||                     Logical OR
  10124.  Operator               Meaning
  10125.  ────────────────────────────────────────────────────────────────────────────
  10126. ||                     Logical OR
  10127.  
  10128.  
  10129.  A condition without operators (other than !) tests for nonzero as it does in
  10130.  C. For example,  .WHILE (x)  is the same as  .WHILE (x != 0), and  .WHILE
  10131.  (!x)  is the same as  .WHILE (x == 0).
  10132.  
  10133.  Flag names can be operands in a condition.
  10134.  
  10135.  You can also use the flag names (ZERO?, CARRY?, OVERFLOW?, SIGN?, and
  10136.  PARITY?) as operands in conditions with the high-level control structures as
  10137.  in .WHILE (CARRY?). The particular flag set determines the outcome of the
  10138.  condition. Use flag names when you want to generate the compare or other
  10139.  instructions that set the flags.
  10140.  
  10141.  
  10142.  7.2.2.2  Signed and Unsigned Operands
  10143.  
  10144.  Registers, constants, and memory locations are unsigned by default.
  10145.  
  10146.  Expression operators generate unsigned jumps by default. However, if either
  10147.  side of the operation is signed, then the entire operation is considered
  10148.  signed. The default for the operands in registers, constants, and named
  10149.  memory locations is also to be unsigned.
  10150.  
  10151.  You can use the PTR operator to tell the assembler that a particular operand
  10152.  in a register or constant is a signed number, as in these examples:
  10153.  
  10154.    .WHILE  SWORD PTR [bx] <= 0
  10155.            .IF     SWORD PTR mem1 >  0
  10156.  
  10157.  Without the PTR operator, the assembler would treat the contents of BX as an
  10158.  unsigned value.
  10159.  
  10160.  You can also specify the size attributes of operands in memory locations
  10161.  with SBYTE, SWORD, and SDWORD, for use with .IF, .WHILE, and .REPEAT.
  10162.  
  10163.    .DATA
  10164.    mem1    SBYTE   ?
  10165.    mem2    WORD    ?
  10166.            .IF     mem1 > 0
  10167.            .WHILE  mem2 < bx
  10168.            .WHILE  SWORD PTR ax < count
  10169.  
  10170.  
  10171.  7.2.2.3  Precedence Level
  10172.  
  10173.  As with C, you can concatenate conditions with the && operator for AND, the
  10174.  || operator for OR, and the ! operator for negate. The precedence level is
  10175.  !, &&, and ||, with ! having the highest precedence. Like expressions in
  10176.  high-level languages, associativity is evaluated left to right.
  10177.  
  10178.  
  10179.  7.2.2.4  Expression Evaluation
  10180.  
  10181.  The assembler evaluates conditions created with high-level control
  10182.  structures according to short-circuit evaluation. If the evaluation of a
  10183.  particular condition automatically determines the final result (such as a
  10184.  condition that evaluates to false in a compound statement concatenated with
  10185.  AND), the evaluation does not continue.
  10186.  
  10187.  For example, in this .WHILE statement,
  10188.  
  10189.    .WHILE (ax > 0) && (WORD PTR [bx] == 0)
  10190.  
  10191.  the assembler evaluates the first condition. If this condition is false
  10192.  (that is, if AX is less than or equal to 0), the evaluation is finished. The
  10193.  second condition is not checked and the loop does not execute, because a
  10194.  compound condition containing a && requires both expressions to be true for
  10195.  the entire condition to be true.
  10196.  
  10197.  
  10198.  
  10199.  
  10200.  
  10201.  7.3  Procedures
  10202.  
  10203.  Organizing your code into procedures that execute specific tasks divides
  10204.  large programs into manageable units, allows for separate testing, and makes
  10205.  code more efficient for repetitive tasks.
  10206.  
  10207.  Assembly-language procedures are comparable to functions in C; subprograms,
  10208.  functions, and subroutines in Basic; procedures and functions in Pascal; or
  10209.  subroutines and functions in FORTRAN.
  10210.  
  10211.  Two instructions control the use of assembly-language procedures; CALL
  10212.  pushes the return address onto the stack and transfers control to a
  10213.  procedure, and RET pops the return address off the stack and returns control
  10214.  to that location.
  10215.  
  10216.  The PROC and ENDP directives mark the beginning and end of a procedure.
  10217.  Additionally, PROC can automatically
  10218.  
  10219.  
  10220.    ■   Preserve register values that should not change but that the procedure
  10221.        might otherwise alter
  10222.  
  10223.    ■   Set up a local stack pointer, so that you can access parameters and
  10224.        local variables placed on the stack
  10225.  
  10226.    ■   Adjust the stack when the procedure ends
  10227.  
  10228.  
  10229.  Sections 7.3.1 through 7.3.3 give information on techniques for calling
  10230.  procedures and accessing parameters. Sections 7.3.4 through 7.3.5 show how
  10231.  to allocate and access local variables and parameters.
  10232.  
  10233.  Sections 7.3.6 and 7.3.7 introduce new directives in MASM 6.0 to further
  10234.  automate calling procedures and passing arguments. The PROTO directive
  10235.  allows you to declare prototypes for your procedures. INVOKE handles
  10236.  procedure calls and stack cleanup. Section 7.3.8 describes the automatic
  10237.  stack setup and cleanup generated with PROC.
  10238.  
  10239.  
  10240.  7.3.1  Defining Procedures
  10241.  
  10242.  Procedures require a label at the start of the procedure and a return at the
  10243.  end. Procedures are normally defined by using the PROC directive at the
  10244.  start of the procedure and the ENDP directive at the end. The RET
  10245.  instruction is normally placed immediately before the ENDP directive. The
  10246.  assembler makes sure that the distance of the RET instruction matches the
  10247.  distance defined by the PROC directive. The basic syntax for PROC is
  10248.  
  10249.    label PROC [[NEAR|FAR]]
  10250.          .
  10251.          .
  10252.          .
  10253.    RET [[constant]]
  10254.    label ENDP
  10255.  
  10256.  The CALL instruction pushes the address of the next instruction in your code
  10257.  onto the stack and passes control to a specified address. The syntax is
  10258.  
  10259.    CALL {label | register | memory}
  10260.  
  10261.  The operand contains a value calculated at run time. Since that operand can
  10262.  be a register, direct memory operand, or indirect memory operand, you can
  10263.  write call tables similar to the jump table illustrated in Section 7.1.1.2.
  10264.  
  10265.  
  10266.  Calls can be near or far. Near calls push only the offset portion of the
  10267.  calling address and therefore must be within the same segment or group. You
  10268.  can specify the type for the target operand, but if you do not, MASM uses
  10269.  the declared distance (NEAR or FAR) for operands that are labels and for the
  10270.  size of register or memory operands. Then the assembler encodes the call
  10271.  appropriately, as it does with unconditional jumps (see Sections 7.1.1,
  10272.  "Unconditional Jumps," and 7.1.2, "Conditional Jumps").
  10273.  
  10274.  MASM 6.0 optimizes a call to a far label when the label is in the current
  10275.  segment by generating the code for a near call, saving one byte.
  10276.  
  10277.  You can define procedures without PROC and ENDP, but if you do, you must
  10278.  make sure that the size of the CALL matches the size of the RET. You can
  10279.  specify the RET instruction as RETN (Return Near) or RETF (Return Far) to
  10280.  override the default size:
  10281.  
  10282.    call    NEAR PTR task ; Call is declared near
  10283.            .                     ; Return comes to here
  10284.            .
  10285.            .
  10286.    task:                         ; Procedure begins with near label
  10287.            .
  10288.            .                     ; Instructions go here
  10289.            .
  10290.            retn                  ; Return declared near
  10291.  
  10292.  The syntax for RETN and RETF is
  10293.  
  10294.    label: | label NEAR
  10295.    statements
  10296.    RETN [[constant]]
  10297.  
  10298.    label LABEL FAR
  10299.    statements
  10300.    RETF [[constant]]
  10301.  
  10302.  The RET instruction (and its RETF and RETN variations) allows an optional
  10303.  constant operand that specifies a number of bytes to be added to the value
  10304.  of the SP register after the return. This operand adjusts for arguments
  10305.  passed to the procedure before the call, as shown in the example in Section
  10306.  7.3.4, "Using Local Variables."
  10307.  
  10308.  Incorrect size for RET can cause your program to fail.
  10309.  
  10310.  When you define procedures without PROC and ENDP, you must make sure that
  10311.  calls have the same size as corresponding returns. For example, RETF pops
  10312.  two words off the stack. If a NEAR call is made to a procedure with a far
  10313.  return, not only is the popped value meaningless, but the stack status may
  10314.  cause the execution to return to a random memory location, resulting in
  10315.  program failure.
  10316.  
  10317.  There is an also an extended PROC syntax that automates many of the details
  10318.  of accessing arguments and saving registers. See Section 7.3.3, "Declaring
  10319.  Parameters with the PROC Directive."
  10320.  
  10321.  
  10322.  7.3.2  Passing Arguments on the Stack
  10323.  
  10324.  Each time you call a procedure, you may want it to operate on different
  10325.  data. This data, called "arguments," can be passed in various ways. For
  10326.  example, arguments can be passed to a procedure in registers or in
  10327.  variables. However, the
  10328.  
  10329.  most common method of passing arguments is to use the stack. Microsoft
  10330.  languages have specific conventions for passing arguments. Chapter 20,
  10331.  "Mixed-Language Programming," explains these conventions for
  10332.  assembly-language modules shared with modules from high-level languages.
  10333.  
  10334.  This section describes how a procedure accesses the arguments passed to it
  10335.  on the stack. Each argument is accessed as an offset from BP. However, if
  10336.  you use the PROC directive to declare parameters, the assembler calculates
  10337.  these offsets for you and lets you refer to parameters by name. The next
  10338.  section, "Declaring Parameters with the PROC Directive," explains how to use
  10339.  PROC this way.
  10340.  
  10341.  This example shows how to pass arguments to a procedure. The procedure
  10342.  expects to find those arguments on the stack. As this example shows,
  10343.  arguments must be accessed as offsets of BP.
  10344.  
  10345.    ; C-style procedure call and definition
  10346.  
  10347.            mov     ax, 10     ; Load and
  10348.            push    ax         ;  push constant as third argument
  10349.            push    arg2       ; Push memory as second argument
  10350.            push    cx         ; Push register as first argument
  10351.            call    addup      ; Call the procedure
  10352.            add     sp, 6      ; Destroy the pushed arguments
  10353.            .                  ;  (equivalent to three pops)
  10354.            .
  10355.            .
  10356.    addup   PROC    NEAR       ; Return address for near call
  10357.                               ;  takes two bytes
  10358.            push    bp         ; Save base pointer - takes two bytes
  10359.                               ;  so arguments start at fourth byte
  10360.            mov     bp, sp     ; Load stack into base pointer
  10361.            mov     ax, [bp+4] ; Get first argument from
  10362.                               ;  fourth byte above pointer
  10363.            add     ax, [bp+6] ; Add second argument from
  10364.                               ;  sixth byte above pointer
  10365.            add     ax, [bp+8] ; Add third argument from
  10366.                               ;  eighth byte above pointer
  10367.            mov     sp, bp
  10368.            pop     bp         ; Restore BP
  10369.            ret                ; Return result in AX
  10370.    addup   ENDP
  10371.  
  10372.  Figure 7.1 shows the stack condition at key points in the process.
  10373.  
  10374.  (This figure may be found in the printed book.)
  10375.  
  10376.  Starting with the 80186 processor, the ENTER and LEAVE instructions simplify
  10377.  the stack setup and restore instructions at the beginning and end of
  10378.  procedures.
  10379.  
  10380.  However, ENTER uses a lot of time. It is necessary only with nested,
  10381.  statically scoped procedures. Thus, a Pascal compiler may sometimes generate
  10382.  ENTER. The LEAVE instruction, on the other hand, is an efficient way to do
  10383.  the stack cleanup. LEAVE reverses the effect of the last ENTER instruction
  10384.  by restoring BP and SP to their values before the procedure call.
  10385.  
  10386.  
  10387.  7.3.3  Declaring Parameters with the PROC Directive
  10388.  
  10389.  With the PROC directive, you can specify registers to be saved, define
  10390.  parameters to the procedure, and assign symbol names to parameters (rather
  10391.  than as offsets from BP). This section describes how to use the PROC
  10392.  directive to automate the parameter-accessing techniques described in the
  10393.  last section.
  10394.  
  10395.  For example, the diagram below shows a valid PROC statement for a procedure
  10396.  called from C. It takes two parameters,  var1  and  arg1, and uses (and must
  10397.  save) the DI and SI registers:
  10398.  
  10399.  (This figure may be found in the printed book.)
  10400.  
  10401.  The syntax for PROC is
  10402.  
  10403.    label PROC [[attributes]]
  10404.    [[USES reglist]] [[, parameter[[:tag]]...
  10405.    ]]
  10406.  
  10407.  The following list describes the parts of the PROC directive.
  10408.  
  10409.  Argument                          Description
  10410.  ────────────────────────────────────────────────────────────────────────────
  10411.  label                             The name of the procedure.
  10412.  
  10413.  attributes                        Any of several attributes of the
  10414.                                    procedure, including the distance,
  10415.                                    langtype, and visibility of the
  10416.                                    procedure. The syntax for attributes is
  10417.                                    given in Section 7.3.3.1.
  10418.  
  10419.  reglist                           A list of registers following the USES
  10420.                                    keyword that the procedure uses and that
  10421.                                    should be saved on entry. Registers in
  10422.                                    the list must be separated by blanks or
  10423.                                    tabs, not by commas. The assembler
  10424.                                    generates prologue code to push these
  10425.                                    registers onto the stack. When you exit,
  10426.                                    the assembler generates epilogue code to
  10427.                                    pop the saved register values off the
  10428.                                    stack.
  10429.  
  10430.  parameter                         The list of parameters passed to the
  10431.                                    procedure on the stack. The list can
  10432.                                    have a variable number of parameters.
  10433.                                    See the discussion below for the syntax
  10434.                                    of parameter. This list can be longer
  10435.                                    than one line if the continued line ends
  10436.                                    with a comma.
  10437.  
  10438.  
  10439.  This diagram shows a valid PROC definition that uses several attributes:
  10440.  
  10441.  (This figure may be found in the printed book.)
  10442.  
  10443.  
  10444.  7.3.3.1  Attributes
  10445.  
  10446.  The syntax for the attributes field is
  10447.  
  10448.    «distance» «langtype» «visibility»
  10449.    «<prologuearg>»
  10450.  
  10451.  The list below explains each of these options.
  10452.  
  10453. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  10454.  Argument                          Description
  10455.  ────────────────────────────────────────────────────────────────────────────
  10456.  distance                          Controls the form of the RET instruction
  10457.                                    generated. Can be NEAR or FAR. If
  10458.                                    distance is not specified, it is
  10459.                                    determined from the model declared with
  10460.  Argument                          Description
  10461.  ────────────────────────────────────────────────────────────────────────────
  10462.                                   determined from the model declared with
  10463.                                    the .MODEL directive. For TINY, SMALL,
  10464.                                    COMPACT, and FLAT, NEAR is assumed. For
  10465.                                    MEDIUM, LARGE, and HUGE, FAR is assumed.
  10466.                                    For 80386/486 programming with 16- and
  10467.                                    32-bit segments, NEAR16, NEAR32, FAR16,
  10468.                                    or FAR32 can be specified.
  10469.  
  10470.  langtype                          Determines the calling convention used
  10471.                                    to access param-
  10472.                                    eters and restore the stack. The BASIC,
  10473.                                    FORTRAN, and PASCAL langtypes convert
  10474.                                    procedure names to uppercase, place the
  10475.                                    last parameter in the parameter list
  10476.                                    lowest on the stack, and generate a RET,
  10477.                                    which adjusts the stack upward by the
  10478.                                    number of bytes in the argument list.
  10479.  
  10480.                                    The C and STDCALL langtype prefixes an
  10481.  Argument                          Description
  10482.  ────────────────────────────────────────────────────────────────────────────
  10483.                                   The C and STDCALL langtype prefixes an
  10484.                                    underscore to the procedure name when
  10485.                                    the procedure's scope is PUBLIC or
  10486.                                    EXPORT and places the first parameter
  10487.                                    lowest on the stack. SYSCALL is
  10488.                                    equivalent to the C calling convention
  10489.                                    with no underscore prefixed to the
  10490.                                    procedure's name. STDCALL uses caller
  10491.                                    stack cleanup when :VARARG is specified;
  10492.                                    otherwise the called routine must clean
  10493.                                    up the stack (see Chapter 20).
  10494.  
  10495.  visibility                        Indicates whether the procedure is
  10496.                                    available to other modules. The
  10497.                                    visibility can be PRIVATE, PUBLIC, or
  10498.                                    EXPORT. A procedure name is PUBLIC
  10499.                                    unless it is explicitly declared as
  10500.                                    PRIVATE. If the visibility is EXPORT,
  10501.                                    the linker places the procedure's name
  10502.  Argument                          Description
  10503.  ────────────────────────────────────────────────────────────────────────────
  10504.                                   the linker places the procedure's name
  10505.                                    in the export table for segmented
  10506.                                    executables. EXPORT also enables PUBLIC
  10507.                                    visibility.
  10508.  
  10509.                                    You can explicitly set the default
  10510.                                    visibility with the
  10511.                                    OPTION directive. OPTION PROC:PUBLIC
  10512.                                    sets the default to public. See Section
  10513.                                    1.3.2 for more information.
  10514.  
  10515.  prologuearg                       Specifies the arguments that affect the
  10516.                                    generation of prologue and epilogue code
  10517.                                    (the code MASM generates when it
  10518.                                    encounters a PROC directive or the end
  10519.                                    of a procedure). See Section 7.3.8 for
  10520.                                    an explanation of prologue and epilogue
  10521.                                    code.
  10522.  
  10523.  Argument                          Description
  10524.  ────────────────────────────────────────────────────────────────────────────
  10525. 
  10526.  
  10527.  
  10528.  
  10529.  7.3.3.2  Parameters
  10530.  
  10531.  The parameters are separated from the reglist by a comma if there is a list
  10532.  of registers. In the syntax:
  10533.  
  10534.    parmname [[:tag»
  10535.  
  10536.  parmname is the name of the parameter. The tag can be either the
  10537.  qualifiedtype or the keyword VARARG. However, only the last parameter in a
  10538.  list of parameters can use the VARARG keyword. The qualifiedtype is
  10539.  discussed in Section 1.2.6, "Data Types." An example showing how to
  10540.  reference VARARG parameters appears later in this section. Procedures can be
  10541.  nested if they do not have parameters or USES register lists. This diagram
  10542.  shows a procedure definition with one parameter definition.
  10543.  
  10544.  (This figure may be found in the printed book.)
  10545.  
  10546.  The following example shows the procedure in Section 7.3.2, "Passing
  10547.  Arguments on the Stack," rewritten to use the extended PROC functionality.
  10548.  Prior to the procedure call, you must push the arguments onto the stack
  10549.  unless you use INVOKE (see Section 7.3.7, "Calling Procedures with INVOKE").
  10550.  
  10551.  
  10552.    addup   PROC NEAR C,
  10553.            arg1:WORD, arg2:WORD, count:WORD
  10554.            mov     ax, arg1
  10555.            add     ax, count
  10556.            add     ax, arg2
  10557.            ret
  10558.    addup   ENDP
  10559.  
  10560.  If the arguments for a procedure are pointers, the assembler does not
  10561.  generate any code to get the value or values that the pointers reference;
  10562.  your program must still explicitly treat the argument as a pointer. (See
  10563.  Chapter 3, "Using Addresses and Pointers," for more information about using
  10564.  pointers.)
  10565.  
  10566.  In the example below, even though the procedure declares the parameters as
  10567.  near pointers, you still must code two MOV instructions to get the values of
  10568.  the parameters─the first MOV gets the address of the parameters, and the
  10569.  second MOV gets the parameter.
  10570.  
  10571.    ; Call from C as a FUNCTION returning an integer
  10572.  
  10573.            .MODEL medium, c
  10574.            .CODE
  10575.    myadd   PROC   arg1:NEAR PTR WORD, arg2:NEAR PTR WORD
  10576.  
  10577.            mov     bx, arg1     ; Load first argument
  10578.            mov     ax, [bx]
  10579.            mov     bx, arg2     ; Add second argument
  10580.            add     ax, [bx]
  10581.  
  10582.            ret
  10583.  
  10584.    myadd   ENDP
  10585.            END
  10586.  
  10587.  You can use conditional-assembly directives to make sure that your pointer
  10588.  parameters are loaded correctly for the memory model. For example, the
  10589.  following version of  myadd  treats the parameters as FAR parameters if
  10590.  necessary:
  10591.  
  10592.    .MODEL  medium, c       ; Could be any model
  10593.            .CODE
  10594.    myadd   PROC    arg1:PTR WORD,   arg2:PTR WORD
  10595.  
  10596.            IF      @DataSize
  10597.            les     bx, arg1        ; Far parameters
  10598.            mov     ax, es:[bx]
  10599.            les     bx, arg2
  10600.            add     ax, es:[bx]
  10601.            ELSE
  10602.            mov     bx, arg1        ; Near parameters
  10603.            mov     ax, [bx]
  10604.            mov     bx, arg2
  10605.            add     ax, [bx]
  10606.            ENDIF
  10607.  
  10608.            ret
  10609.    myadd   ENDP
  10610.  
  10611.            END
  10612.  
  10613.  
  10614.  7.3.3.3  Using VARARG
  10615.  
  10616.  In the PROC statement, you can append the :VARARG keyword to the last
  10617.  parameter to indicate that a variable number of arguments can be passed if
  10618.  you use the C, SYSCALL, or STDCALL calling conventions (see Section 20.1). A
  10619.  label must precede :VARARG so that the arguments can be accessed as offsets
  10620.  from the variable name given. This example illustrates VARARG:
  10621.  
  10622.    addup3  PROTO NEAR C, argcount:WORD, arg1:VARARG
  10623.  
  10624.            invoke  addup3, 3, 5, 2, 4
  10625.  
  10626.    addup3  PROC    NEAR C, argcount:WORD, arg1:VARARG
  10627.            sub     ax, ax        ; Clear work register
  10628.            sub     si, si
  10629.  
  10630.            .WHILE  argcount > 0  ; Argcount has number of arguments
  10631.            add     ax, arg1[si]  ; Arg1 has the first argument
  10632.            dec     arg1          ; Point to next argument
  10633.            inc     si
  10634.            inc     si
  10635.            .ENDW
  10636.  
  10637.            ret                   ; Total is in AX
  10638.    addup3  ENDP
  10639.  
  10640.  Passing non-default-sized pointers in the VARARG portion of the parameter
  10641.  list can be done by explicitly passing the segment portion and the offset
  10642.  portion of the address separately.
  10643.  
  10644.  ────────────────────────────────────────────────────────────────────────────
  10645.  NOTE
  10646.  
  10647.  When you use the extended PROC features and the assembler encounters a RET
  10648.  instruction, it automatically generates instructions to pop saved registers,
  10649.  remove local variables from the stack, and, if necessary, remove parameters.
  10650.  It generates this code for each RET instruction it encounters. You can
  10651.  reduce code size by having only one return and jumping to it from various
  10652.  locations.
  10653.  ────────────────────────────────────────────────────────────────────────────
  10654.  
  10655.  
  10656.  7.3.4  Using Local Variables
  10657.  
  10658.  In high-level languages, local variables are visible only within a
  10659.  procedure. In Microsoft languages, these variables are usually stored on the
  10660.  stack. In assembly-language programs, you can also have local variables.
  10661.  These variables should not be confused with labels or variable names that
  10662.  are local to a module, as described in Chapter 8, "Sharing Data and
  10663.  Procedures among Modules and Libraries."
  10664.  
  10665.  This section outlines the standard methods for creating local variables. The
  10666.  next section shows how to use the LOCAL directive to make the assembler
  10667.  automatically generate local variables. When you use this directive, the
  10668.  assembler generates the same instructions as those used in this section but
  10669.  handles some of the details for you.
  10670.  
  10671.  If your procedure has relatively few variables, you can usually write the
  10672.  most efficient code by placing these values in registers. Local (stack) data
  10673.  is more efficient when you have a large amount of local data for the
  10674.  procedure.
  10675.  
  10676.  Local variables are stored on the stack.
  10677.  
  10678.  To use local variables you must save stack space for the variable at the
  10679.  start of the procedure. The variable can then be accessed by its position in
  10680.  the stack. At the end of the procedure, you need to restore the stack
  10681.  pointer, which restores the memory used by local variables.
  10682.  
  10683.  This example subtracts two bytes from the SP register to make room for a
  10684.  local word variable. This variable can then be accessed as  [bp-2].
  10685.  
  10686.    push    ax                 ; Push one argument
  10687.            call    task               ; Call
  10688.            .
  10689.            .
  10690.            .
  10691.  
  10692.    task    PROC    NEAR
  10693.            push    bp                 ; Save base pointer
  10694.            mov     bp, sp             ; Load stack into base pointer
  10695.            sub     sp, 2              ; Save two bytes for local
  10696.                                       ;  variable
  10697.            .
  10698.            .
  10699.            .
  10700.            mov     WORD PTR [bp-2], 3 ; Initialize local variable
  10701.            add     ax, [bp-2]         ; Add local variable to AX
  10702.            sub     [bp+4], ax         ; Subtract local from argument
  10703.            .                          ; Use [bp-2] and [bp+4] in
  10704.            .                          ;  other operations
  10705.            .
  10706.            mov     sp, bp             ; Clear local variables
  10707.            pop     bp                 ; Restore base
  10708.            ret     2                  ; Return result in AX and pop
  10709.    task    ENDP                       ;  two bytes to clear parameter
  10710.  
  10711.  Notice that the instruction  mov sp,bp  at the end of the procedure restores
  10712.  the original value of SP. The statement is required only if the value of SP
  10713.  is changed inside the procedure (usually by allocating local variables). The
  10714.  argument passed to the procedure is removed with the RET instruction.
  10715.  Contrast this to the example in Section 7.3.2, "Passing Arguments on the
  10716.  Stack," in which the calling code adjusts the stack for the argument.
  10717.  
  10718.  Figure 7.2 shows the state of the stack at key points in the process.
  10719.  
  10720.  (This figure may be found in the printed book.)
  10721.  
  10722.  
  10723.  7.3.5  Creating Local Variables Automatically
  10724.  
  10725.  Section 7.3.4 described how to create local variables on the stack. This
  10726.  section shows you how to automate the process with the LOCAL directive.
  10727.  
  10728.  The LOCAL directive generates code to set up the stack for local variables.
  10729.  
  10730.  
  10731.  You can use the LOCAL directive to save time and effort when working with
  10732.  local variables. When you use this directive, simply list the variables you
  10733.  want to create, giving a type for each one. The assembler calculates how
  10734.  much space is required on the stack. It also generates instructions to
  10735.  properly decrement SP (as described in the previous section) and to reset SP
  10736.  when you return from the procedure.
  10737.  
  10738.  When you create local variables this way, your source code can then refer to
  10739.  each local variable by name rather than as an offset of the stack pointer.
  10740.  Moreover, the assembler generates debugging information for each local
  10741.  variable.
  10742.  
  10743.  The procedure in the previous section can be generated more simply with the
  10744.  following code:
  10745.  
  10746.    task    PROC    NEAR    arg:WORD
  10747.            LOCAL   loc:WORD
  10748.            .
  10749.            .
  10750.            .
  10751.            mov     loc, 3    ; Initialize local variable
  10752.            add     ax, loc   ; Add local variable to AX
  10753.            sub     arg, ax   ; Subtract local from argument
  10754.            .                 ; Use "loc" and "arg" in other operations
  10755.            .
  10756.            .
  10757.            ret
  10758.    task    ENDP
  10759.  
  10760.  The LOCAL directive must be on the line immediately following the PROC
  10761.  statement. It cannot be used after the first instruction in a procedure. The
  10762.  LOCAL directive has the following syntax:
  10763.  
  10764.    LOCAL vardef [[, vardef]]...
  10765.  
  10766.  Each vardef defines a local variable. A local variable definition has this
  10767.  form:
  10768.  
  10769.    label[[ [count] ]][[:qualifiedtype]]
  10770.  
  10771.  These are the parameters in local variable definitions:
  10772.  
  10773.  Argument                          Description
  10774.  ────────────────────────────────────────────────────────────────────────────
  10775.  label                             The name given to the local variable.
  10776.                                    You can use this name to access the
  10777.                                    variable.
  10778.  
  10779.  count                             The number of elements of this name and
  10780.                                    type to allocate on the stack. You can
  10781.                                    allocate a simple array on the stack
  10782.                                    with count. The brackets around count
  10783.                                    are required. If this field is omitted,
  10784.                                    one data object is assumed.
  10785.  
  10786.  qualifiedtype                     A simple MASM type or a type defined
  10787.                                    with other types and attributes. See
  10788.                                    Section 1.2.6, "Data Types," for more
  10789.                                    information.
  10790.  
  10791.  
  10792.  If the number of local variables exceeds one line, you can place a comma at
  10793.  the end of the first line and continue the list on the next line. Another
  10794.  method is to use several consecutive LOCAL directives.
  10795.  
  10796.  You must initialize local variables.
  10797.  
  10798.  The assembler does not initialize local variables. Your program must include
  10799.  code to perform any necessary initializations. For example, the following
  10800.  code fragment sets up a local array and initializes it to zero:
  10801.  
  10802.    arraysz EQU     20
  10803.  
  10804.    aproc   PROC    USES di
  10805.            LOCAL   var1[arraysz]:WORD, var2:WORD
  10806.            .
  10807.            .
  10808.            .
  10809.    ; Initialize local array to zero
  10810.            push    ss
  10811.            pop     es              ; Set ES=SS
  10812.            lea     di, var1        ; ES:DI now points to array
  10813.            mov     cx, arraysz     ; Load count
  10814.            sub     ax, ax
  10815.            rep     stosw           ; Store zeros
  10816.    ; Use the array...
  10817.            .
  10818.            .
  10819.            .
  10820.            ret
  10821.    aproc   ENDP
  10822.  
  10823.  Even though you can reference stack variables by name, the assembler treats
  10824.  them as offsets from BP, and they are not visible outside the procedure. In
  10825.  this procedure,  array  is a local variable.
  10826.  
  10827.    index   EQU   10
  10828.    test    PROC  NEAR
  10829.    LOCAL   array[index]:WORD
  10830.            .
  10831.            .
  10832.            .
  10833.            mov     bx, index
  10834.    ;       mov     array[bx], 5           ; Not legal!
  10835.  
  10836.  The second MOV statement may appear to be legal, but since  array  is an
  10837.  offset of BP, this statement is the same as
  10838.  
  10839.    ;       mov [bp + bx + arrayoffset], 5   ; Not legal!
  10840.  
  10841.  BP and BX can be added only to SI and DI. This example would be legal,
  10842.  however, if the index value were moved to SI or DI. This type of error in
  10843.  your program can be difficult to find unless you keep in mind that local
  10844.  variables in procedures are offsets of BP.
  10845.  
  10846.  
  10847.  7.3.6  Declaring Procedure Prototypes
  10848.  
  10849.  MASM 6.0 provides a new directive, INVOKE, to handle many of the details
  10850.  important to procedure calls, such as pushing parameters according to the
  10851.  correct calling conventions. In order to use INVOKE, the procedure called
  10852.  must have previously been declared with a PROC statement, an EXTERNDEF (or
  10853.  EXTERN) statement, or a TYPEDEF. You can also place a prototype defined with
  10854.  PROTO before the INVOKE if the procedure type does not appear before the
  10855.  INVOKE. Procedure prototypes defined with PROTO inform the assembler of
  10856.  types and numbers of arguments so the assembler can check for errors and
  10857.  provide automatic conversions when INVOKE calls the procedure.
  10858.  
  10859.  
  10860.  Place prototypes after data declarations or in a separate include file.
  10861.  
  10862.  Prototypes in MASM perform the same function as prototypes in the C language
  10863.  and other high-level languages. A procedure prototype includes the procedure
  10864.  name, the types, and (optionally) the names of all parameters the procedure
  10865.  expects. Prototypes are usually placed at the beginning of an assembly
  10866.  program or in a separate include file. They are especially useful for
  10867.  procedures called from other modules and other languages, enabling the
  10868.  assembler to check for unmatched parameters. If you write routines for a
  10869.  library, you may want to put prototypes into an include file for all the
  10870.  procedures used in that library. See Chapter 8, "Sharing Data and Procedures
  10871.  among Modules and Libraries," for more information about using include
  10872.  files.
  10873.  
  10874.  Declaring procedure prototypes is optional. You can use the PROC directive
  10875.  and the CALL instruction, as shown in the previous section.
  10876.  
  10877.  In MASM 6.0, using the PROTO directive is one way to define procedure
  10878.  prototypes. The syntax for a prototype definition is the same as for a
  10879.  procedure declaration (see Section 7.3.3, "Declaring Parameters with the
  10880.  PROC Directive"), except that you do not include the list of registers,
  10881.  prologuearg list, or the scope of the procedure.
  10882.  
  10883.  Also, the PROTO keyword precedes the langtype and distance attributes. The
  10884.  attributes (like C and FAR) are optional, but if not specified, the defaults
  10885.  are based on any .MODEL or OPTION LANGUAGE statement. The names of the
  10886.  parameters are also optional, but you must list parameter types. A label
  10887.  preceding :VARARG is also optional in the prototype but not in the PROC
  10888.  statement.
  10889.  
  10890.  If a PROTO and a PROC for the same function appear in the same module, they
  10891.  must match in attribute, number of parameters, and parameter types. The
  10892.  easiest way to create prototypes with PROTO for your procedures is to write
  10893.  the procedure and then copy the first line (the line that contains the PROC
  10894.  keyword) to a location in your program that follows the data declarations.
  10895.  Change PROC to PROTO and remove the USES reglist, the prologuearg field, and
  10896.  the visibility field. It is important that the prototype follow the
  10897.  declarations for any types used in it to avoid any forward references used
  10898.  by the parameters in the prototype.
  10899.  
  10900.  The prototype defined with PROTO statement and the PROC statement for two
  10901.  procedures are given below.
  10902.  
  10903.    ;  Procedure prototypes
  10904.  
  10905.    addup     PROTO NEAR C argcount:WORD, arg2:WORD, arg3:WORD
  10906.  
  10907.    myproc    PROTO FAR C, argcount:WORD, arg2:VARARG
  10908.  
  10909.    ; Procedure declarations
  10910.  
  10911.    addup     PROC NEAR C, argcount:WORD, arg2:WORD, arg3:WORD
  10912.  
  10913.    myproc    PROC FAR C PUBLIC <callcount> USES di si,
  10914.              argcount:WORD,
  10915.              arg2:VARARG
  10916.  
  10917.  When you call a procedure with INVOKE, the assembler checks the arguments
  10918.  given by INVOKE against the parameters expected by the procedure. If the
  10919.  data types of the arguments do not match, MASM either reports an error or
  10920.  converts the type to the expected type. These conversions are explained in
  10921.  the next section.
  10922.  
  10923.  
  10924.  7.3.7  Calling Procedures with INVOKE
  10925.  
  10926.  INVOKE generates a sequence of instructions that push arguments and call a
  10927.  procedure. This helps maintain code if arguments or langtype for a procedure
  10928.  is changed. INVOKE generates procedure calls and automatically handles the
  10929.  following tasks:
  10930.  
  10931.  
  10932.    ■   Converts arguments to the expected types
  10933.  
  10934.    ■   Pushes arguments on the stack in the correct order
  10935.  
  10936.    ■   Cleans up the stack when the procedure returns
  10937.  
  10938.  
  10939.  If arguments do not match in number or if the type is not one the assembler
  10940.  can convert, an error results.
  10941.  
  10942.  If VARARG is an option in a procedure, INVOKE can pass arguments in addition
  10943.  to those in the parameter list without generating an error or warning. The
  10944.  extra arguments must be at the end of the INVOKE argument list. All other
  10945.  arguments must match in number and type.
  10946.  
  10947.  The syntax for INVOKE is
  10948.  
  10949.    INVOKE   expression  «, arguments»
  10950.  
  10951.  where expression can be the procedure's label or an indirect reference to a
  10952.  procedure, and arguments can be an expression, a register pair, or an
  10953.  expression preceded with ADDR. (The ADDR operator is discussed below.)
  10954.  
  10955.  Procedures that have these procedure prototypes
  10956.  
  10957.    addup   PROTO NEAR C argcount:WORD, arg2:WORD, arg3:WORD
  10958.  
  10959.    myproc  PROTO FAR C, argcount:WORD, arg2:VARARG
  10960.  
  10961.  and these procedure declarations
  10962.  
  10963.    addup   PROC NEAR C, argcount:WORD, arg2:WORD, arg3:WORD
  10964.  
  10965.    myproc  PROC FAR C PUBLIC <callcount> USES di si,
  10966.            argcount:WORD,
  10967.            arg2:VARARG
  10968.  
  10969.  may have INVOKE statements that look like this:
  10970.  
  10971.    INVOKE  addup,   ax, x,  y
  10972.            INVOKE  myproc,  bx, cx, 100, 10
  10973.  
  10974.  The assembler can convert some arguments and parameter type combinations so
  10975.  that the correct type can be passed. The signed or unsigned qualities of the
  10976.  arguments in the INVOKE statements determine how the assembler converts them
  10977.  to the types expected by the procedure.
  10978.  
  10979.  The  addup  procedure, for example, expects parameters of type WORD, but the
  10980.  arguments passed by INVOKE to the  addup  procedure can be any of these
  10981.  types:
  10982.  
  10983.  
  10984.    ■   BYTE, SBYTE, WORD, or SWORD
  10985.  
  10986.    ■   An expression whose type is specified with the PTR operator to be one
  10987.        of those types
  10988.  
  10989.    ■   An 8-bit or 16-bit register
  10990.  
  10991.    ■   An immediate expression in the range -32K to +64K
  10992.  
  10993.    ■   A NEAR PTR
  10994.  
  10995.  
  10996.  If the type is smaller than that expected by the procedure, MASM widens the
  10997.  argument to match.
  10998.  
  10999.  
  11000.  7.3.7.1  Widening Arguments
  11001.  
  11002.  For INVOKE to correctly handle type conversions, you must use the signed
  11003.  data types for any signed assignments. This list shows the cases in which
  11004.  MASM widens an argument to match the type expected by a procedure's
  11005.  parameters.
  11006.  
  11007.  Type Passed                       Type Expected
  11008.  ────────────────────────────────────────────────────────────────────────────
  11009.  BYTE, SBYTE                       WORD, SWORD, DWORD, SDWORD
  11010.  
  11011.  WORD, SWORD                       DWORD, SDWORD
  11012.  
  11013.  When possible, MASM widens arguments to match parameter types.
  11014.  
  11015.  The assembler generates instructions such as XOR and CBW to perform the
  11016.  conversion. You can see these generated instructions in the listing file by
  11017.  using the /Sg command-line option. The assembler can extend a segment if far
  11018.  data is expected, and it can convert the type given in the list to the types
  11019.  expected. If the assembler cannot convert the type, however, it generates an
  11020.  error.
  11021.  
  11022.  
  11023.  7.3.7.2  Detecting Errors
  11024.  
  11025.  When the assembler widens arguments, it may require the use of a register
  11026.  that could overwrite another argument.
  11027.  
  11028.  For example, if a procedure with the C calling convention is called with
  11029.  this INVOKE statement,
  11030.  
  11031.    INVOKE  myprocA, ax, cx, 100, arg
  11032.  
  11033.  where  arg  is a BYTE variable and  myproc  expects four arguments of type
  11034.  WORD, the assembler widens and then pushes the variable with this code:
  11035.  
  11036.    mov     al, DGROUP:arg
  11037.            xor     ah, ah
  11038.            push    ax
  11039.  
  11040.  As a result, the assembler generates code that also uses the AX register and
  11041.  therefore overwrites the first argument passed to the procedure in AX. The
  11042.  assembler generates an error in this case, requiring you to rewrite the
  11043.  INVOKE statement for this procedure.
  11044.  
  11045.  The INVOKE directive uses as few registers as possible. However, widening
  11046.  arguments or pushing constants on the 8088 and 8086 requires the use of the
  11047.  AX register, and sometimes the DX register or the EAX and EDX on the
  11048.  80386/486. This means that the content of AL, AH, AX, and EAX must
  11049.  frequently be overwritten, so you should avoid using these registers to pass
  11050.  arguments. As an alternative you can use DL, DH, DX, and EDX, since these
  11051.  registers are rarely used.
  11052.  
  11053.  
  11054.  7.3.7.3  Invoking Far Addresses
  11055.  
  11056.  You can pass a FAR pointer in a segment::offset pair, as shown below. Note
  11057.  the use of double colons to separate the register pair. The registers could
  11058.  be any other register pair, including a pair that a DOS call uses to return
  11059.  values.
  11060.  
  11061.    FPWORD   TYPEDEF FAR PTR WORD
  11062.    SomeProc PROTO var1:DWORD, var2:WORD, var3:WORD
  11063.  
  11064.            pfaritem    FPWORD     faritem
  11065.            .
  11066.            .
  11067.            .
  11068.            les         bx, pfaritem
  11069.            INVOKE      SomeProc, ES::BX, arg1, arg2
  11070.  
  11071.  However, you cannot give INVOKE two arguments, one for the segment and one
  11072.  for the offset, and have INVOKE combine the two for an address.
  11073.  
  11074.  
  11075.  7.3.7.4  Passing an Address
  11076.  
  11077.  You can use the ADDR operator to pass the address of an expression to a
  11078.  procedure that is expecting a NEAR or FAR pointer. This example generates
  11079.  code to pass a far pointer (to  arg1) to the procedure  proc1.
  11080.  
  11081.    PBYTE   TYPEDEF FAR PTR BYTE
  11082.    arg1    BYTE    "This is a string"
  11083.    proc1   PROTO   NEAR C fparg:PBYTE
  11084.            .
  11085.            .
  11086.            .
  11087.    INVOKE  proc1, ADDR arg1
  11088.  
  11089.  See Section 3.3.1 for information on defining pointers with TYPEDEF.
  11090.  
  11091.  
  11092.  7.3.7.5  Invoking Procedures Indirectly
  11093.  
  11094.  You can make an indirect procedure call such as  call [bx + si]  by using a
  11095.  pointer to a function prototype with TYPEDEF, as shown in this example:
  11096.  
  11097.    FUNCPROTO       TYPEDEF PROTO NEAR ARG1:WORD, ARG2:WORD
  11098.    FUNCPTR         TYPEDEF PTR FUNCPROTO
  11099.  
  11100.            .DATA
  11101.    pfunc   FUNCPTR OFFSET proc1, OFFSET proc2
  11102.  
  11103.            .CODE
  11104.            mov     si, Num            ; Num contains 0 or 2
  11105.            INVOKE  FUNCPTR PTR [si]   ; Selects proc1 or proc2
  11106.  
  11107.  You can also use ASSUME to accomplish the same task. The ASSUME statement
  11108.  associates the type  PFUNC  with the BX register.
  11109.  
  11110.    ASSUME  BX:FUNCPTR
  11111.            mov     si, Num
  11112.            INVOKE  FUNCPTR PTR [bx+si]
  11113.  
  11114.  
  11115.  7.3.7.6  Checking the Code Generated
  11116.  
  11117.  The INVOKE directive generates code that may vary depending on the processor
  11118.  mode and calling conventions in effect. You can check your listing files to
  11119.  see the code generated by the INVOKE directive if you use the /Sg
  11120.  command-line option.
  11121.  
  11122.  
  11123.  7.3.8  Generating Prologue and Epilogue Code
  11124.  
  11125.  When you use the PROC directive with its extended syntax and argument list,
  11126.  the assembler automatically generates the prologue and epilogue code in your
  11127.  procedure. "Prologue code" is generated at the start of the procedure; it
  11128.  sets up a stack pointer so you can access parameters from within the
  11129.  procedure. It also saves space on the stack for local variables, initializes
  11130.  registers such as DS, and pushes registers that the procedure uses.
  11131.  Similarly, "epilogue code" is the code at the end of the procedure that pops
  11132.  registers and returns from the procedure.
  11133.  
  11134.  The assembler automatically generates the prologue code when it encounters
  11135.  the first instruction after the PROC directive. It generates the epilogue
  11136.  code when it encounters a RET or IRET instruction. Using the
  11137.  assembler-generated prologue and epilogue code saves you time and decreases
  11138.  the number of repetitive lines of code in your procedures.
  11139.  
  11140.  The generated prologue or epilogue code depends on the
  11141.  
  11142.  
  11143.    ■   Local variables defined
  11144.  
  11145.    ■   Arguments passed to the procedure
  11146.  
  11147.    ■   Current processor selected (affects epilogue code only)
  11148.  
  11149.    ■   Current calling convention
  11150.  
  11151.    ■   Options passed in the prologuearg of the PROC directive
  11152.  
  11153.    ■   Registers being saved
  11154.  
  11155.  
  11156.  The prologuearg list contains options specifying how the prologue or
  11157.  epilogue code should be generated. The next section explains how to use
  11158.  these options, gives the standard prologue and epilogue code, and explains
  11159.  the techniques for defining your own prologue and epilogue code.
  11160.  
  11161.  
  11162.  7.3.8.1  Using Automatic Prologue and Epilogue Code
  11163.  
  11164.  The standard prologue and epilogue code handles parameters and local
  11165.  variables. If a procedure does not have any parameters or local variables,
  11166.  the prologue and epilogue code that sets up and restores a stack pointer is
  11167.  omitted, unless FORCEFRAME is included in the prologuearg list. (FORCEFRAME
  11168.  is discussed later in this section.) Prologue and epilogue code also
  11169.  generates a push and pop for each register in the register list unless the
  11170.  register list is empty.
  11171.  
  11172.  RETN and RETF suppress epilogue code generation.
  11173.  
  11174.  When a RET is used without an operand, the assembler generates the standard
  11175.  epilogue code. If you do not want the standard epilogue generated, you can
  11176.  use RETN or RETF with or without operands. RET with an integer operand does
  11177.  not generate epilogue code, but it does generate the right size of return.
  11178.  
  11179.  In the examples below showing standard prologue and epilogue code,
  11180.  localbytes  is a variable name used in this example to represent the number
  11181.  of bytes needed on the stack for the locals declared,  parmbytes  represents
  11182.  the number of bytes that the parameters take on the stack, and  registers
  11183.  represents the list of registers to be pushed or popped.
  11184.  
  11185.  The standard prologue code is the same in any processor mode:
  11186.  
  11187.    push bp
  11188.            mov bp, sp
  11189.            sub sp, localbytes  ; if localbytes is not 0
  11190.            push registers
  11191.  
  11192.  The standard epilogue code is:
  11193.  
  11194.    pop registers
  11195.            mov sp, bp    ; if localbytes is not 0
  11196.            pop bp
  11197.            ret parmbytes ; use parmbytes only if lang is not C
  11198.  
  11199.  The standard prologue and epilogue code recognizes two operands passed in
  11200.  the prologuearg list, LOADDS and FORCEFRAME. These operands modify the
  11201.  prologue code. Specifying LOADDS saves and initializes DS. Specifying
  11202.  FORCEFRAME as an argument generates a stack frame even if no arguments are
  11203.  sent to the procedure and no local variables are declared. If your procedure
  11204.  has any parameters or locals, you do not need to specify FORCEFRAME.
  11205.  
  11206.  Specifying LOADDS generates this prologue code:
  11207.  
  11208.    push bp
  11209.            mov bp, sp
  11210.            sub sp, localbytes  ; if localbytes is not 0
  11211.            push ds
  11212.            mov ax, DGROUP
  11213.            mov ds, ax
  11214.            push registers
  11215.  
  11216.  Specifying LOADDS generates the following epilogue code:
  11217.  
  11218.    pop registers
  11219.            pop ds
  11220.            mov sp, bp
  11221.            pop bp
  11222.            ret parmbytes ; use parmbytes only if lang is not C
  11223.  
  11224.  
  11225.  7.3.8.2  User-Defined Prologue and Epilogue Code
  11226.  
  11227.  If you want a different set of instructions for prologue and epilogue code
  11228.  in your procedures, you can write macros that are executed instead of the
  11229.  standard prologue and epilogue code. For example, while you are debugging
  11230.  your procedures, you may want to include a stack check or track the number
  11231.  of times a procedure is called. You can write your own prologue code to do
  11232.  these things whenever a procedure executes. Different prologue code may also
  11233.  be necessary if you are writing applications for Microsoft Windows or any
  11234.  other environment application for DOS. User-defined prologue macros will
  11235.  respond correctly if you specify FORCEFRAME in the prologuearg of a
  11236.  procedure.
  11237.  
  11238.  To write your own prologue or epilogue code, the OPTION directive must
  11239.  appear in your program. It disables automatic prologue and epilogue code
  11240.  generation. When you specify
  11241.  
  11242.    OPTION PROLOGUE : macroname
  11243.  
  11244.    OPTION EPILOGUE : macroname
  11245.  
  11246.  the assembler calls the macro specified in the OPTION directive instead of
  11247.  generating the standard prologue and epilogue code. The prologue macro must
  11248.  be a macro function, and the epilogue macro must be a macro procedure.
  11249.  
  11250.  The assembler expects your prologue or epilogue macro to have this form:
  11251.  
  11252.    macroname  MACRO procname, /
  11253.                                                    flag, /
  11254.                                         parmbytes, /
  11255.                                         localbytes, /
  11256.                                           <reglist>, /
  11257.                                           userparms
  11258.  
  11259.  The following list explains the arguments passed to your macro. Your macro
  11260.  must have formal parameters to match all the actual arguments passed.
  11261.  
  11262. ╓┌───────────┌───────────────────────────────┌───────────────────────────────╖
  11263.  Argument    Description
  11264.  ────────────────────────────────────────────────────────────────────────────
  11265.  procname    The name of the procedure.
  11266.  
  11267.  flag        A 16-bit flag containing the
  11268.              following information:
  11269.  
  11270.              Bit = Value                     Description
  11271.  
  11272.              Bit 0, 1, 2                     For calling conventions
  11273.                                              (000=unspecified language type,
  11274.                                              001=C, 010=SYSCALL, 011=
  11275.                                              STDCALL, 100=PASCAL, 101=
  11276.                                              FORTRAN, 110=BASIC)
  11277.  
  11278.              Bit 3                           Undefined (not necessarily
  11279.  Argument    Description
  11280.  ────────────────────────────────────────────────────────────────────────────
  11281.             Bit 3                           Undefined (not necessarily
  11282.                                              zero)
  11283.  
  11284.              Bit 4                           Set if the caller restores the
  11285.                                              stack (Use RET, not RETn)
  11286.  
  11287.              Bit 5                           Set if procedure is FAR
  11288.  
  11289.              Bit 6                           Set if procedure is PRIVATE
  11290.  
  11291.              Bit 7                           Set if procedure is EXPORT
  11292.  
  11293.              Bit 8                           Set if the epilogue was
  11294.                                              generated as a result of an
  11295.                                              IRET instruction and cleared
  11296.                                              if the epilogue was generated
  11297.                                              as a result of a RET
  11298.                                              instruction
  11299.  
  11300.  Argument    Description
  11301.  ────────────────────────────────────────────────────────────────────────────
  11302. 
  11303.              Bits 9-15                       Undefined (not necessarily
  11304.                                              zero)
  11305.  
  11306.  parmbytes   The byte count of all the
  11307.              parameters given in the PROC
  11308.              statement.
  11309.  
  11310.  localbytes  The count in bytes of all
  11311.              locals defined with the LOCAL
  11312.              directive.
  11313.  
  11314.  reglist     A list of the registers
  11315.              following the USES operator in
  11316.              the procedure declaration.
  11317.              This list is enclosed by angle
  11318.              brackets (< >), and each item
  11319.              is separated by commas. This
  11320.              list is reversed for epilogues.
  11321.  Argument    Description
  11322.  ────────────────────────────────────────────────────────────────────────────
  11323.             list is reversed for epilogues.
  11324.  
  11325.  userparms   Any argument you want to pass
  11326.              to the macro. The
  11327.              prologuearg (if there is one)
  11328.              specified in the PROC
  11329.              directive is passed to this
  11330.              argument.
  11331.  
  11332.  
  11333.  
  11334.  Your macro function must return the parmbytes parameter. However, if the
  11335.  prologue places other values on the stack after pushing BP and these values
  11336.  are not referenced by any of the local variables, the exit value must be the
  11337.  number of bytes for procedure locals plus any space between BP and the
  11338.  locals. Therefore parmbytes is not always equal to the bytes occupied by the
  11339.  locals.
  11340.  
  11341.  The following macro is an example of a user-defined prologue that counts the
  11342.  number of times a procedure is called.
  11343.  
  11344.    ProfilePro      MACRO procname,       \
  11345.                          flag,           \
  11346.                          bytecount,      \
  11347.                          numlocals,      \
  11348.                          regs,           \
  11349.                          macroargs
  11350.  
  11351.                    .DATA
  11352.    procname&count  WORD 0
  11353.                    .CODE
  11354.            inc     procname&count  ; Accumulates count of times the
  11355.                                    ;  procedure is called
  11356.            push    bp
  11357.            mov     bp, sp
  11358.                                    ; Other BP operations
  11359.            IFNB <regs>
  11360.               FOR r, regs
  11361.                  push r
  11362.               ENDM
  11363.            ENDIF
  11364.            EXITM %bytecount
  11365.    ENDM
  11366.  
  11367.  Your program must also include this statement before any procedures are
  11368.  called that use the prologue:
  11369.  
  11370.    OPTION PROLOGUE:ProfilePro
  11371.  
  11372.  If you define only a prologue or an epilogue macro, the standard prologue or
  11373.  epilogue code is used for the one you do not define. The form of the code
  11374.  generated depends on the .MODEL and PROC options used.
  11375.  
  11376.  If you want to revert to the standard prologue or epilogue code, use
  11377.  PROLOGUEDEF  or  EPILOGUEDEF  as the macroname in the OPTION statement.
  11378.  
  11379.    OPTION EPILOGUE:EPILOGUEDEF
  11380.  
  11381.  You can completely suppress prologue or epilogue generation with
  11382.  
  11383.    OPTION PROLOGUE:None
  11384.    OPTION EPILOGUE:None
  11385.  
  11386.  In this case, no user-defined macro is called, and the assembler does not
  11387.  generate a default code sequence. This state remains in effect until the
  11388.  next OPTION PROLOGUE or OPTION EPILOGUE is encountered.
  11389.  
  11390.  See Chapter 9 for additional information about writing macros. The
  11391.  PROLOGUE.INC file provided in the MASM 6.0 distribution disks can be used to
  11392.  create the prologue and epilogue sequences for the Microsoft C Professional
  11393.  Development System, version 6.0.
  11394.  
  11395.  
  11396.  7.4  DOS Interrupts
  11397.  
  11398.  In addition to jumps, loops, and procedures that alter program execution,
  11399.  interrupt routines transfer execution to a different location. In this case,
  11400.  control goes to an interrupt routine.
  11401.  
  11402.  You can write your own interrupt routines, either to replace an existing
  11403.  routine or to use an undefined interrupt number. You may want to replace the
  11404.  processor's divide-overflow (0h) interrupts or DOS interrupts, such as the
  11405.  critical-error (24h) and CONTROL+C (23h) handlers. The BOUND instruction
  11406.  checks array bounds and calls interrupt 5 when an error occurs. If you use
  11407.  this instruction, you need to write an interrupt handler for it.
  11408.  
  11409.  This section summarizes the following:
  11410.  
  11411.  
  11412.    ■   How to call interrupts
  11413.  
  11414.    ■   How the processor handles interrupts
  11415.  
  11416.    ■   How to redefine an existing interrupt routine
  11417.  
  11418.  
  11419.  The example routine in this section handles addition or multiplication
  11420.  overflow and illustrates the steps necessary for writing an interrupt
  11421.  routine. See Chapter 19, "Writing Memory-Resident Software" for additional
  11422.  information about DOS and BIOS interrupts.
  11423.  
  11424.  ────────────────────────────────────────────────────────────────────────────
  11425.  NOTE
  11426.  Under OS/2, system access is made through calls to the Applications Program
  11427.  Interface (API), not through interrupts. Microsoft Windows applications use
  11428.  both interrupts and API calls.
  11429.  ────────────────────────────────────────────────────────────────────────────
  11430.  
  11431.  
  11432.  7.4.1  Calling DOS and ROM-BIOS Interrupts
  11433.  
  11434.  Interrupts are the only way to access DOS from assembly language. They are
  11435.  called with the INT instruction, which takes one operand─an immediate value
  11436.  between 0 and 255.
  11437.  
  11438.  When calling DOS and ROM-BIOS interrupts, you usually need to place a
  11439.  function number in the AH register. You can use other registers to pass
  11440.  arguments to functions. Some interrupts and functions return values in
  11441.  certain registers, although register use varies for each interrupt. This
  11442.  code writes the text of  msg  to the screen.
  11443.  
  11444.    .DATA
  11445.    msg     BYTE    "This writes to the screen",$
  11446.            .CODE
  11447.            mov     dx, offset msg
  11448.            mov     ah, 09h
  11449.            int     21h
  11450.  
  11451.  When the INT instruction executes, the processor takes the following six
  11452.  steps:
  11453.  
  11454.  
  11455.    1.  Looks up the address of the interrupt routine in the interrupt
  11456.        descriptor table (also called the "interrupt vector"). This table
  11457.        starts at the lowest point in memory (segment 0, offset 0) and
  11458.        consists of four bytes (two segment and two offset) for each
  11459.        interrupt. Thus, the address of an interrupt routine equals the number
  11460.        of the interrupt multiplied by 4.
  11461.  
  11462.    2.  Clears the trap flag (TF) and interrupt enable flag (IF).
  11463.  
  11464.    3.  Pushes the flags register, the current code segment (CS), and the
  11465.        current instruction pointer (IP).
  11466.  
  11467.    4.  Jumps to the address of the interrupt routine, as specified in the
  11468.        interrupt descriptor table.
  11469.  
  11470.    5.  Executes the code of the interrupt routine until it encounters an IRET
  11471.        instruction.
  11472.  
  11473.    6.  Pops the instruction pointer, code segment, and flags.
  11474.  
  11475.  
  11476.  Figure 7.3 illustrates how interrupts work.
  11477.  
  11478.  (This figure may be found in the printed book.)
  11479.  
  11480.  Some DOS interrupts should not normally be called. Some (such as 20h and
  11481.  27h) have been replaced by other DOS interrupts. Others are used internally
  11482.  by DOS.
  11483.  
  11484.  
  11485.  7.4.2  Replacing or Redefining Interrupt Routines
  11486.  
  11487.  One interrupt routine you may want to redefine is the routine called by
  11488.  INTO. The INTO (Interrupt on Overflow) instruction is a variation of the INT
  11489.  instruction. It calls interrupt 04h when the overflow flag is set. By
  11490.  default, the routine for interrupt 4 simply consists of an IRET, so it
  11491.  returns without doing anything. Using INTO is an alternative to using JO
  11492.  (Jump on Overflow) to jump to an overflow routine.
  11493.  
  11494.  To replace or redefine an existing interrupt, your routine must
  11495.  
  11496.  
  11497.    ■   Replace the address in the interrupt descriptor table with the address
  11498.        of your new routine and save the old address
  11499.  
  11500.    ■   Provide new instructions to handle the interrupt
  11501.  
  11502.    ■   Restore the old address when your routine ends
  11503.  
  11504.  
  11505.  An interrupt routine can be written like a procedure by using the PROC and
  11506.  ENDP directives. The routine should always be defined as FAR and should end
  11507.  with an IRET instruction instead of a RET instruction.
  11508.  
  11509.  ────────────────────────────────────────────────────────────────────────────
  11510.  NOTE
  11511.  
  11512.  Since the assembler doesn't know whether you are going to terminate with
  11513.  RET or  IRET, you can use the full extended PROC syntax (described in
  11514.  Section 7.3.3, "Declaring Parameters with the PROC Directive") to write
  11515.  interrupt procedures. However, you should not make interrupt procedures NEAR
  11516.  or specify arguments for them. You can use the USES keyword, however, to
  11517.  correctly generate code to save and to restore a register list in interrupt
  11518.  procedures.
  11519.  ────────────────────────────────────────────────────────────────────────────
  11520.  
  11521.  The STI (Set Interrupt Flag) and CLI (Clear Interrupt Flag) instructions
  11522.  turn interrupts on or off. You can use CLI to turn off interrupt processing
  11523.  so that an important routine cannot be stopped by a hardware interrupt.
  11524.  After the routine has finished, use STI to turn interrupt processing back
  11525.  on. Interrupts received while interrupt processing was turned off by CLI are
  11526.  saved and executed when STI turns interrupts back on.
  11527.  
  11528.  MASM 6.0 provides two new forms of the IRET instruction that suppress
  11529.  epilogue sequences. This allows an interrupt to have local variables or use
  11530.  a userdefined prologue. IRETF pops a FAR16 return address, and IRETFD pops a
  11531.  FAR32 return address.
  11532.  
  11533.  The following example uses DOS functions to save the address of the initial
  11534.  interrupt routine in a variable and to put the address of the new interrupt
  11535.  routine in the interrupt descriptor table. Once the new address has been
  11536.  set, the new routine is called any time the interrupt is called. This new
  11537.  routine prints a message and sets AX and DX to 0.
  11538.  
  11539.  To replace the address in the interrupt descriptor table with the address of
  11540.  your procedure, AL needs to be loaded with 04h and AH loaded with 35, the
  11541.  Get Interrupt Vector function. The Set Interrupt Vector function requires 25
  11542.  in AH.
  11543.  
  11544.  Follow this example to replace an existing interrupt routine. To write an
  11545.  interrupt handler for an unused interrupt, see online help for available
  11546.  vectors.
  11547.  
  11548.    .MODEL LARGE, C, DOS
  11549.    FPFUNC  TYPEDEF FAR PTR
  11550.            .DATA
  11551.    msg     BYTE    "Overflow - result set to 0",13,10,"$"
  11552.    vector  FPFUNC  ?
  11553.            .CODE
  11554.            .STARTUP
  11555.  
  11556.            mov     ax, 3504h       ; Load interrupt 4 and call DOS
  11557.            int     21h             ;  Get Interrupt Vector function
  11558.            mov     WORD PTR vector[2],es ; Save segment
  11559.            mov     WORD PTR vector[0],bx ;  and offset
  11560.  
  11561.            push    ds              ; Save DS
  11562.            mov     ax, cs          ; Load segment of new routine
  11563.            mov     ds, ax
  11564.            mov     dx, OFFSET ovrflow   ; Load offset of new routine
  11565.            mov     ax, 2504h       ; Load interrupt 4 and call DOS
  11566.            int     21h             ;  Set Interrupt Vector function
  11567.            pop     ds              ; Restore
  11568.            .
  11569.            .
  11570.            .
  11571.            add     ax, bx          ; Do addition (or multiplication)
  11572.            into                    ; Call interrupt 4 if overflow
  11573.            .
  11574.            .
  11575.            .
  11576.            lds     dx, vector      ; Load original interrupt address
  11577.            mov     ax, 2504h       ; Restore interrupt number 4
  11578.            int     21h             ;  with DOS set vector function
  11579.            mov     ax, 4C00h       ; Terminate function
  11580.            int     21h
  11581.  
  11582.    ovrflow         PROC    FAR
  11583.                    sti             ; Enable interrupts
  11584.                                    ;  (turned off by INT)
  11585.                    mov     ah, 09h ; Display string function
  11586.                    mov     dx, OFFSET msg     ; Load address
  11587.                    int     21h     ; Call DOS
  11588.                    sub     ax, ax  ; Set AX to 0
  11589.                    sub     dx, dx  ; Set DX to 0
  11590.                    iret            ; Return
  11591.    ovrflow         ENDP
  11592.                    END
  11593.  
  11594.  Before your program ends, you should restore the original address by loading
  11595.  DX with the original interrupt address and using the DOS set vector function
  11596.  to store the original address at the correct location.
  11597.  
  11598.  
  11599.  7.5  Related Topics in Online Help
  11600.  
  11601.  Other information available online which relates to topics in this chapter
  11602.  is given in the list below:
  11603.  
  11604.  Topic                             Access
  11605.  ────────────────────────────────────────────────────────────────────────────
  11606.  OPTION directive                  From the "MASM 6.0 Contents" screen,
  11607.                                    choose "Directives," then choose
  11608.                                    "Miscellaneous"
  11609.  
  11610.  DOS and ROM-BIOS interrupts       From the list of System Resources on the
  11611.                                    "MASM 6.0 Contents" screen, choose "DOS
  11612.                                    Calls" or "BIOS Calls"
  11613.  
  11614.  BT, BTC, BTR, BTS                 From the "MASM 6.0 Contents" screen,
  11615.                                    choose "Processor Instructions" and then
  11616.                                    "Logical and Shifts"
  11617.  
  11618.  Other forms of the LOOP           From the "MASM 6.0 Contents" screen,
  11619.  instruction                       choose "Processor Instructions" and then
  11620.                                    "Control Flow"
  11621.  
  11622.  Processor Flag Summary            From the "MASM 6.0 Contents" screen,
  11623.                                    choose "Processor Instructions"
  11624.  
  11625.  
  11626.  
  11627.  
  11628.  
  11629.  
  11630.  
  11631.  Chapter 8  Sharing Data and Procedures among Modules and Libraries
  11632.  ────────────────────────────────────────────────────────────────────────────
  11633.  
  11634.  To use symbols and procedures in more than one module, the assembler must be
  11635.  able to recognize the shared data as global to all the modules where they
  11636.  are used. MASM 6.0 provides new techniques to simplify data-sharing and give
  11637.  a high-level interface to multiple-module programming. With these
  11638.  techniques, you can place shared symbols in include files. This makes the
  11639.  data declarations in the file available to all modules that use the include
  11640.  file.
  11641.  
  11642.  After an overview of the data-sharing methods, the next section of this
  11643.  chapter focuses on organizing modules and using the include file to simplify
  11644.  data-sharing. The first method allows you to create a single include file
  11645.  that works in the modules where the symbol is used as well as where it is
  11646.  defined.
  11647.  
  11648.  Sharing procedures and data items using the PUBLIC and EXTERN directives in
  11649.  the appropriate modules is the other method of data-sharing. The third
  11650.  section of this chapter explains how to use PUBLIC and EXTERN.
  11651.  
  11652.  You may also want to place commonly used routines in libraries. Section 8.4
  11653.  explains how to create program libraries and access their routines.
  11654.  
  11655.  
  11656.  8.1  Selecting Data-Sharing Methods
  11657.  
  11658.  If data defined in one module is to be used in the other modules of a
  11659.  multiple-module program, the data must be made public and external. MASM
  11660.  provides several methods for doing this.
  11661.  
  11662.  One method is to declare a symbol public (with the PUBLIC directive) in the
  11663.  module where it is defined. This makes the symbol available to other
  11664.  modules. Then place an EXTERN statement for that symbol in the rest of the
  11665.  modules that use the public symbol. This statement informs the assembler
  11666.  that the symbol is external─defined in another module.
  11667.  
  11668.  As an alternative, you can use the COMM directive instead of PUBLIC and
  11669.  EXTERN. However, communal variables have some limitations. You cannot depend
  11670.  on their location in memory because they are allocated by the linker, and
  11671.  they cannot be initialized.
  11672.  
  11673.  These two data-sharing methods are still available, but MASM 6.0 introduces
  11674.  a new directive, EXTERNDEF, that declares a symbol either public or
  11675.  external, as appropriate. EXTERNDEF simplifies the declarations for global
  11676.  (public and external) variables and encourages the use of include files.
  11677.  
  11678.  The next section provides further details on using include files. Section
  11679.  8.3, "Using Alternatives to Include Files," provides more information on
  11680.  PUBLIC and EXTERN.
  11681.  
  11682.  
  11683.  8.2  Sharing Symbols with Include Files
  11684.  
  11685.  Place statements common to all modules in include files.
  11686.  
  11687.  Include files can contain any valid MASM statement but typically consist of
  11688.  type and symbol declarations. The assembler inserts the contents of the
  11689.  include file into a module at the location of the INCLUDE directive. Include
  11690.  files can simplify project organization by eliminating the need to
  11691.  physically insert common declarations into more than one program or module.
  11692.  Include files are always optional. See Section 8.3 for alternatives to using
  11693.  include files.
  11694.  
  11695.  The first part of this section explains how to organize symbol definitions
  11696.  and the declarations that make the symbols global (available to all
  11697.  modules). It then shows how to make both variables and procedures public
  11698.  with EXTERNDEF, PROTO, and COMM. The last part of this section tells where
  11699.  to place these directives in the modules and include files.
  11700.  
  11701.  
  11702.  8.2.1  Organizing Modules
  11703.  
  11704.  This section summarizes the organization of declarations and definitions in
  11705.  modules and include files and the use of the INCLUDE directive.
  11706.  
  11707.  Include Files - Type declarations that need to be identical in every module
  11708.  should be placed in an include file. Doing so ensures consistency and can
  11709.  save programming time when updating programs. Include files should contain
  11710.  only symbol declarations and any other declarations that are resolved at
  11711.  assembly time. (See Section 1.3.1, "Generating and Running Executable
  11712.  Programs," for a list of assembly-time operations.) If the include file is
  11713.  associated with more than one module, it cannot contain statements that
  11714.  define and allocate memory for symbols unless you include the data
  11715.  conditionally (see Section 1.3.3).
  11716.  
  11717.  Modules - Label definitions that cause the assembler to allocate memory
  11718.  space must be defined in a module, not in an include file. If any of these
  11719.  definitions is located in the include file, it is copied into each file that
  11720.  uses the include file, creating an error.
  11721.  
  11722.  Include files are inserted at the location of the INCLUDE directive.
  11723.  
  11724.  Once you have placed public symbols in an include file, you need to
  11725.  associate that file with the main module. The INCLUDE statement is usually
  11726.  placed before data and code segments in your modules. When the assembler
  11727.  encounters an INCLUDE directive, it opens the specified file and assembles
  11728.  all its statements. The assembler then returns to the original file and
  11729.  continues the assembly process.
  11730.  
  11731.  The INCLUDE directive takes the form
  11732.  
  11733.    INCLUDE filename
  11734.  
  11735.  where filename is the full name or fully specified path of the include file.
  11736.  For example, the following declaration inserts the contents of the include
  11737.  file SCREEN.INC in your program:
  11738.  
  11739.    INCLUDE SCREEN.INC
  11740.  
  11741.  You must make sure that the assembler can find include files.
  11742.  
  11743.  The file name in the INCLUDE directive must be fully specified; no
  11744.  extensions are assumed. If a full path name is not given, the assembler
  11745.  searches first in the directory of the source file containing the INCLUDE
  11746.  directive.
  11747.  
  11748.  If the include file is not in the source file directory, the assembler
  11749.  searches the paths specified in the assembler's command-line option /I, or
  11750.  in PWB's Include Paths field in the MASM Option dialog box (accessed from
  11751.  the Option menu). The /I option takes this form:
  11752.  
  11753.    /I path
  11754.  
  11755.  Multiple /I options can be used to specify that multiple directives be
  11756.  searched in the order they appear on the command line. If none of these
  11757.  directories contains the desired include file, the assembler finally
  11758.  searches in the paths specified in the INCLUDE environment variable. If the
  11759.  include file still cannot be found, an assembly error occurs. The related /x
  11760.  option tells the assembler to ignore the INCLUDE environment variable for
  11761.  all subsequent assemblies.
  11762.  
  11763.  An include file may specify another include file. The assembler processes
  11764.  the second include file before returning to the first. Include files can be
  11765.  nested this way as deeply as desired; the only limit is the amount of free
  11766.  memory.
  11767.  
  11768.  Put constants used in more than one module into the include file.
  11769.  
  11770.  Include Files or Modules - You can use the EQU directive to create named
  11771.  constants that cannot be redefined in your program (see Section 1.2.4,
  11772.  "Integer Constants and Constant Expressions," for information about the EQU
  11773.  directive). Placing a constant defined with EQU in an include file makes it
  11774.  available to all modules that use that include file.
  11775.  
  11776.  Placing TYPEDEF, STRUCT, UNION, and RECORD definitions in an include file
  11777.  guarantees consistency in type definitions. If required, the variable
  11778.  instances derived from these definitions can be made public among the
  11779.  modules with EXTERNDEF declarations (see the next section). Macros
  11780.  (including macros defined with TEXTEQU) must be placed in include files to
  11781.  make them visible in other modules.
  11782.  
  11783.  If you elect to use full segment definitions (along with, or instead of,
  11784.  simplified definitions), you can force a consistent segment order in all
  11785.  files by defining segments in an include file. This technique is explained
  11786.  in Section 2.3.2, "Controlling the Segment Order."
  11787.  
  11788.  
  11789.  8.2.2  Declaring Symbols Public and External
  11790.  
  11791.  It is sometimes useful to make procedures and variables (such as large
  11792.  arrays or status flags) global to all program modules. Global variables are
  11793.  freely accessible within all routines; you do not have to explicitly pass
  11794.  them to the routines that need them.
  11795.  
  11796.  Variables can be made global to multiple modules in several ways. This
  11797.  section describes three ways to make them global by using the EXTERNDEF,
  11798.  PROTO, or COMM declarations within include files. Section 8.3.1 explains how
  11799.  to use the PUBLIC and EXTERN directives within modules.
  11800.  
  11801.  External identifiers must be unique.
  11802.  
  11803.  These methods make symbols global to the modules in which they are used.
  11804.  Therefore, symbols must be unique. The linker enforces this requirement.
  11805.  
  11806.  
  11807.  8.2.2.1  Using EXTERNDEF
  11808.  
  11809.  EXTERNDEF can appear in the defining or calling modules.
  11810.  
  11811.  MASM treats EXTERNDEF as a public declaration in the defining module and as
  11812.  an external declaration in accessing module(s). You can use the EXTERNDEF
  11813.  statement in your include file to make a variable common among two or more
  11814.  modules. EXTERNDEF works with all types of variables, including arrays,
  11815.  structures, unions, and records. It also works with procedures.
  11816.  
  11817.  As a result, a single include file can contain an EXTERNDEF declaration that
  11818.  works in both the defining module and any accessing module. It is ignored in
  11819.  modules that neither define nor access the variable. Therefore, an include
  11820.  file for a library which is used in multiple .EXE files does not force the
  11821.  definition of a symbol as EXTERN does.
  11822.  
  11823.  The EXTERNDEF statement takes this form:
  11824.  
  11825.    EXTERNDEF [[langtype]] name:qualifiedtype
  11826.  
  11827.  The name is the variable's identifier. The qualifiedtype is explained in
  11828.  detail in Section 1.2.6, "Data Types."
  11829.  
  11830.  The optional langtype specifier sets the naming conventions for the name it
  11831.  precedes. It overrides any language specified in the .MODEL directive. The
  11832.  specifier can be C, SYSCALL, STDCALL, PASCAL, FORTRAN, or BASIC. See Section
  11833.  20.1, "Naming and Calling Conventions," for information on selecting the
  11834.  appropriate langtype type.
  11835.  
  11836.  The diagram below shows the statements that declare an array, make it
  11837.  public, and use it in another module.
  11838.  
  11839.  (This figure may be found in the printed book.)
  11840.  
  11841.  The file position of EXTERNDEF directives is important. See Section 8.2.3,
  11842.  "Positioning External Declarations," for more information.
  11843.  
  11844.  The assembler does not check parameters when you call EXTERNDEF procedures.
  11845.  
  11846.  
  11847.  You can also make procedures visible by using EXTERNDEF without PROTO inside
  11848.  an include file. This method treats the procedure name as a simple
  11849.  identifier, without the parameter list, so you forgo the assembler's ability
  11850.  to check for the correct parameters during assembly.
  11851.  
  11852.  The method for using EXTERNDEF for procedures is the same as using it with
  11853.  variables. You can also use EXTERNDEF to make code labels global.
  11854.  
  11855.  
  11856.  8.2.2.2  Using PROTO
  11857.  
  11858.  When a procedure is defined in one module and called from another module, it
  11859.  must be declared public in the defining module and external in the calling
  11860.  modules; otherwise, assembly or linking errors occur.
  11861.  
  11862.  You have three methods for declaring a procedure public. Using PUBLIC and
  11863.  EXTERN is the only method prior to MASM 6.0. Section 8.3.1 explains the use
  11864.  of PUBLIC and EXTERN. The previous section (8.2.2.1) explains the use of
  11865.  EXTERNDEF. This section illustrates the use of PROTO.
  11866.  
  11867.  A PROTO (prototype) declaration in the include file establishes a
  11868.  procedure's interface in both the defining and calling modules. The PROTO
  11869.  directive automatically generates an EXTERNDEF for the procedure unless the
  11870.  procedure has been declared PRIVATE in the PROC statement. Defining a
  11871.  prototype enables type-checking for the procedure arguments.
  11872.  
  11873.  PROTO and INVOKE simplify procedure calls.
  11874.  
  11875.  Follow these steps to create an interface for a procedure defined in one
  11876.  module and called from other modules:
  11877.  
  11878.  
  11879.    1.  Place the PROTO declaration in the include file.
  11880.  
  11881.    2.  Define the procedure with PROC. The PROC directive declares the
  11882.        procedure PUBLIC by default.
  11883.  
  11884.    3.  Call the procedure with the INVOKE statement (or with CALL).
  11885.  
  11886.  
  11887.  The following example is a PROTO declaration for the far procedure
  11888.  CopyFile, which uses the C parameter-passing and naming conventions, and
  11889.  takes the arguments  filename  and  numberlines. The diagram following the
  11890.  example shows the file placement for these statements. This definition goes
  11891.  into the include file:
  11892.  
  11893.    CopyFile PROTO FAR C filename:BYTE, numberlines:WORD
  11894.  
  11895.  The procedure definition for  CopyFile  is
  11896.  
  11897.    CopyFile PROC FAR C USES cx, filename:BYTE, numberlines:WORD
  11898.  
  11899.  To call the  CopyFile  procedure, you can use this INVOKE statement:
  11900.  
  11901.    INVOKE   CopyFile, NameVar, 200
  11902.  
  11903.  (This figure may be found in the printed book.)
  11904.  
  11905.  See Chapter 7, "Controlling Program Flow," for descriptions, syntax, and
  11906.  examples of PROTO, PROC, and INVOKE.
  11907.  
  11908.  
  11909.  8.2.2.3  Using COMM
  11910.  
  11911.  Another way to share variables among modules is to add the COMM (communal)
  11912.  declaration to your include file. Since communal variables are allocated by
  11913.  the linker and cannot be initialized, you cannot depend on their location or
  11914.  sequence.
  11915.  
  11916.  Communal variables are supported by MASM primarily for compatibility with
  11917.  communal variables in Microsoft C. Communal variables are not used in any
  11918.  other Microsoft language, and they are not compatible with C++ and some
  11919.  other languages.
  11920.  
  11921.  Communal variables can reduce the size of executable files.
  11922.  
  11923.  COMM declares a variable external but cannot be used with code. COMM also
  11924.  instructs the linker to define the variable if it has not been explicitly
  11925.  defined in a module. The memory space for communal variables may not be
  11926.  assigned until load time, so using communal variables may reduce the size of
  11927.  your executable file.
  11928.  
  11929.  The COMM declaration has the syntax
  11930.  
  11931.    COMM [[langtype]] [[NEAR
  11932.    | FAR]] label:type«:count»
  11933.  
  11934.  The label is the name of the variable. The langtype sets the naming
  11935.  conventions for the name it precedes. It overrides any language specified in
  11936.  the .MODEL directive.
  11937.  
  11938.  If NEAR or FAR is not specified, the variable determines the default from
  11939.  the current memory model (NEAR for TINY, SMALL, COMPACT, and FLAT; FAR for
  11940.  MEDIUM, LARGE, and HUGE).
  11941.  
  11942.  The type can be a constant expression, but it is usually a type such as
  11943.  BYTE, WORD, or DWORD, or a structure, union, or record. If you first declare
  11944.  the type with TYPEDEF, CodeView can provide type information. The count is
  11945.  the number of elements. If no count is given, one element is assumed.
  11946.  
  11947.  The following example creates the common far variable  DataBlock, which is a
  11948.  1,024-element array of uninitialized signed doublewords:
  11949.  
  11950.    COMM FAR DataBlock:SDWORD:1024
  11951.  
  11952.  ────────────────────────────────────────────────────────────────────────────
  11953.  NOTE
  11954.  
  11955.  C variables declared outside functions (except static variables) are
  11956.  communal unless explicitly initialized; they are the same as
  11957.  assembly-language communal variables. If you are writing assembly-language
  11958.  modules for C, you can declare the same communal variables in both C and
  11959.  MASM include files. However, communal variables in C do not have to be
  11960.  declared communal in assembler. The linker will match the EXTERN, PUBLIC,
  11961.  and COMM statements for the variable.
  11962.  ────────────────────────────────────────────────────────────────────────────
  11963.  
  11964.  EXTERNDEF is a flexible alternative to using COMM.
  11965.  
  11966.  EXTERNDEF (explained in the previous section) is more flexible than COMM
  11967.  because you can initialize variables defined with it, and you can use those
  11968.  variables in code that depends on the position and sequence of the data.
  11969.  
  11970.  
  11971.  8.2.3  Positioning External Declarations
  11972.  
  11973.  Although LINK determines the actual address of an external symbol, the
  11974.  assembler assumes a default segment for the symbol, based on the location of
  11975.  the external directive in the source code. You should therefore position
  11976.  EXTERN and EXTERNDEF directives according to these rules:
  11977.  
  11978.  
  11979.    ■   If you know which segment defines an external symbol, put the EXTERN
  11980.        statement in that segment.
  11981.  
  11982.    ■   If you know the group but not the segment, position the EXTERN
  11983.        statement outside any segment and reference the variable with the
  11984.        group name. For example, if  var1  is in DGROUP, you would reference
  11985.        the variable as  mov DGROUP:var1, 10.
  11986.  
  11987.    ■   If you know nothing about the location of an external variable, put
  11988.        the EXTERN statement outside any segment. You can use the SEG
  11989.        directive to access the external variable like this:
  11990.  
  11991.        mov ax, SEG var1
  11992.              mov es, ax
  11993.              mov ax, es:var1
  11994.  
  11995.  
  11996.    ■   If the symbol is an absolute symbol or a far code label, you can
  11997.        declare it external anywhere in the source code.
  11998.  
  11999.  
  12000.  Always close opened segments.
  12001.  
  12002.  Any segments opened in include files should always be closed so that
  12003.  external declarations following an include statement are not incorrectly
  12004.  placed inside a segment. Any include statements in your program should
  12005.  immediately follow the .MODEL, OPTION, and processor directives.
  12006.  
  12007.  For the same reason, if you want to be certain that an external definition
  12008.  is outside a segment, you can use @CurSeg. The @CurSeg predefined symbol
  12009.  returns a blank if the definition is not in a segment. For example,
  12010.  
  12011.    .DATA
  12012.            .
  12013.            .
  12014.            .
  12015.    @CurSeg ENDS                    ; Close segment
  12016.            EXTERNDEF var:WORD
  12017.  
  12018.  See Section 1.2.3, "Predefined Symbols," for information about predefined
  12019.  symbols such as @CurSeg.
  12020.  
  12021.  
  12022.  8.3  Using Alternatives to Include Files
  12023.  
  12024.  If your project uses only two modules (or if it is written with a version of
  12025.  MASM prior to 6.0), you may want to continue using PUBLIC in the defining
  12026.  module and EXTERN in the accessing module, and not create an include file
  12027.  for the project. The EXTERN directive can be used in an include file, but
  12028.  the include file containing EXTERN cannot be added to the module that
  12029.  contains the corresponding PUBLIC directive for that symbol. This section
  12030.  assumes that you are not using include files.
  12031.  
  12032.  
  12033.  8.3.1  PUBLIC and EXTERN
  12034.  
  12035.  The PUBLIC and EXTERN directives are less flexible than EXTERNDEF and PROTO
  12036.  because they are module-specific: PUBLIC must appear in the defining module
  12037.  and EXTERN must appear in the calling modules. This section shows how to use
  12038.  PUBLIC and EXTERN. Information on where to place the external declarations
  12039.  in your file is in Section 8.2.3, "Positioning External Declarations."
  12040.  
  12041.  The PUBLIC directive makes a name visible outside the module in which it is
  12042.  defined. This gives other program modules access to that identifier.
  12043.  
  12044.  The EXTERN directive performs the complementary function. It tells the
  12045.  assembler that a name referenced within a particular module is actually
  12046.  defined and declared public in another module that will be specified at link
  12047.  time.
  12048.  
  12049.  A PUBLIC directive can appear anywhere in a file. Its syntax is
  12050.  
  12051.    PUBLIC [[langtype]] name[[,
  12052.    [[langtype]] name]] ...
  12053.  
  12054.  The name must be the name of an identifier defined within the current source
  12055.  file. Only code labels, data labels, procedures, and numeric equates can be
  12056.  declared public.
  12057.  
  12058.  If you specify the langtype field here, it overrides the language specified
  12059.  by .MODEL. The langtype field can be C, SYSCALL, STDCALL, PASCAL, FORTRAN,
  12060.  or BASIC. Section 7.3.3, "Declaring Parameters with the PROC Directive," and
  12061.  Section 20.1, "Naming and Calling Conventions," provide more information on
  12062.  specifying langtype types.
  12063.  
  12064.  The EXTERN directive tells the assembler that an identifier is
  12065.  external─defined in some other module that will be supplied at link time.
  12066.  Its syntax is
  12067.  
  12068.    EXTERN «langtype» name:{ABS | qualifiedtype}
  12069.  
  12070.  Section 1.2.6, "Data Types," describes qualifiedtype. The ABS (absolute)
  12071.  keyword can be used only with external numeric constants. ABS causes the
  12072.  identifier to be imported as a relocatable unsized constant. This identifier
  12073.  can then be used anywhere a constant can be used. If the identifier is not
  12074.  found in another module at link time, the linker generates an error.
  12075.  
  12076.  In the following example, the procedure  BuildTable  and the variable  Var
  12077.  are declared public. The procedure uses the Pascal naming and data-passing
  12078.  conventions:
  12079.  
  12080.  (This figure may be found in the printed book.)
  12081.  
  12082.  
  12083.  8.3.2  Other Alternatives
  12084.  
  12085.  You can also use the directives discussed earlier (EXTERNDEF, PROTO, and
  12086.  COMM) without the include file. In this case, place the declarations to make
  12087.  a symbol global in the same module where the symbol is defined. You might
  12088.  want to use this technique if you are linking only a few modules that have
  12089.  very little data in common.
  12090.  
  12091.  
  12092.  8.4  Developing Libraries
  12093.  
  12094.  As you create reusable procedures, you can place them in a library file for
  12095.  convenient access. Although you can put any routine into a library, each
  12096.  library usually contains related routines. For example, you might place
  12097.  string-manipulation functions in one library, matrix calculations in
  12098.  another, and port communications in another.
  12099.  
  12100.  A library consists of combined object modules, each created from a single
  12101.  source file. The object module is the smallest independent unit in a
  12102.  library. If you link with one symbol in a module, you get the entire module,
  12103.  but not the entire library.
  12104.  
  12105.  A library can consist of two files─an include file containing necessary
  12106.  declarations and constants and a .LIB file containing procedures already
  12107.  assembled into object code.
  12108.  
  12109.  
  12110.  8.4.1  Associating Libraries with Modules
  12111.  
  12112.  You can choose either of two methods for associating your libraries with the
  12113.  modules that use them: you can use the INCLUDELIB directive inside your
  12114.  source files or link the modules from the command line.
  12115.  
  12116.  Specify library names with INCLUDELIB.
  12117.  
  12118.  To associate a specified library with your object code, use INCLUDELIB. You
  12119.  can add this directive to the source file to specify the libraries you want
  12120.  linked, rather than specifying them in the LINK command line. The INCLUDELIB
  12121.  syntax is
  12122.  
  12123.    INCLUDELIB libraryname
  12124.  
  12125.  The libraryname can be a file name or a complete path specification. If you
  12126.  do not specify an extension, .LIB is assumed. The libraryname is placed in
  12127.  the comment record of the object file. LINK reads this record and links with
  12128.  the specified library file.
  12129.  
  12130.  For example, the statement  INCLUDELIB GRAPHICS  passes a message from the
  12131.  assembler to the linker telling LINK to use library routines from the file
  12132.  GRAPHICS.LIB. If this statement is in the source file DRAW.ASM and
  12133.  GRAPHICS.LIB is in the same directory, the program can be assembled and
  12134.  linked with the following command line:
  12135.  
  12136.    ML DRAW.ASM
  12137.  
  12138.  Link libraries with command-line options.
  12139.  
  12140.  Without the INCLUDELIB directive, the program DRAW.ASM has to be linked with
  12141.  either of the following command lines:
  12142.  
  12143.    ML DRAW.ASM GRAPHICS.LIB
  12144.    ML DRAW /link GRAPHICS
  12145.  
  12146.  If you want to assemble and link separately, you can use
  12147.  
  12148.    ML /c DRAW.ASM
  12149.    LINK DRAW,,,GRAPHICS
  12150.  
  12151.  LINK searches in a specific order.
  12152.  
  12153.  If you do not specify a complete path in the INCLUDELIB statement or at the
  12154.  command line, LINK searches for the library file in the following order:
  12155.  
  12156.  
  12157.    1.  In the current directory
  12158.  
  12159.    2.  In any directories in the library field of the LINK command line
  12160.  
  12161.    3.  In any directories in the LIB environment variable
  12162.  
  12163.  
  12164.  The LIB utility provided with MASM 6.0 helps you create, organize, and
  12165.  maintain run-time libraries.
  12166.  
  12167.  
  12168.  8.4.2  Using EXTERN with Library Routines
  12169.  
  12170.  In some cases, EXTERN helps you limit the size of your executable file by
  12171.  specifying in the syntax an alternative name for a procedure. You would use
  12172.  this form of the EXTERN directive when declaring a procedure or symbol that
  12173.  may not need to be used.
  12174.  
  12175.  The syntax looks like this:
  12176.  
  12177.    EXTERN «langtype» name « (altname)
  12178.    » :qualifiedtype
  12179.  
  12180.  The addition of the altname to the syntax provides the name of an alternate
  12181.  procedure that the linker uses to resolve the external reference if the
  12182.  procedure given by name is not needed. Both name and altname must have the
  12183.  same qualifiedtype.
  12184.  
  12185.  When the linker encounters an external definition for a procedure that gives
  12186.  an altname, the linker finishes processing that module before it links the
  12187.  object module that contains the procedure given by name. If the program does
  12188.  not reference any symbols in the name file's object from any of the linked
  12189.  modules, the assembler uses altname to satisfy the external reference. This
  12190.  saves space because the library object module is not brought in.
  12191.  
  12192.  For example, assume that the contents of STARTUP.ASM include these
  12193.  statements:
  12194.  
  12195.    EXTERN  init(dummy)
  12196.            .
  12197.            .
  12198.            .
  12199.    dummy   PROC
  12200.            .
  12201.            .
  12202.            .                     ; A procedure definition containing
  12203.    no
  12204.            ret                   ;  executable code
  12205.  
  12206.    dummy   ENDP
  12207.            .
  12208.            .
  12209.            .
  12210.            call   init   ; Defined in FLOAT.OBJ
  12211.  
  12212.  In this example, the reference to the routine  init  (defined in FLOAT.OBJ)
  12213.  does not force the module FLOAT.OBJ to be linked into the executable file.
  12214.  If another reference causes FLOAT.OBJ to be linked into the executable file,
  12215.  then  init  will refer to the  init  label in FLOAT.OBJ. If there are no
  12216.  references which force FLOAT.OBJ to be loaded, then the alternate name for
  12217.  init(dummy)  will be used by the linker.
  12218.  
  12219.  
  12220.  8.5  Related Topics in Online Help
  12221.  
  12222.  In addition to information covered in this chapter, information on the
  12223.  following topics can be found in online help.
  12224.  
  12225.  Topic                             Access
  12226.  ────────────────────────────────────────────────────────────────────────────
  12227.  LIB                               From the "Microsoft Advisor Contents"
  12228.                                    screen, choose "LIB" from the list of
  12229.                                    Microsoft Utilities
  12230.  
  12231.  INCLUDE, INCLUDELIB,              From the "MASM 6.0 Contents" screen,
  12232.  EXTERNDEF, COMM, and              choose "Directives," then "Scope and
  12233.  PUBLIC                            Visibility"
  12234.  
  12235.  TYPEDEF                           From the "MASM 6.0 Contents" screen,
  12236.                                    choose "Directives," then "Complex Data
  12237.                                    Types"
  12238.  
  12239.  PROTO and INVOKE                  From the "MASM 6.0 Contents" screen,
  12240.                                    choose "Directives," then "Procedures
  12241.                                    and Code Labels"
  12242.  
  12243.  OPTION directive                  From the "MASM 6.0 Contents" screen,
  12244.                                    choose "Directives," then "Miscellaneous"
  12245.  
  12246.  @CurSeg                           From the "MASM 6.0 Contents" screen,
  12247.                                    choose "Predefined Symbols"
  12248.  
  12249.  PWB Options menu                  From the "Microsoft Advisor Contents"
  12250.                                    screen, choose "Programmer's WorkBench"
  12251.  
  12252.  
  12253.  
  12254.  
  12255.  
  12256.  
  12257.  Chapter 9  Using Macros
  12258.  ────────────────────────────────────────────────────────────────────────────
  12259.  
  12260.  A "macro" is a symbolic name you give to a series of characters (a text
  12261.  macro) or to one or more statements (a macro procedure or function). As the
  12262.  assembler evaluates each line of your program, it scans the source code for
  12263.  names of previously defined macros. When it finds one, it substitutes the
  12264.  macro text for the macro name. In this way, you can avoid writing the same
  12265.  code several places in your program.
  12266.  
  12267.  This chapter describes the following types of macros:
  12268.  
  12269.  
  12270.    ■   Text macros, which expand to text within a source statement
  12271.  
  12272.    ■   Macro procedures, which expand to one or more complete statements and
  12273.        can optionally take parameters
  12274.  
  12275.    ■   Repeat blocks, which generate a group of statements a specified number
  12276.        of times or until a specified condition becomes true
  12277.  
  12278.    ■   Macro functions, which look like macro procedures and can be used like
  12279.        text macros but which also return a value
  12280.  
  12281.    ■   Predefined macro functions and string directives, which perform string
  12282.        operations
  12283.  
  12284.  
  12285.  Macro processing is a text-processing mechanism that is done sequentially at
  12286.  assembly time. By the end of assembly, all macros have been expanded and the
  12287.  resulting text assembled into object code.
  12288.  
  12289.  This chapter shows how to use macros for simple code substitutions as well
  12290.  as how to write sophisticated macros with parameter lists and repeat loops.
  12291.  It also describes how to use these features in conjunction with local
  12292.  symbols, macro operators, and predefined macro functions.
  12293.  
  12294.  
  12295.  9.1  Text Macros
  12296.  
  12297.  You can give a sequence of characters a symbolic name and then use the name
  12298.  in place of the text later in the source code. The named text is called a
  12299.  text macro.
  12300.  
  12301.  The syntax for defining a text macro is
  12302.  
  12303.    name TEXTEQU <text>
  12304.    name TEXTEQU macroId | textmacro
  12305.    name TEXTEQU %constExpr
  12306.  
  12307.  
  12308.  where text is a sequence of characters enclosed in angle brackets, macroId
  12309.  is a previously defined macro function (see Section 9.6), textmacro is a
  12310.  previously defined text macro, and %constExpr is an expression that
  12311.  evaluates to text. The use of angle brackets to delimit text is discussed in
  12312.  more detail in Section 9.3.1, and the % operator is explained in Section
  12313.  9.3.2.
  12314.  
  12315.  Here are some examples:
  12316.  
  12317.    msg     TEXTEQU <Some text>         ; Text assigned to symbol
  12318.    string  TEXTEQU msg                 ; Text macro assigned to symbol
  12319.    msg     TEXTEQU <Some other text>   ; New text assigned to symbol
  12320.    value   TEXTEQU %(3 + num)          ; Text representation of
  12321.                                        ;  resolved expression assigned
  12322.                                        ;  to symbol
  12323.  
  12324.  In the first line, text is assigned to the symbol  msg. In the second line,
  12325.  the text of the  msg  text macro is assigned to a new text macro called
  12326.  string. In the third line, new text is assigned to  msg. The result is that
  12327.  msg  has the new text value, while  string  has the original text value. The
  12328.  fourth line assigns  7  to  value  if  num  equals  4. If a text macro
  12329.  expands to another text macro (or macro function, which is discussed in
  12330.  Section 9.6), the resulting text macro will be recursively expanded.
  12331.  
  12332.  Text macros are useful for naming strings of text that do not evaluate to
  12333.  integers. For example, you might use a text macro to name a floating-point
  12334.  constant or a bracketed expression. Here are some practical examples:
  12335.  
  12336.    pi      TEXTEQU <3.1416>            ; Floating point constant
  12337.    WPT     TEXTEQU <WORD PTR>          ; Sequence of key words
  12338.    arg1    TEXTEQU <[bp+4]>            ; Bracketed expression
  12339.  
  12340.  ────────────────────────────────────────────────────────────────────────────
  12341.  NOTE
  12342.  
  12343.  Use of the TEXTEQU directive to define text macros is new in MASM 6.0. In
  12344.  previous versions, you can use the EQU directive for the same purpose. If
  12345.  you have old code that worked under previous versions, it should still work
  12346.  under 6.0. However, the more consistent and flexible TEXTEQU is recommended
  12347.  for new code.
  12348.  ────────────────────────────────────────────────────────────────────────────
  12349.  
  12350.  
  12351.  9.2  Macro Procedures
  12352.  
  12353.  If your program needs to perform the same task many times, you can avoid
  12354.  having to type the same statements each time by writing a macro procedure.
  12355.  Macro procedures (commonly called macros) can be seen as text-processing
  12356.  mechanisms that automatically generate repeated text.
  12357.  
  12358.  The term "macro procedure" rather than macro is used when necessary to
  12359.  distinguish between macro procedures and macro functions (a new feature of
  12360.  MASM 6.0 described in Section 9.6, "Returning Values with Macro Functions").
  12361.  
  12362.  
  12363.  
  12364.  9.2.1  Creating Macro Procedures
  12365.  
  12366.  To define a macro procedure without parameters, place the desired statements
  12367.  between the MACRO and ENDM directives:
  12368.  
  12369.  name MACRO statements ENDM
  12370.  
  12371.  For example, suppose you want a program to beep when it encounters certain
  12372.  errors. A  beep  macro can be defined as follows:
  12373.  
  12374.    beep    MACRO
  12375.        mov  ah, 2          ;; Select DOS Print Char function
  12376.        mov  dl, 7          ;; Select ASCII 7 (bell)
  12377.        int  21h            ;; Call DOS
  12378.    ENDM
  12379.  
  12380.  Macro comments must start with two semicolons instead of one.
  12381.  
  12382.  The double semicolons mark the beginning of macro comments. Macro comments
  12383.  appear in a listing file only at the macro's initial definition, not at the
  12384.  point where it is called and expanded. Listings are usually easier to read
  12385.  if the comments aren't always expanded. Regular comments (those with a
  12386.  single semicolon) are listed in macro expansions. Appendix C discusses
  12387.  listing files and shows examples of how macros are expanded in listings.
  12388.  
  12389.  Once a macro is defined, you can call it anywhere in the program by using
  12390.  the macro's name as a statement. The following example calls the  beep
  12391.  macro two times if an error flag has been set.
  12392.  
  12393.    .IF     error   ; If error flag is true
  12394.            beep            ;  execute macro two times
  12395.            beep
  12396.            .ENDIF
  12397.  
  12398.  The instructions in the macro take the place of the macro call when the
  12399.  program is assembled. This would be the resulting code (from the listing
  12400.  file):
  12401.  
  12402.    .IF     error
  12403.    0017  80 3E 0000 R 00   *         cmp    error, 000h
  12404.    001C  74 0C             *         je     @C0001
  12405.                               beep
  12406.    001E  B4 02               1         mov     ah, 2
  12407.    0020  B2 07               1         mov     dl, 7
  12408.    0022  CD 21               1         int     21h
  12409.                               beep
  12410.    0024  B4 02               1         mov     ah, 2
  12411.    0026  B2 07               1         mov     dl, 7
  12412.    0028  CD 21               1         int     21h
  12413.                               .ENDIF
  12414.    002A                  *@C0001:
  12415.  
  12416.  Contrast this with the results of defining  beep  as a procedure using the
  12417.  PROC directive and then calling it using the CALL instruction. The
  12418.  instructions of the procedure occur only once in the executable file, but
  12419.  you would also have the additional overhead of the CALL and RET
  12420.  instructions.
  12421.  
  12422.  Macros are usually faster than run-time procedures.
  12423.  
  12424.  In some cases the same task can be done with either a macro or a procedure.
  12425.  Macros are potentially faster because they have less overhead, but they
  12426.  generate the same code multiple times rather than just once.
  12427.  
  12428.  
  12429.  9.2.2  Passing Arguments to Macros
  12430.  
  12431.  Parameters allow macros to execute variations of a general task.
  12432.  
  12433.  By defining parameters for macros, you can define a general task and then
  12434.  execute variations of it by passing different arguments each time you call
  12435.  the macro. The complete syntax for a macro procedure includes a parameter
  12436.  list:
  12437.  
  12438.  name MACRO parameterlist statements ENDM
  12439.  
  12440.  The parameterlist can contain any number of parameters. Use commas to
  12441.  separate each parameter in the list. Parameter names cannot be reserved
  12442.  words unless the keyword has been disabled with OPTION NOKEYWORD, the
  12443.  compatibility modes have been set by specifying OPTION M510 (see Section
  12444.  1.3.2), or the /Zm command-line option has been set.
  12445.  
  12446.  To pass arguments to a macro, place the arguments after the macro name when
  12447.  you call the macro:
  12448.  
  12449.  macroname arglist
  12450.  
  12451.  All text between matching quotation marks in an arglist is considered one
  12452.  text item.
  12453.  
  12454.  The  beep  macro introduced in the last section used the DOS interrupt to
  12455.  write the bell character (ASCII 7). It can be rewritten with a parameter to
  12456.  specify any character to write.
  12457.  
  12458.    writechar MACRO char
  12459.        mov  ah, 2                  ;; Select DOS Print Char function
  12460.        mov  dl, char               ;; Select ASCII char
  12461.        int  21h                    ;; Call DOS
  12462.    ENDM
  12463.  
  12464.  Wherever  char  appears in the macro definition, the assembler replaces it
  12465.  with the argument in the macro call. Each time you call  writechar, you can
  12466.  print a different value:
  12467.  
  12468.    writechar 7             ; Causes computer to beep
  12469.            writechar 'A'           ; Writes A to screen
  12470.  
  12471.  If you pass more arguments than there are parameters, the additional
  12472.  arguments generate a warning (unless you use the VARARG keyword; see Section
  12473.  9.4.3). If you pass fewer arguments than the macro procedure expects,
  12474.  remaining parameters are assigned empty strings (unless default values have
  12475.  been specified). This may cause errors. For example, if you call the
  12476.  writechar  macro with no argument, it generates the following:
  12477.  
  12478.    mov     dl,
  12479.  
  12480.  The assembler generates an error for the expanded statement but not for the
  12481.  macro definition or the macro call.
  12482.  
  12483.  Macros can be made more flexible by leaving off macro arguments or adding
  12484.  additional ones. The next section tells some of the ways you can handle
  12485.  missing or extra arguments.
  12486.  
  12487.  
  12488.  9.2.3  Specifying Required and Default Parameters
  12489.  
  12490.  You can specify required and default parameters for macros.
  12491.  
  12492.  You can give macro parameters special attributes to make them more flexible
  12493.  and improve error handling; you can make them required, give them default
  12494.  values, or vary their number. Because variable parameters are used almost
  12495.  exclusively with the FOR directive, discussion of them is postponed until
  12496.  Section 9.4.3, "FOR Loops and Variable-Length Parameters."
  12497.  
  12498.  The syntax for a required parameter is
  12499.  
  12500.    parameter:REQ
  12501.  
  12502.  For example, you can rewrite the  writechar  macro to require the  char
  12503.  parameter:
  12504.  
  12505.    writechar MACRO char:REQ
  12506.        mov  ah, 2                  ;; Select DOS Print Char function
  12507.        mov  dl, char               ;; Select ASCII char
  12508.        int  21h                    ;; Call DOS
  12509.    ENDM
  12510.  
  12511.  If the call does not include a matching argument, the assembler reports the
  12512.  error in the line that contains the macro call. The effect of REQ is to
  12513.  improve error reporting.
  12514.  
  12515.  A default value fills in missing parameters.
  12516.  
  12517.  Another way to handle missing parameters is to specify a default value. The
  12518.  syntax is
  12519.  
  12520.    parameter:=textvalue
  12521.  
  12522.  Suppose that you often use  writechar  to beep by printing ASCII 7. The
  12523.  following macro definition uses an equal sign to tell the assembler to
  12524.  assume the parameter  char  is  7  unless you specify otherwise:
  12525.  
  12526.    writechar  MACRO char:=<7>
  12527.        mov  ah, 2                  ;; Select DOS Print Char function
  12528.        mov  dl, char               ;; Select ASCII char
  12529.        int  21h                    ;; Call DOS
  12530.    ENDM
  12531.  
  12532.  In this case,  char  is not required. If you don't supply a value, the
  12533.  assembler fills in the blank with the default value of  7  and the macro
  12534.  beeps when called.
  12535.  
  12536.  The default parameter value is enclosed in angle brackets so that the
  12537.  supplied value will be recognized as a text value. Section 9.3.1, "Text
  12538.  Delimiters (< >) and the Literal-Character Operator (!)," explains this in
  12539.  more detail.
  12540.  
  12541.  Missing arguments can also be handled with the IFB, IFNB, .ERRB, and .ERRNB
  12542.  directives. They are described briefly in Section 1.3.3, "Conditional
  12543.  Directives," and in online help. Here is a slightly more complex macro that
  12544.  uses some of these techniques.
  12545.  
  12546.    Scroll MACRO distance:REQ, attrib:=<07h>, tcol, trow, bcol,
  12547.    brow
  12548.        IFNB <tcol>             ;; Ignore arguments if blank
  12549.            mov   cl, tcol
  12550.        ENDIF
  12551.        IFNB <trow>
  12552.            mov   ch, trow
  12553.        ENDIF
  12554.        IFNB <bcol>
  12555.            mov   dl, bcol
  12556.        ENDIF
  12557.        IFNB <brow>
  12558.            mov   dh, brow
  12559.        ENDIF
  12560.        IFDIFI <attrib>, <bh>   ;; Don't move BH onto itself
  12561.            mov   bh, attrib
  12562.        ENDIF
  12563.        IF distance LE 0        ;; Negative scrolls up, positive down
  12564.            mov   ax, 0600h + (-(distance) AND 0FFh)
  12565.        ELSE
  12566.            mov   ax, 0700h + (distance AND 0FFh)
  12567.        ENDIF
  12568.        int   10h
  12569.    ENDM
  12570.  
  12571.  In this macro, the  distance  parameter is required. The  attrib  parameter
  12572.  has a default value of  07h  (white on black), but the macro also tests to
  12573.  make sure the corresponding argument isn't BH, since it would be inefficient
  12574.  (though legal) to load a register onto itself. The IFNB directive is used to
  12575.  test for blank arguments. These are ignored to allow the user to manipulate
  12576.  rows and columns directly in registers CX and DX at run time.
  12577.  
  12578.  The following are two valid ways to call the macro:
  12579.  
  12580.    ; Assume DL and CL already loaded
  12581.            dec     dh                   ; Decrement top row
  12582.            inc     ch                   ; Increment bottom row
  12583.            Scroll -3                    ; Scroll white on black dynamic
  12584.                                         ;  window up three lines
  12585.            Scroll 5, 17h, 2, 2, 14, 12  ; Scroll white on blue constant
  12586.                                         ;  window down five lines
  12587.  
  12588.  This macro can generate completely different code, depending on its
  12589.  arguments. In this sense, it is not comparable to a procedure, which always
  12590.  has the same code regardless of arguments.
  12591.  
  12592.  
  12593.  9.2.4  Defining Local Symbols in Macros
  12594.  
  12595.  You can make a symbol local to a macro by declaring it at the start of the
  12596.  macro with the LOCAL directive. Any identifier may be declared local.
  12597.  
  12598.  You can choose whether you want numeric equates and text macros to be local
  12599.  or global. If a symbol will be used only inside a particular macro, you can
  12600.  declare it local so that the name will be available for other declarations
  12601.  inside other macros or at the global level. On the other hand, it is
  12602.  sometimes convenient to define text macros and equates that are not local,
  12603.  so that their values can be shared between macros.
  12604.  
  12605.  If you need to use a label inside a macro, you must declare it local, since
  12606.  a label can occur only once in the source. The LOCAL directive makes a
  12607.  special instance of the label each time the macro is called. This prevents
  12608.  redefinition of the label.
  12609.  
  12610.  All local symbols must be declared immediately following the MACRO statement
  12611.  (although blank lines and comments may precede the local symbol). Separate
  12612.  each symbol with a comma. Comments are allowed on the LOCAL statement.
  12613.  Multiple LOCAL statements are also permitted. Here is an example macro that
  12614.  declares local labels:
  12615.  
  12616.    power   MACRO   factor:REQ, exponent:REQ
  12617.        LOCAL   again, gotzero      ;; Local symbols
  12618.        sub     dx, dx              ;; Clear top
  12619.        mov     ax, 1               ;; Multiply by one on first loop
  12620.        mov     cx, exponent        ;; Load count
  12621.        jcxz    gotzero             ;; Done if zero exponent
  12622.        mov     bx, factor          ;; Load factor
  12623.    again:
  12624.        mul     bx                  ;; Multiply factor times exponent
  12625.        loop    again               ;; Result in AX
  12626.    gotzero:
  12627.    ENDM
  12628.  
  12629.  If the labels  again  and  gotzero  were not declared local, the macro would
  12630.  work the first time it is called, but it would generate redefinition errors
  12631.  on subsequent calls. MASM implements local labels by generating different
  12632.  names for them each time the macro is called. You can see this in listing
  12633.  files. The labels in the  power  macro might be expanded to  ??0000  and
  12634.  ??0001  on the first call and to  ??0002  and  ??0003  on the second.
  12635.  
  12636.  
  12637.  9.3  Assembly Time Variables and Macro Operators
  12638.  
  12639.  In writing macros, you will often assign and modify values assigned to
  12640.  symbols. These symbols can be thought of as assembly-time variables. Like
  12641.  memory variables, they are symbols that represent values. But since macros
  12642.  are processed at assembly time, any symbol modified in a macro must be
  12643.  resolved as a constant by the end of assembly.
  12644.  
  12645.  The three kinds of assembly-time variables are:
  12646.  
  12647.  
  12648.    ■   Macro parameters
  12649.  
  12650.    ■   Text macros
  12651.  
  12652.    ■   Macro functions
  12653.  
  12654.  
  12655.  When a macro is expanded, the symbols are processed in the order shown
  12656.  above. First macro parameters are replaced with the text of their actual
  12657.  arguments. Then text macros are expanded.
  12658.  
  12659.  Macro parameters are similar to procedure parameters in some ways, but they
  12660.  also have important differences. In a procedure, a parameter has a type and
  12661.  a memory location. Its value can be modified within the procedure. In a
  12662.  macro, a parameter is a placeholder for the argument text. The value can
  12663.  only be assigned to another symbol or used directly; it cannot be modified.
  12664.  The macro may interpret the argument text it receives either as a numeric
  12665.  value or as a text value.
  12666.  
  12667.  It is important to understand the difference between text values and numeric
  12668.  values. Numeric values can be processed with arithmetic operators and
  12669.  assigned to numeric equates. Text values can be processed with macro
  12670.  functions and assigned to text macros.
  12671.  
  12672.  Macro operators are often helpful when processing assembly-time variables.
  12673.  Table 9.1 shows the macro operators that MASM provides:
  12674.  
  12675.  Table 9.1  MASM Macro Operators
  12676.  
  12677.  Symbol  Name                              Description
  12678.  ────────────────────────────────────────────────────────────────────────────
  12679.  < >     Text Delimiters                   Opens and closes a literal
  12680.                                            string.
  12681.  
  12682.  !       Literal-Character Operator        Treats the next character as a
  12683.                                            literal character, even if it
  12684.                                            would normally have another
  12685.                                            meaning.
  12686.  
  12687.  %       Expansion Operator                Causes the assembler to expand a
  12688.                                            constant expression or text
  12689.                                            macro.
  12690.  
  12691.  &       Substitution Operator             Tells the assembler to replace a
  12692.                                            macro parameter or text macro
  12693.                                            name with its
  12694.                                            actual value.
  12695.  
  12696.  ────────────────────────────────────────────────────────────────────────────
  12697.  
  12698.  
  12699.  The next sections explain these operators in detail.
  12700.  
  12701.  
  12702.  9.3.1  Text Delimiters (< >) and the Literal-Character Operator (!)
  12703.  
  12704.  The angle brackets (< >) are text delimiters. The most common reason to
  12705.  delimit a text value is when assigning a text macro. You can do this with
  12706.  TEXTEQU, as previously shown, or with the SUBSTR and CATSTR directives
  12707.  discussed in Section 9.5, "String Directives and Predefined Functions."
  12708.  
  12709.  By delimiting the text of macro arguments, you can pass text that includes
  12710.  spaces, commas, semicolons, and other special characters. In the following
  12711.  example, assume you have previously defined a macro called  work:
  12712.  
  12713.    work    <1, 2, 3, 4, 5> ; Passes one argument
  12714.                                    ;  with 15 characters
  12715.            work    1, 2, 3, 4, 5   ; Passes five arguments, each
  12716.                                    ;  with 1 character
  12717.  
  12718.  Since angle brackets are delimiters, you can't include them as part of a
  12719.  delimited text value. The literal-character operator (!) can be used to
  12720.  override this limitation. It forces the assembler to treat the character
  12721.  following it literally rather than as a special character.
  12722.  
  12723.    errstr  TEXTEQU <Expression !> 255>  ; errstr = "Expression
  12724.    > 255"
  12725.  
  12726.  Text delimiters also have a special use with the FOR directive, as explained
  12727.  in Section 9.4.3.
  12728.  
  12729.  
  12730.  9.3.2  Expansion Operator (%)
  12731.  
  12732.  The expansion operator (%) expands text macros or converts constant
  12733.  expressions into their text representations. It performs these tasks
  12734.  differently in different contexts, as discussed below.
  12735.  
  12736.  
  12737.  9.3.2.1  The Expansion Operator with Constants
  12738.  
  12739.  The expansion operator can be used in any context where a text value is
  12740.  expected but a numeric value is supplied. In these contexts, it can be
  12741.  thought of as a conversion operator to convert numeric values to text
  12742.  values.
  12743.  
  12744.  The expansion operator forces immediate evaluation of a constant expression
  12745.  and replaces it with a text value consisting of the digits of the result.
  12746.  The digits are generated in the current radix (default decimal).
  12747.  
  12748.  This application of the expansion operator is useful when defining a text
  12749.  macro:
  12750.  
  12751.    a       TEXTEQU <3 + 4>         ; a = "3 + 4"
  12752.    b       TEXTEQU %3 + 4          ; b = "7"
  12753.  
  12754.  When assigning text macros, numeric equates can be used in the constant
  12755.  expressions, but text macros cannot:
  12756.  
  12757.    num     EQU     4               ; num = 4
  12758.    numstr  TEXTEQU <4>             ; numstr = <4>
  12759.    a       TEXTEQU %3 + num        ; a = <7>
  12760.    b       TEXTEQU %3 + numstr     ; b = <7>
  12761.  
  12762.  The expansion operator can be used when passing macro arguments. If you want
  12763.  the value rather than the text of an expression to be passed, use the
  12764.  expansion operator. Use of the expansion operator depends on whether you
  12765.  want the expression to be evaluated inside the macro on each use, or outside
  12766.  the macro once. The following macro
  12767.  
  12768.    work    MACRO   arg
  12769.        mov ax, arg * 4
  12770.    ENDM
  12771.  
  12772.  can be called with these statements:
  12773.  
  12774.    work    2 + 3           ; Passes "2 + 3"
  12775.                                    ; Code: mov ax, 2 + 3 * 4 (14)
  12776.            work    %2 + 3          ; Passes 5
  12777.                                    ; Code: mov ax, 5 * 4 (20)
  12778.  
  12779.  Notice that because of operator precedence, results can vary depending on
  12780.  whether the expansion operator is used. Sometimes parentheses can be used
  12781.  inside the macro to force evaluation in a particular order:
  12782.  
  12783.    work    MACRO   arg
  12784.        mov ax, (arg) * 4
  12785.    ENDM
  12786.  
  12787.            work    2 + 3           ; Code: mov ax, (2 + 3) * 4 (20)
  12788.            work    %2 + 3          ; Code: mov ax, (5) * 4 (20)
  12789.  
  12790.  This example generates the same code regardless of whether you pass the
  12791.  argument as a value or as text, but in some cases you need to specify how
  12792.  the argument is passed.
  12793.  
  12794.  The value for a default argument must be text, but frequently you need to
  12795.  give a constant value. The expansion operator is one way to force the
  12796.  conversion. The following statements are equivalent:
  12797.  
  12798.    work    MACRO   arg:=<07h>
  12799.    work    MACRO   arg:=%07h
  12800.  
  12801.  The expansion operator also has several uses with macro functions. See
  12802.  Section 9.6.
  12803.  
  12804.  
  12805.  9.3.2.2  The Expansion Operator with Symbols
  12806.  
  12807.  When you use the expansion operator on a macro argument, any text macros or
  12808.  numeric equates in the argument are expanded:
  12809.  
  12810.    num     EQU     4
  12811.    numstr  TEXTEQU <4>
  12812.  
  12813.            work    2 + num         ; Passes "2 + num"
  12814.            work    %2 + num        ; Passes "6"
  12815.            work    2 + numstr      ; Passes "2 + numstr"
  12816.            work    %2 + numstr     ; Passes "6"
  12817.  
  12818.  The arguments can optionally be enclosed in parentheses. For example, these
  12819.  two statements are equivalent:
  12820.  
  12821.    work    %2 + num
  12822.            work    %(2 + num)
  12823.  
  12824.  
  12825.  9.3.2.3  The Expansion Operator as the First Character on a Line
  12826.  
  12827.  The expansion operator has a different meaning when used as the first
  12828.  character on a line. In this case, it instructs the assembler to expand any
  12829.  text macros and macro functions it finds on the rest of the line.
  12830.  
  12831.  This feature makes it possible to use text macros with directives such as
  12832.  ECHO, TITLE, and SUBTITLE that take an argument consisting of a single text
  12833.  value. For instance, ECHO displays its argument to the standard output
  12834.  device during assembly. Such expansion can be useful for debugging macros
  12835.  and expressions, but the requirement that its argument be a single text
  12836.  value may have unexpected results:
  12837.  
  12838.    ECHO    Bytes per element: %(SIZEOF array / LENGTHOF
  12839.    array)
  12840.  
  12841.  Instead of evaluating the expression, this line just echoes it:
  12842.  
  12843.    Bytes per element: %(SIZEOF array / LENGTHOF array)
  12844.  
  12845.  However, you can achieve the desired result by assigning the text of the
  12846.  expression to a text macro and then using the expansion operator at the
  12847.  beginning of the line to force expansion of the text macro.
  12848.  
  12849.    temp    TEXTEQU %(SIZEOF array / LENGTHOF array)
  12850.    %       ECHO    Bytes per element: temp
  12851.  
  12852.  Note that you cannot get the same results by simply putting the % at the
  12853.  beginning of the first echo line, because % expands only text macros, not
  12854.  numeric equates or constant expressions.
  12855.  
  12856.  Here are more examples of the use of the expansion operator at the start of
  12857.  a line:
  12858.  
  12859.    ; Assume memmod, lang, and os are passed in with /D option
  12860.    %   SUBTITLE  Model: memmod  Language: lang  Operating System: os
  12861.  
  12862.    ; Assume num defined earlier
  12863.    tnum    TEXTEQU %num
  12864.    %       .ERRE   num LE 255, <Failed because tnum !> 255>
  12865.  
  12866.  
  12867.  9.3.3  Substitution Operator (&)
  12868.  
  12869.  In MASM 6.0, the substitution operator (&) enables substitution of macro
  12870.  parameters, even when the parameter occurs within a larger word or within a
  12871.  quoted string. It can also be used to concatenate two macro parameters after
  12872.  they have been expanded.
  12873.  
  12874.  The syntax for the substitution operator looks like this:
  12875.  
  12876.    ¶metername&
  12877.  
  12878.  The operators delimiting a name always tell the assembler to substitute the
  12879.  actual argument for the name. However, the substitution operator is often
  12880.  optional. The substitution operator is not necessary when there is a space
  12881.  or separation character (comma, tab, or other operator) on that side. In the
  12882.  case of a parameter name inside a string, at least one substitution operator
  12883.  must appear.
  12884.  
  12885.  The rules for using the substitution operator have changed significantly
  12886.  since MASM 5.1, making macro behavior more consistent and flexible. If you
  12887.  have macros written for a previous version of MASM, you can specify the old
  12888.  behavior by using OLDMACROS or M510 with the OPTION directive (see Section
  12889.  1.3.2).
  12890.  
  12891.  In the macro
  12892.  
  12893.    work    MACRO   arg
  12894.        mov ax, &arg& * 4
  12895.    ENDM
  12896.  
  12897.  the & symbols tell the assembler to replace the value of  arg  with the
  12898.  corresponding argument. However, the characters on both the right and left
  12899.  are spaces. Therefore, the operators are unnecessary. The macro would
  12900.  normally be written like this:
  12901.  
  12902.    work    MACRO   arg
  12903.        mov ax, arg * 4
  12904.    ENDM
  12905.  
  12906.  The substitution operator is used for one of the following reasons:
  12907.  
  12908.  
  12909.    ■   To paste together two parameter names or a parameter name and text
  12910.  
  12911.    ■   To indicate that a parameter name inside double or single quotation
  12912.        marks should be expanded rather than be treated as part of the quoted
  12913.        string
  12914.  
  12915.  
  12916.  This macro illustrates both uses:
  12917.  
  12918.    errgen  MACRO   num, msg
  12919.        PUBLIC  err&num
  12920.        err&num BYTE    "Error &num: &msg"
  12921.    ENDM
  12922.  
  12923.  When called with the following arguments,
  12924.  
  12925.    errgen  5, <Unreadable disk>
  12926.  
  12927.  the macro generates this code:
  12928.  
  12929.    PUBLIC  err5
  12930.    err5    BYTE    "Error 5: Unreadable disk"
  12931.  
  12932.  In the second line of the macro, the left & symbol must be provided because
  12933.  it is adjacent to the  r  character, which is a valid identifier symbol. The
  12934.  right & symbol is not needed because there is a space to the right of the
  12935.  m. The statement pastes the text  err  to the argument value  5  to generate
  12936.  the symbol  err5.
  12937.  
  12938.  The substitution operator is used again inside quotation marks at the start
  12939.  of the parameter names  num  and  msg  to indicate that these names should
  12940.  be expanded. In this case, no pasting operation is necessary, so either
  12941.  operator could be omitted, but not both. The macro line could have been
  12942.  written as
  12943.  
  12944.    err&num BYTE    "Error num&: msg&"
  12945.  
  12946.  or
  12947.  
  12948.    err&num BYTE    "Error &num&: &msg&"
  12949.  
  12950.  The assembler processes substitution operators from left to right. This can
  12951.  have unexpected results when you are pasting together two macro parameters.
  12952.  For example, if  arg1  has the value  var  and  arg2  has the value  3, you
  12953.  could paste them together with this statement:
  12954.  
  12955.    &arg1&&arg2&    BYTE    "Text"
  12956.  
  12957.  Eliminating extra substitution operators, you might expect the following to
  12958.  be equivalent:
  12959.  
  12960.    &arg1&arg2      BYTE    "Text"
  12961.  
  12962.  However, this actually produces the symbol  vararg2  because in processing
  12963.  from left to right the assembler associates both the first and the second &
  12964.  symbols with the first parameter. The assembler replaces  &arg1&  by  var ,
  12965.  producing  vararg2 . The  arg2  is never evaluated. The correct abbreviation
  12966.  is
  12967.  
  12968.    arg1&&arg2      BYTE    "Text"
  12969.  
  12970.  which produces the desired symbol  var3. The symbol  arg1&&arg2  is replaced
  12971.  by  var&arg2, which is replaced by  var3.
  12972.  
  12973.  The substitution operator is also necessary if you want a text macro
  12974.  substituted inside quotes. For example,
  12975.  
  12976.    arg     TEXTEQU <hello>
  12977.    %echo   This is a string "&arg" ; Produces: This is a string "hello"
  12978.    %echo   This is a string "arg"  ; Produces: This is a string "arg"
  12979.  
  12980.  The substitution operator can also be used in lines beginning with the
  12981.  expansion operator (%) symbol, even outside macros (see Section 9.3.2.3).
  12982.  Text macros are always expanded in such lines, but it may be necessary to
  12983.  use the substitution operator to paste text macro names to adjacent
  12984.  characters or symbol names, as shown below:
  12985.  
  12986.    text    TEXTEQU <var>
  12987.    value   TEXTEQU %5
  12988.    %       ECHO    textvalue is text&&value
  12989.  
  12990.  This echoes the message
  12991.  
  12992.    textvalue is var5
  12993.  
  12994.  Bit-test and macro expansion statements can be confused.
  12995.  
  12996.  The single ampersand (&) is the bit-test operator in MASM, as it is for C.
  12997.  This operator is also used in macro expansion as the substitute operator.
  12998.  Macro substitution always occurs before evaluation of the high-level control
  12999.  structures; therefore, in ambiguous cases, the & operator is treated as a
  13000.  macro-expansion character. You can always guarantee the correct use of the
  13001.  bit-test operator by enclosing the bit-test operands in parentheses. The
  13002.  example below illustrates these two uses.
  13003.  
  13004.    test    MACRO   x
  13005.        .IF ax==&x      ; &x substituted with parameter value
  13006.        mov     ax, 10
  13007.        .ELSEIF ax&(x)  ; & is bitwise AND
  13008.        mov ax, 20
  13009.        .ENDIF
  13010.        ENDM
  13011.  
  13012.  
  13013.  9.4  Defining Repeat Blocks with Loop Directives
  13014.  
  13015.  A "repeat block" is an unnamed macro defined with a loop directive. It
  13016.  generates the statements inside the repeat block a specified number of times
  13017.  or until a given condition becomes true.
  13018.  
  13019.  Several loop directives are available, providing different ways of
  13020.  specifying the number of iterations. Some loop directives also provide a way
  13021.  to specify arguments for each iteration. Although the number of iterations
  13022.  is usually specified in the directive, you can use the EXITM directive to
  13023.  exit from the loop early.
  13024.  
  13025.  Repeat blocks can be used outside macros, but they frequently appear inside
  13026.  macro definitions to perform some repeated operation in the macro.
  13027.  
  13028.  This section explains the following four loop directives: REPEAT, WHILE,
  13029.  FOR, and FORC. In previous versions of MASM, REPEAT was called REPT, FOR was
  13030.  called IRP, and FORC was called IRPC. MASM 6.0 still recognizes the old
  13031.  names.
  13032.  
  13033.  ────────────────────────────────────────────────────────────────────────────
  13034.  NOTE
  13035.  
  13036.  The REPEAT and WHILE directives should not be confused with the .REPEAT and
  13037.  .WHILE directives (see Section 7.2.1, "Loop-Generating Directives"), which
  13038.  generate loop and jump instructions for run-time program control.
  13039.  ────────────────────────────────────────────────────────────────────────────
  13040.  
  13041.  
  13042.  9.4.1  REPEAT Loops
  13043.  
  13044.  Repeat loops are expanded at assembly time.
  13045.  
  13046.  The REPEAT directive is the simplest loop directive. It specifies the number
  13047.  of times to generate the statements inside the macro. The syntax is
  13048.  
  13049.    REPEAT constexpr
  13050.    statements
  13051.    ENDM
  13052.  
  13053.  The constexpr can be a constant or a constant expression, and must contain
  13054.  no forward references. Since the repeat block will be expanded at assembly
  13055.  time, the number of iterations must be known then.
  13056.  
  13057.  Here is an example of a repeat block used to generate data. It initializes
  13058.  an array containing sequential ASCII values for all uppercase letters.
  13059.  
  13060.    alpha   LABEL   BYTE            ;  Name the data generated
  13061.    letter  =       'A'             ;  Initialize counter
  13062.    REPEAT  26                      ;; Repeat for each letter
  13063.        BYTE    letter              ;; Allocate ASCII code for letter
  13064.        letter  = letter + 1        ;; Increment counter
  13065.    ENDM
  13066.  
  13067.  Here is another use of REPEAT, this time inside a macro:
  13068.  
  13069.    beep    MACRO   iter:=<3>
  13070.        mov ah, 2                   ;; Character output function
  13071.        mov dl, 7                   ;; Bell character
  13072.        REPEAT iter                 ;; Repeat number specified by macro
  13073.            int 21h                 ;; Call DOS
  13074.        ENDM
  13075.    ENDM
  13076.  
  13077.  
  13078.  9.4.2  WHILE Loops
  13079.  
  13080.  The WHILE directive is similar to REPEAT, but the loop continues as long as
  13081.  a given condition is true. The syntax is
  13082.  
  13083.    WHILE expression
  13084.    statements
  13085.    ENDM
  13086.  
  13087.  The expression must be a value that can be calculated at assembly time.
  13088.  Normally the expression uses relational operators, but it can be any
  13089.  expression that evaluates to zero (false) or nonzero (true). Usually, the
  13090.  condition changes during the evaluation of the macro so that the loop won't
  13091.  attempt to generate an infinite amount of code. However, you can use the
  13092.  EXITM directive to break out of the loop.
  13093.  
  13094.  Loops are especially useful for generating lookup tables.
  13095.  
  13096.  The following repeat block uses the WHILE directive to allocate variables
  13097.  initialized to calculated values. This is a common technique for generating
  13098.  lookup tables. Frequently it is faster to look up a value precalculated by
  13099.  the assembler at assembly time than to have the processor calculate the
  13100.  value at run time.
  13101.  
  13102.    cubes   LABEL   BYTE            ;; Name the data generated
  13103.    root    =   1                   ;; Initialize root
  13104.    cube    =   root * root * root  ;; Calculate first cube
  13105.    WHILE   cube LE 32767           ;; Repeat until result too large
  13106.        WORD   cube                 ;; Allocate cube
  13107.        root   =    root + 1        ;; Calculate next root and cube
  13108.        cube   =    root * root * root
  13109.    ENDM
  13110.  
  13111.  
  13112.  9.4.3  FOR Loops and Variable-Length Parameters
  13113.  
  13114.  With the FOR directive you can iterate through a list of arguments, doing
  13115.  some operation on each of them in turn. It has the following syntax:
  13116.  
  13117.  FOR parameter, <argumentlist> statements ENDM
  13118.  
  13119.  The parameter is a placeholder that will be used as the name of each
  13120.  argument inside the FOR block. The argument list must be a list of
  13121.  comma-separated arguments and must always be enclosed in angle brackets, as
  13122.  the following example illustrates:
  13123.  
  13124.    series  LABEL   BYTE
  13125.    FOR     arg, <1,2,3,4,5,6,7,8,9,10>
  13126.        BYTE  arg DUP (arg)
  13127.    ENDM
  13128.  
  13129.  On the first iteration, the  arg  parameter is replaced with the first
  13130.  argument, the value 1. On the second iteration  arg  is replaced with 2. The
  13131.  result is an array with the first byte initialized to 1, the next two bytes
  13132.  initialized to 2, the next three bytes initialized to 3, and so on.
  13133.  
  13134.  In this example the argument list is given specifically, but in some cases
  13135.  the list must be generated as a text macro. The value of the text macro must
  13136.  include the angle brackets.
  13137.  
  13138.    arglist TEXTEQU <!<3,6,9!>>     ; Generate list as text macro
  13139.    FOR  arg, arglist
  13140.        .                           ; Do something to arg
  13141.        .
  13142.        .
  13143.    ENDM
  13144.  
  13145.  Note the use of the literal character operator (!) to use angle brackets as
  13146.  characters, not delimiters (see Section 9.3.1).
  13147.  
  13148.  Variable parameter lists provide flexibility.
  13149.  
  13150.  The FOR directive also provides a convenient way to process macros with a
  13151.  variable number of arguments. To do this, add VARARG to the last parameter
  13152.  to indicate that a single named parameter will have the actual value of all
  13153.  additional arguments. For example, the following macro definition includes
  13154.  the three possible parameter attributes─required, default, and variable.
  13155.  
  13156.    work    MACRO   rarg:REQ, darg:=<5>, varg:VARARG
  13157.  
  13158.  The variable argument must always come last. If this macro is called with
  13159.  the statement
  13160.  
  13161.    work 5, , 6, 7, a, b
  13162.  
  13163.  the first argument is received as passed, the second is replaced by the
  13164.  default value  5, and the last four are received as the single argument  <6,
  13165.  7, a, b>. This is the same format expected by the FOR directive. The FOR
  13166.  directive discards leading spaces but recognizes trailing spaces.
  13167.  
  13168.  The following macro illustrates variable arguments:
  13169.  
  13170.    show    MACRO chr:VARARG
  13171.        mov     ah, 02h
  13172.        FOR arg, <chr>
  13173.            mov     dl, arg
  13174.            int     21h
  13175.        ENDM
  13176.    ENDM
  13177.  
  13178.  When called with
  13179.  
  13180.    show  'O', 'K', 13, 10
  13181.  
  13182.  the macro displays each of the specified characters one at a time.
  13183.  
  13184.  The parameter in a FOR loop can have the required or default attribute. The
  13185.  show  macro can be modified to make blank arguments generate errors:
  13186.  
  13187.    show    MACRO chr:VARARG
  13188.        mov     ah, 02h
  13189.        FOR arg:REQ, <chr>
  13190.            mov     dl, arg
  13191.            int     21h
  13192.        ENDM
  13193.    ENDM
  13194.  
  13195.  The macro now generates an error if called with
  13196.  
  13197.    show  'O',, 'K', 13, 10
  13198.  
  13199.  Another approach would be to use a default argument:
  13200.  
  13201.    show    MACRO chr:VARARG
  13202.        mov     ah, 02h
  13203.        FOR arg:=<' '>, <chr>
  13204.            mov     dl, arg
  13205.            int     21h
  13206.        ENDM
  13207.    ENDM
  13208.  
  13209.  Now if the macro is called with
  13210.  
  13211.    show  'O',, 'K', 13, 10
  13212.  
  13213.  it inserts the default character, a space, for the blank argument.
  13214.  
  13215.  
  13216.  9.4.4  FORC Loops
  13217.  
  13218.  The FORC directive is similar to FOR but takes a string of text rather than
  13219.  a list of arguments. The statements are assembled once for each character
  13220.  (including spaces) in the string, substituting a different character for the
  13221.  parameter each time through.
  13222.  
  13223.  The syntax looks like this:
  13224.  
  13225.    FORC parameter, < text>
  13226.    statements
  13227.    ENDM
  13228.  
  13229.  The text must be enclosed in angle brackets. The following example
  13230.  illustrates FORC:
  13231.  
  13232.    FORC arg, <ABCDEFGHIJKLMNOPQRSTUVWXYZ>
  13233.        BYTE  '&arg'             ;; Allocate uppercase letter
  13234.        BYTE  '&arg' + 20h       ;; Allocate lowercase letter
  13235.        BYTE  '&arg' - 40h       ;; Allocate ordinal of letter
  13236.    ENDM
  13237.  
  13238.  Notice that the substitution operator must be used inside the quotation
  13239.  marks to make sure that  arg  is expanded to a character rather than treated
  13240.  as a literal string.
  13241.  
  13242.  With earlier versions of MASM, FORC is often used for complex parsing tasks.
  13243.  A long sentence can be examined character by character. Each character is
  13244.  then either thrown away or pasted onto a token string, depending on whether
  13245.  it is a separator character. In MASM 6.0, the predefined macro functions and
  13246.  string processing directives discussed in Section 9.5 are usually more
  13247.  efficient for these tasks.
  13248.  
  13249.  
  13250.  9.5  String Directives and Predefined Functions
  13251.  
  13252.  Predefined macro string functions are new to MASM 6.0.
  13253.  
  13254.  The assembler provides the following directives for manipulating text:
  13255.  SUBSTR, INSTR, SIZESTR, and CATSTR. Each of these has a corresponding
  13256.  predefined macro function version: @SubStr, @InStr, @SizeStr, and @CatStr.
  13257.  
  13258.  You use the directive versions to assign a processed value to a text macro
  13259.  or numeric equate. For example, CATSTR, which concatenates a list of text
  13260.  values, can be used like this:
  13261.  
  13262.    num     =       7
  13263.    newstr  CATSTR  <3 + >, %num, < = > , %3 + num ; "3 + 7 = 10"
  13264.  
  13265.  Assignment with CATSTR and SUBSTR works like assignment with the TEXTEQU
  13266.  directive. Assignment with SIZESTR and INSTR works like assignment with the
  13267.  = operator.
  13268.  
  13269.  The arguments to directives must be text values. Use the expansion operator
  13270.  to make sure that constants and numeric equates are expanded to text.
  13271.  
  13272.  The macro function versions are similar, but their arguments must be
  13273.  enclosed in parentheses. Macro functions return text values and can be used
  13274.  in any context where text is expected. Section 9.6 tells how to write your
  13275.  own macro functions. An equivalent statement to the previous example using
  13276.  CATSTR is
  13277.  
  13278.    num     =       7
  13279.    newstr  TEXTEQU @CatStr( <3 + >, %num, < = > , %3 + num )
  13280.  
  13281.  Although the directive version is simpler in the example above, the function
  13282.  versions are often convenient because they can be used as arguments to
  13283.  string directives or to other macro functions.
  13284.  
  13285.  Unlike the string directives, predefined macro function names are case
  13286.  sensitive. Since MASM is not case sensitive by default, the case doesn't
  13287.  matter unless you use the /Cp command-line option.
  13288.  
  13289.  The following sections summarize the syntax for each of the string
  13290.  directives and functions. The explanations focus on the directives, but the
  13291.  functions work the same except where noted.
  13292.  
  13293.  
  13294.  SUBSTR
  13295.  
  13296.    name SUBSTR string, start«, length»
  13297.    @SubStr( string, start«, length» )
  13298.  
  13299.  The SUBSTR directive assigns a substring from a given string to a new
  13300.  symbol, specified by name. Start specifies the position (1-based) in string
  13301.  to start the substring. Length specifies the length of the substring. If
  13302.  length is not given, it is assumed to be the remainder of the string
  13303.  including the start character. The string
  13304.  
  13305.  in the SUBSTR syntax, as well as in the syntax for the other string
  13306.  directives and predefined functions, can be any textItem where textItem can
  13307.  be text enclosed in angle brackets (< >), the name of a macro, or a constant
  13308.  expression preceded by % (%constExpr).
  13309.  
  13310.  
  13311.  INSTR
  13312.  
  13313.    name INSTR «start,» string, substring
  13314.    @InStr( «start», string, substring
  13315.    )
  13316.  
  13317.  The INSTR directive searches a specified string for an occurrence of a given
  13318.  substring and assigns its position (1-based) to name. The search is case
  13319.  sensitive. Start is the position in string to start the search for
  13320.  substring. If start is not given, it is assumed to be 1 (the start of the
  13321.  string). If substring is not found, the position assigned to name is 0.
  13322.  
  13323.  If the INSTR directive is used, the position value is assigned to a name as
  13324.  if it were a numeric equate. If the @InStr function is used, the value is
  13325.  returned as a string of digits in the current radix.
  13326.  
  13327.  The @InStr function has a slightly different syntax than the INSTR
  13328.  directive. You can omit the first argument and its associated comma from the
  13329.  directive. You can leave the first argument blank with the function, but a
  13330.  blank function argument must still have a comma. For example,
  13331.  
  13332.    pos     INSTR   <person>, <son>
  13333.  
  13334.  is the same as
  13335.  
  13336.    pos     = @InStr( , <person>, <son> )
  13337.  
  13338.  The return value could also be assigned to a text macro:
  13339.  
  13340.    strpos  TEXTEQU @InStr( , <person>, <son> )
  13341.  
  13342.  
  13343.  SIZESTR
  13344.  
  13345.    name SIZESTR string
  13346.    @SizeStr( string )
  13347.  
  13348.  The SIZESTR directive assigns the number of characters in string to name. An
  13349.  empty string assigns a length of zero. Although the length is always a
  13350.  positive number, it is assigned as a string of digits in the current radix
  13351.  rather than as a numeric value.
  13352.  
  13353.  If the SIZESTR directive is used, the size value is assigned to a name as if
  13354.  it were a numeric equate. If the @SizeStr function is used, the value is
  13355.  returned as a string of digits in the current radix.
  13356.  
  13357.  
  13358.  CATSTR
  13359.  
  13360.    name CATSTR string«, string»...
  13361.    @CatStr( string«,  string»... )
  13362.  
  13363.  The CATSTR directive concatenates a list of text values specified by string
  13364.  into a single text value and assigns it to name. TEXTEQU is technically a
  13365.  synonym for CATSTR. TEXTEQU is normally used for single-string assignments,
  13366.  while CATSTR is used for multistring concatenations.
  13367.  
  13368.  The following example that pushes and pops one set of registers illustrates
  13369.  several uses of string directives and functions:
  13370.  
  13371.    ; SaveRegs - Macro to generate a push instruction for each
  13372.    ; register in argument list. Saves each register name in the
  13373.    ; regpushed text macro.
  13374.    regpushed TEXTEQU <>                    ;; Initialize empty string
  13375.  
  13376.    SaveRegs MACRO regs:VARARG
  13377.        FOR reg, <regs>                     ;; Push each register
  13378.            push reg                        ;;  and add it to the list
  13379.            regpushed CATSTR   <reg>, <,>, regpushed
  13380.        ENDM                                ;; Strip off last comma
  13381.        regpushed CATSTR <!<>, regpushed    ;; Mark start of list with
  13382.    <
  13383.        regpushed SUBSTR regpushed, 1, @SizeStr( regpushed )
  13384.        regpushed CATSTR regpushed, <!>>    ;; Mark end with >
  13385.    ENDM
  13386.  
  13387.    ; RestoreRegs - Macro to generate a pop instruction for registers
  13388.    ; saved by the SaveRegs macro. Restores one group of registers.
  13389.  
  13390.    RestoreRegs MACRO
  13391.        LOCAL regs
  13392.        %FOR reg, regpushed                  ;; Pop each register        pop
  13393.    reg
  13394.        ENDM
  13395.     ENDM
  13396.  
  13397.  Notice how the  SaveRegs  macro saves its result in the  regpushed  text
  13398.  macro for later use by the  RestoreRegs  macro. In this case, a text macro
  13399.  is used as a global variable. By contrast, the  regs  text macro is used
  13400.  only in RestoreRegs. It is declared LOCAL so that it won't take the name
  13401.  regs  from the global name space. The MACROS.INC file provided with MASM 6.0
  13402.  includes expanded versions of these same two macros.
  13403.  
  13404.  
  13405.  9.6  Returning Values with Macro Functions
  13406.  
  13407.  A macro function returns a text string.
  13408.  
  13409.  A macro function is a named group of statements that returns a value. When a
  13410.  macro function is called, its argument list must be enclosed in parentheses,
  13411.  even if the list is empty. The value returned is always text.
  13412.  
  13413.  Macro functions are new to MASM 6.0, as are several predefined macro
  13414.  functions for common tasks. The predefined macros include @Environ (see
  13415.  Section 1.2.3) and the string functions @SizeStr, @CatStr, @SubStr, and
  13416.  @InStr (discussed in the preceding section).
  13417.  
  13418.  Macro functions are defined in exactly the same way as macro procedures,
  13419.  except that a value must always be returned using the EXITM directive. Here
  13420.  is an example:
  13421.  
  13422.    DEFINED MACRO   symbol:REQ
  13423.        IFDEF symbol
  13424.            EXITM <-1>              ;; True
  13425.        ELSE
  13426.            EXITM <0>               ;; False
  13427.        ENDIF
  13428.    ENDM
  13429.  
  13430.  This macro works like the defined operator in the C language. You can use it
  13431.  to test the defined state of several different symbols with a single
  13432.  statement, as shown below:
  13433.  
  13434.    IF DEFINED( DOS ) AND NOT DEFINED( XENIX )
  13435.        ;; Do something
  13436.    ENDIF
  13437.  
  13438.  Notice that the macro returns integer values as strings of digits, but the
  13439.  IF statement evaluates numeric values or expressions. There is no conflict
  13440.  because the value returned by the macro function is seen in the statement
  13441.  exactly as if the user had typed the values directly into the program:
  13442.  
  13443.    IF -1 AND NOT 0
  13444.  
  13445.  
  13446.  Returning Values with EXITM
  13447.  
  13448.  The return value must be text, a text equate name, or the result of another
  13449.  macro function. If a function must return a numeric value (such as a
  13450.  constant, a numeric equate, or the result of a numeric expression), it must
  13451.  first convert the value to text using angle brackets or the expansion
  13452.  operator (%). The defined macro, for example, could have returned its value
  13453.  as
  13454.  
  13455.    EXITM   %-1
  13456.  
  13457.  Although macro functions can include any legal statement, they seldom need
  13458.  to include instructions. This is because a macro function is expanded and
  13459.  its value returned at assembly time, while instructions are executed at run
  13460.  time.
  13461.  
  13462.  Here is another example of a macro function. It uses the WHILE directive to
  13463.  calculate factorials:
  13464.  
  13465.    factorial   MACRO   num:REQ
  13466.        LOCAL   i, factor
  13467.        factor  =   num
  13468.        i       =   1
  13469.        WHILE   factor GT 1
  13470.            i       =   i * factor
  13471.            factor  =   factor - 1
  13472.        ENDM
  13473.        EXITM   %i
  13474.    ENDM
  13475.  
  13476.  The integer result of the calculation is changed to a text string with the
  13477.  expansion operator (%). The  factorial  macro can be used to define data, as
  13478.  shown below:
  13479.  
  13480.    var     WORD    factorial( 4 )
  13481.  
  13482.  The effect of this statement is to initialize  var  with the number 24 (the
  13483.  factorial of 4).
  13484.  
  13485.  
  13486.  Using Macro Functions with Variable-Length Parameter Lists
  13487.  
  13488.  Macro functions can enhance FOR loops.
  13489.  
  13490.  You can use the FOR directive to handle macro parameters with the VARARG
  13491.  attribute. Section 9.4.3 explains how to do this in simple cases where the
  13492.  variable parameters are handled sequentially, from first to last. However,
  13493.  you may sometimes need to process the parameters in reverse order or
  13494.  nonsequentially. Macro functions make these techniques possible.
  13495.  
  13496.  You may need to know the number of arguments in a VARARG parameter. The
  13497.  following macro functions handle this.
  13498.  
  13499.    @ArgCount MACRO arglist:VARARG
  13500.        LOCAL count
  13501.        count = 0
  13502.        FOR arg, <arglist>
  13503.            count = count + 1       ;; Count the arguments
  13504.        ENDM
  13505.        EXITM %count
  13506.    ENDM
  13507.  
  13508.  You could use this inside a macro that has a VARARG parameter, as shown
  13509.  below:
  13510.  
  13511.    work    MACRO args:VARARG
  13512.    %   ECHO Number of arguments is: @ArgCount( args )
  13513.    ENDM
  13514.  
  13515.  Another useful task might be to select an item from an argument list using
  13516.  an index to indicate which item. The following macro simplifies this.
  13517.  
  13518.    @ArgI MACRO index:REQ, arglist:VARARG
  13519.        LOCAL count, retstr
  13520.        retstr TEXTEQU <>            ;; Initialize count
  13521.        count  = 0                   ;; Initialize return string
  13522.        FOR arg, <arglist>
  13523.            count = count + 1
  13524.            IF count EQ index        ;; Item is found
  13525.                retstr TEXTEQU <arg> ;; Set return string
  13526.                EXITM                ;;  and exit IF
  13527.            ENDIF
  13528.        ENDM
  13529.        EXITM retstr                 ;; Exit function
  13530.    ENDM
  13531.  
  13532.  This function can be used as shown below:
  13533.  
  13534.    work    MACRO args:VARARG
  13535.    %   ECHO Third argument is: @ArgI( 3, args )
  13536.    ENDM
  13537.  
  13538.  Finally, you might need to process arguments in reverse order. The following
  13539.  macro returns a new argument list in reverse order.
  13540.  
  13541.    @ArgRev MACRO arglist:REQ
  13542.        LOCAL txt, arg
  13543.        txt TEXTEQU <>
  13544.    %   FOR arg, <arglist>
  13545.            txt CATSTR <arg>, <,>, txt      ;; Paste each onto list
  13546.        ENDM
  13547.                                            ;; Remove terminating comma
  13548.        txt SUBSTR  txt, 1, @SizeStr( %txt ) - 1
  13549.        txt CATSTR  <!<>, txt, <!>>         ;; Add angle brackets
  13550.        EXITM txt
  13551.    ENDM
  13552.  
  13553.  You could call this function as shown below:
  13554.  
  13555.    work    MACRO   args:VARARG
  13556.    %   FOR  arg, @ArgRev( <args> )   ;; Process in reverse order
  13557.            ECHO    arg
  13558.        ENDM
  13559.    ENDM
  13560.  
  13561.  These three macro functions are provided on the MASM distribution disk in
  13562.  the MACROS.INC include file.
  13563.  
  13564.  
  13565.  Macro Operators and Macro Functions
  13566.  
  13567.  This list summarizes the behavior of the expansion operator with macro
  13568.  functions.
  13569.  
  13570.  
  13571.    ■   If a macro function is not preceded by a %, it will be expanded.
  13572.        However, if it expands to a text macro or a macro function call, the
  13573.        result will not be expanded further.
  13574.  
  13575.    ■   If you use a macro function call as an argument for another macro
  13576.        function call, a % is not needed.
  13577.  
  13578.    ■   If a macro function expands to a text macro (or another macro
  13579.        function), the macro function will be recursively expanded.
  13580.  
  13581.    ■   If a macro function is called inside angle brackets and is preceded by
  13582.        %, it will be expanded.
  13583.  
  13584.  
  13585.  
  13586.  9.7  Advanced Macro Techniques
  13587.  
  13588.  The concept of replacing macro names with predefined macro text is simple in
  13589.  theory, but it has many implications and complications. Here is a brief
  13590.  summary of some advanced techniques you can use in macros.
  13591.  
  13592.  
  13593.  9.7.1  Nesting Macro Definitions
  13594.  
  13595.  Macros can define other macros or can be redefined. MASM does not process
  13596.  nested definitions until the outer macro has been called. Therefore, the
  13597.  inner macros cannot be called until the outer macro has been called. The
  13598.  nesting of macro definitions is limited only by memory.
  13599.  
  13600.    shifts  MACRO   opname                  ;; Macro generates macros
  13601.        opname&s    MACRO operand:REQ, rotates:=<1>
  13602.            IF rotates LE 2                 ;; One at a time is faster
  13603.                REPEAT rotate               ;;  for 2 or less
  13604.                    opname  operand, 1
  13605.                ENDM
  13606.            ELSE                            ;; Using CL is faster for
  13607.                mov     cl, rotates         ;;  more than 2
  13608.                opname  operand, cl
  13609.            ENDIF
  13610.        ENDM
  13611.    ENDM
  13612.  
  13613.    ; Call macro to make new macros
  13614.            shifts  ror                     ; Generates rors
  13615.            shifts  rol                     ; Generates rols
  13616.            shifts  shr                     ; Generates shrs
  13617.            shifts  shl                     ; Generates shls
  13618.            shifts  rcl                     ; Generates rcls
  13619.            shifts  rcr                     ; Generates rcrs
  13620.            shifts  sal                     ; Generates sals
  13621.            shifts  sar                     ; Generates sars
  13622.  
  13623.  This macro generates enhanced versions of the shift and rotate instructions.
  13624.  The macros could be called like this:
  13625.  
  13626.    shrs    ax, 5
  13627.            rols    bx, 3
  13628.  
  13629.  The macro versions handle multiple shifts by generating different code,
  13630.  depending on how many shifts are specified. The example above is optimized
  13631.  for the 8088 and 8086 processors. If you want to enhance for other
  13632.  processors, you can simply change the outer macro; it automatically changes
  13633.  all the inner macros. Code that uses the inner macros benefits from the
  13634.  enhancements but does not change so long as the macro interface doesn't
  13635.  change.
  13636.  
  13637.  
  13638.  9.7.2  Testing for Argument Type and Environment
  13639.  
  13640.  Macros can check the type of arguments and generate different code depending
  13641.  on what they find. For example, you can use the OPATTR operator to determine
  13642.  if an argument is a constant, a register, or a memory operand.
  13643.  
  13644.  If you discover a constant value, you can often optimize the code. In some
  13645.  cases, you can generate better code for 0 or 1 than for other constants. If
  13646.  the argument is a memory operand, you know nothing about the value of the
  13647.  operand, since it may change at run time. However, you may want to generate
  13648.  different code depending on the operand size and on whether it is a pointer.
  13649.  Similarly, if the operand is a register, you know nothing of its contents,
  13650.  but you may be able to optimize if you can identify a particular register
  13651.  with the IFDIFI or IFIDNI directives.
  13652.  
  13653.  The following example illustrates some of these techniques. It loads a
  13654.  specified address into a specified offset register. The segment register is
  13655.  assumed to be DS.
  13656.  
  13657.    load    MACRO reg:REQ, adr:REQ
  13658.        IF (OPATTR (adr)) AND 00010000y    ;; Register
  13659.            IFDIFI reg, adr                ;; Don't load register
  13660.                mov     reg, adr           ;;  onto itself
  13661.            ENDIF
  13662.        ELSEIF (OPATTR (adr)) AND 00000100y
  13663.            mov     reg, adr               ;; Constant
  13664.        ELSEIF (TYPE (adr) EQ BYTE) OR (TYPE (adr) EQ SBYTE)
  13665.            mov    reg, OFFSET adr         ;; Bytes
  13666.        ELSEIF (SIZE (TYPE (adr)) EQ 2
  13667.            mov    reg, adr                ;; Near pointer
  13668.        ELSEIF (SIZE (TYPE (adr)) EQ 4
  13669.            mov    reg, WORD PTR adr[0]    ;; Far pointer
  13670.            mov    ds,  WORD PTR adr[2]
  13671.        ELSE
  13672.            .ERR <Illegal argument>
  13673.        ENDIF
  13674.    ENDM
  13675.  
  13676.  A macro may also generate different code depending on the assembly
  13677.  environment. The predefined text macro @Cpu can be used to test for
  13678.  processor type. The following example uses the more efficient constant
  13679.  variation of the PUSH instruction if the processor is an 80186 or higher.
  13680.  
  13681.    IF  @Cpu AND 00000010y
  13682.        pushc  MACRO op             ;; 80186 or higher
  13683.            push op
  13684.        ENDM
  13685.    ELSE
  13686.        pushc  MACRO op             ;; 8088/8086
  13687.            mov  ax, op
  13688.            push ax
  13689.        ENDM
  13690.    ENDIF
  13691.  
  13692.  Note that the example generates a completely different macro for the two
  13693.  cases. This is more efficient than testing the processor inside the macro
  13694.  and conditionally generating different code. With this macro, the
  13695.  environment is checked only once; if the conditional were inside the macro
  13696.  it would be checked every time the macro is called.
  13697.  
  13698.  You can test the language and operating system using the @Interface text
  13699.  macro. The memory model can be tested with the @Model, @DataSize, or
  13700.  @CodeSize text macros.
  13701.  
  13702.  You can save the contexts inside macros with PUSHCONTEXT and POPCONTEXT. The
  13703.  options for these keywords are:
  13704.  
  13705.  Option            Description
  13706.  ────────────────────────────────────────────────────────────────────────────
  13707.  RADIX             Saves segment register information
  13708.  LIST              Saves listing and CREF information
  13709.  CPU               Saves current CPU and processor
  13710.  ALL               All of the above
  13711.  
  13712.  
  13713.  9.7.3  Using Recursive Macros
  13714.  
  13715.  Macros can call themselves. In previous versions of MASM, recursion is an
  13716.  important technique for handling variable arguments. With MASM 6.0, you can
  13717.  do this much more cleanly using the FOR directive and the VARARG attribute,
  13718.  as described in Section 9.4.3. However, recursion is still available and may
  13719.  be useful for some macros.
  13720.  
  13721.  
  13722.  9.8  Related Topics in Online Help
  13723.  
  13724.  In addition to information covered in this chapter, information on the
  13725.  following topics can be found in online help. From the "MASM 6.0 Contents"
  13726.  screen:
  13727.  
  13728. ╓┌─────────────────────────────────────┌─────────────────────────────────────╖
  13729.  Topics                                Access
  13730.  ────────────────────────────────────────────────────────────────────────────
  13731.  INCLUDE                               Choose "Directives," and then "Scope
  13732.                                        and
  13733.                                        Visibility"
  13734.  
  13735.  GOTO, PURGE                           Choose "Directives," and then
  13736.  Topics                                Access
  13737.  ────────────────────────────────────────────────────────────────────────────
  13738. GOTO, PURGE                           Choose "Directives," and then
  13739.                                        "Macros and Iterative Blocks"
  13740.  
  13741.  .LISTMACRO                            Choose "Directives," and then
  13742.                                        "Listing
  13743.                                        Control"
  13744.  
  13745.  IFB, IFNB, IFDIFI,                    Choose "Directives," and then
  13746.  and IFIDNI                            "Conditional Assembly"
  13747.  
  13748.  ECHO                                  Choose "Directives," and then
  13749.                                        "Miscellaneous"
  13750.  
  13751.  OPATTR                                Choose "Operators," and then
  13752.                                        "Miscellaneous"
  13753.  
  13754.  @Cpu, @Interface, @DataSize,          Choose "Predefined Symbols"
  13755.  @Environ, and @CodeSize
  13756.  
  13757.  Topics                                Access
  13758.  ────────────────────────────────────────────────────────────────────────────
  13759. 
  13760.  PUSHCONTEXT,                          Choose "Directives" and then
  13761.  POPCONTEXT                            "Iterative Blocks"
  13762.  
  13763.  
  13764.  
  13765.  
  13766.  
  13767.  
  13768.  
  13769.  
  13770.  Chapter 10  Managing Projects with NMAKE
  13771.  ────────────────────────────────────────────────────────────────────────────
  13772.  
  13773.  The Microsoft Program Maintenance Utility (NMAKE) is a sophisticated command
  13774.  processor that saves time and simplifies project management. Once you
  13775.  specify which project files depend on others, NMAKE automatically executes
  13776.  the commands needed to update your project when any project file has
  13777.  changed.
  13778.  
  13779.  The advantage of using NMAKE instead of simple batch files is that NMAKE
  13780.  recompiles only those files that need recompiling. NMAKE doesn't waste time
  13781.  with files that haven't changed since the last build. NMAKE also has
  13782.  advanced features (such as macros) that simplify managing complex projects.
  13783.  
  13784.  
  13785.  This chapter includes examples that show how each feature of NMAKE works. In
  13786.  addition, Section 10.9, "A Sample NMAKE Description File," shows how many of
  13787.  these features work together.
  13788.  
  13789.  If you are using the Microsoft Programmer's WorkBench (PWB) to build your
  13790.  project, PWB automatically creates a description file (called a "makefile"
  13791.  in the PWB documentation) and calls NMAKE to run the file. You may want to
  13792.  read this chapter if you intend to build your program outside of PWB or if
  13793.  you want to understand or modify a description file created by PWB.
  13794.  
  13795.  A utility called NMK allows you to use NMAKE to manage your project under
  13796.  DOS (or in a DOS session under OS/2). Section 10.11, "Using NMK," explains
  13797.  when and how to use NMK.
  13798.  
  13799.  If you are familiar with MAKE, the predecessor to NMAKE, be sure to read
  13800.  Section 10.10, "Differences between NMAKE and MAKE." These utilities differ
  13801.  in several important respects.
  13802.  
  13803.  
  13804.  10.1  Overview of NMAKE
  13805.  
  13806.  NMAKE works by looking at the last times and dates of modification for a
  13807.  "target" file and its "dependents" and then comparing them. A target is
  13808.  usually a file you want to create, such as an executable file. A dependent
  13809.  is usually a file from which a target is created, such as a source file. A
  13810.  target is "out-of-date" if any of its dependents has changed more recently
  13811.  than the target.
  13812.  
  13813.  ────────────────────────────────────────────────────────────────────────────
  13814.  WARNING
  13815.  
  13816.  For NMAKE to work properly, the date and time setting on your system must be
  13817.  consistent relative to previous settings. If you set the date and time each
  13818.  time you start the system, be careful to set it accurately. If your system
  13819.  stores a setting, be certain that the battery is working.
  13820.  ────────────────────────────────────────────────────────────────────────────
  13821.  
  13822.  When you run NMAKE, it reads a "description file" that you supply. The
  13823.  description file consists of one or more description blocks. Each
  13824.  description block typically lists a target, the target's dependents, and the
  13825.  commands that build the target. NMAKE compares the last time the targets
  13826.  changed to the last time the dependents changed. If the modification time of
  13827.  any dependents is the same or later than the time of the target, NMAKE
  13828.  updates the target by executing the command or commands listed in the
  13829.  description block.
  13830.  
  13831.  NMAKE's main purpose is to help you update applications quickly and simply.
  13832.  However, it can execute any DOS or OS/2 command, so it is not limited to
  13833.  compiling and linking. NMAKE can also make backups, move files, and perform
  13834.  other project-management tasks that you ordinarily do at the
  13835.  operating-system prompt.
  13836.  
  13837.  
  13838.  10.2  Running NMAKE
  13839.  
  13840.  You invoke NMAKE with the following syntax:
  13841.  
  13842.    NMAKE [[options]] [[macros]]
  13843.    [[targets]]
  13844.  
  13845.  The options field lists NMAKE options, which are described in Section 10.4,
  13846.  "Command-Line Options."
  13847.  
  13848.  The macros field lists macro definitions, which allow you to change text in
  13849.  the description file. The syntax for macros is described in "User-Defined
  13850.  Macros" in Section 10.3.4.1, "Macros."
  13851.  
  13852.  The targets field lists targets to build. NMAKE rebuilds only the targets
  13853.  listed on the command line. If you don't specify any targets, NMAKE builds
  13854.  only the first target in the description file. (This behavior departs
  13855.  significantly from that of MAKE. See Section 10.10, "Differences between
  13856.  NMAKE and MAKE.")
  13857.  
  13858.  NMAKE follows the instructions you specify in a description file.
  13859.  
  13860.  NMAKE searches the current directory for the name of a description file you
  13861.  specify with the /F option. It halts and displays an error message if the
  13862.  file does not exist. If you do not use the /F option to specify a
  13863.  description file, NMAKE searches the current directory for a description
  13864.  file named MAKEFILE. If MAKEFILE does not exist, NMAKE checks the command
  13865.  line for target files and tries to build them using predefined inference
  13866.  rules (either default or defined in TOOLS.INI). This feature lets you use
  13867.  NMAKE without a description file (as long as NMAKE has a predefined
  13868.  inference rule for the target). If the command line does not specify any
  13869.  target files, NMAKE halts and displays an error message.
  13870.  
  13871.  
  13872.  Example
  13873.  
  13874.    NMAKE /S "program=sample" sort.exe search.exe
  13875.  
  13876.  This command supplies four arguments: an option (/S), a macro definition
  13877.  ("program=sample"), and two target specifications (sort.exe  and
  13878.  search.exe).
  13879.  
  13880.  The command does not specify a description file, so NMAKE looks for the
  13881.  default description file, MAKEFILE. The /S option tells NMAKE not to display
  13882.  the commands as they are executed. (See Section 10.4, "Command-Line
  13883.  Options.") The macro definition performs a text substitution throughout the
  13884.  description file, replacing every instance of  program  with  sample. The
  13885.  target specifications tell NMAKE to update the targets SORT.EXE and
  13886.  SEARCH.EXE.
  13887.  
  13888.  
  13889.  10.3  NMAKE Description Files
  13890.  
  13891.  The most important parts of a description file are the description blocks,
  13892.  which tell NMAKE how to build your project's target files. A description
  13893.  file can also contain comments, macros, inference rules, and directives.
  13894.  This section describes the elements of description files.
  13895.  
  13896.  
  13897.  10.3.1  Description Blocks
  13898.  
  13899.  Description blocks form the heart of the description file. Figure 10.1
  13900.  illustrates a typical NMAKE description block, including the three sections:
  13901.  targets, dependents, and commands.
  13902.  
  13903.  (This figure may be found in the printed book.)
  13904.  
  13905.  
  13906.  10.3.1.1  Targets
  13907.  
  13908.  The target is the file that you want to build.
  13909.  
  13910.  The targets section of the dependency line lists one or more files to build.
  13911.  The line that lists targets and dependents is called the "dependency line."
  13912.  
  13913.  
  13914.  The example in Figure 10.1 tells NMAKE how to build a single target,
  13915.  MYAPP.EXE, if it is missing or out-of-date. Although single targets are
  13916.  common, you can also list multiple targets in a single dependency line; you
  13917.  must separate each target name with a space. If the name of the last target
  13918.  before the colon (:) is one character long, put a space between the name and
  13919.  the colon, so NMAKE won't interpret the character as a drive specification.
  13920.  
  13921.  
  13922.  A target can appear in only one dependency line when specified as shown
  13923.  above. To update a target using more than one description block, specify two
  13924.  consecutive colons (::) between targets and dependents. For details, see
  13925.  Section 10.3.1.8, "Specifying a Target in Multiple Description Blocks."
  13926.  
  13927.  The target is usually a file, but it can also be a "pseudotarget," a name
  13928.  that lets you build groups of files or execute a group of commands. For more
  13929.  information, see Section 10.3.2, "Pseudotargets."
  13930.  
  13931.  
  13932.  10.3.1.2  Dependents
  13933.  
  13934.  A dependent is a file used to build a target.
  13935.  
  13936.  The dependents section of the description block lists one or more files from
  13937.  which the target is built. A colon (:) separates it from the targets
  13938.  section. The example in Figure 10.1 lists three dependents after MYAPP.EXE:
  13939.  
  13940.  
  13941.    myapp.exe : myapp.obj another.obj myapp.def
  13942.  
  13943.  You can also specify the directories in which NMAKE should search for a
  13944.  dependent. Enclose one or more directory names in braces ( { } ). Separate
  13945.  multiple directories with a semicolon ( ; ). The syntax for a directory
  13946.  specification is
  13947.  
  13948.    {directory[[;directory...]]}dependent
  13949.  
  13950.  
  13951.  Example
  13952.  
  13953.  The following dependency line tells NMAKE to search the current directory
  13954.  first, then the specified directories:
  13955.  
  13956.    forward.exe : {\src\alpha;d:\proj}pass.obj
  13957.  
  13958.  In the line above, the target, FORWARD.EXE, has one dependent, PASS.OBJ. The
  13959.  directory list specifies two directories:
  13960.  
  13961.    {\src\alpha;d:\proj}
  13962.  
  13963.  NMAKE first searches for PASS.OBJ in the current directory. If PASS.OBJ
  13964.  isn't there, NMAKE searches the \ SRC \ ALPHA directory, then the D:\ PROJ
  13965.  directory. If NMAKE cannot find a dependent in the current directory or a
  13966.  listed directory, it looks for a description block with a dependency line
  13967.  containing PASS.OBJ as a target, and uses the commands in that description
  13968.  block to create PASS.OBJ. If NMAKE cannot find such a description block, it
  13969.  looks for an inference rule that describes how to create the dependent. (See
  13970.  Section 10.3.5, "Inference Rules.")
  13971.  
  13972.  
  13973.  10.3.1.3  Dependency Line
  13974.  
  13975.  The dependency line in Figure 10.1 tells NMAKE to rebuild the target
  13976.  MYAPP.EXE whenever MYAPP.OBJ, ANOTHER.OBJ, or MYAPP.DEF has changed more
  13977.  recently than MYAPP.EXE.
  13978.  
  13979.  The object files in the dependency list above would never be newer than the
  13980.  executable file (unless you had recompiled the source code before running
  13981.  NMAKE). So NMAKE checks to see if the object files themselves are targets in
  13982.  other dependency lists, and if any dependents in those lists are targets
  13983.  elsewhere, and so on.
  13984.  
  13985.  NMAKE continues moving through all dependencies this way to build a
  13986.  "dependency tree" that specifies all the steps required to fully update the
  13987.  target. If NMAKE then finds any dependents in the tree that are newer than
  13988.  the target, NMAKE updates the appropriate files and rebuilds the target.
  13989.  
  13990.  
  13991.  10.3.1.4  Commands
  13992.  
  13993.  The commands section can contain one or more commands.
  13994.  
  13995.  The commands section of the description block lists the commands that NMAKE
  13996.  should use to build the target. You can use any command that can be executed
  13997.  from the command line. The example in Figure 10.1 tells NMAKE to build
  13998.  MYAPP.EXE using the following LINK command:
  13999.  
  14000.        link myapp another.obj, , NUL, os2, myapp
  14001.  
  14002.  Notice that the line is indented. NMAKE uses indentation to distinguish
  14003.  between a dependency line and a command line. A command line must be
  14004.  indented at least one space or tab. The dependency line must not be indented
  14005.  (it cannot start with a space or tab).
  14006.  
  14007.  Many targets are built with a single command, but you can place more than
  14008.  one command after the dependency line, each on a separate line, as shown in
  14009.  Figure 10.1.
  14010.  
  14011.  A long command can span several lines if each line ends with a backslash ( \
  14012.  ). A backslash at the end of a line is equivalent to a space on the command
  14013.  line. For example, the command
  14014.  
  14015.    echo abcd\
  14016.    efgh
  14017.  
  14018.  is equivalent to the command
  14019.  
  14020.    echo abcd efgh
  14021.  
  14022.  You can also place a command at the end of a dependency line. Use a
  14023.  semicolon (;) to separate the command from the rightmost dependent, as in
  14024.  
  14025.    project.exe : project.obj ; link project;
  14026.  
  14027.  OS/2 allows multiple commands on one command line.
  14028.  
  14029.  OS/2 allows you to combine two or more commands on a single command line
  14030.  with an ampersand (&). For example, the following command line is legal in
  14031.  an OS/2 description file:
  14032.  
  14033.    DIR & COPY sample.exe backup.exe
  14034.  
  14035.  A slight restriction is imposed on the use of the CD, CHDIR, and SET
  14036.  commands in OS/2 description files. NMAKE executes these commands itself
  14037.  rather than passing them to OS/2. Therefore, if any of these commands is the
  14038.  first command on a line, the remaining commands are not executed because
  14039.  they aren't passed to OS/2.
  14040.  
  14041.  The following multiple-command line does not display the directory listing
  14042.  because DIR is preceded by a CD command:
  14043.  
  14044.        CD \mydir & DIR
  14045.  
  14046.  To use CD, CHDIR, or SET in a description block, place these commands on
  14047.  separate lines:
  14048.  
  14049.    CD \mydir
  14050.        DIR
  14051.  
  14052.  NMAKE interprets a percent symbol (%) within a command line as the start of
  14053.  a file specifier. To use a literal percent symbol in a command line, specify
  14054.  it as a double percent symbol (%%). (See Section 10.3.8, "Extracting
  14055.  Filename Components.")
  14056.  
  14057.  
  14058.  10.3.1.5  Wild Cards
  14059.  
  14060.  You can use DOS and OS/2 wild-card characters (* and ?) to specify target
  14061.  and dependent filenames. NMAKE expands the wild cards when analyzing
  14062.  dependencies and when building targets. For example, the following
  14063.  description block links all files having the .OBJ extension in the current
  14064.  directory:
  14065.  
  14066.    project.exe : *.obj
  14067.        LINK $*.obj;
  14068.  
  14069.  
  14070.  10.3.1.6  Command Modifiers
  14071.  
  14072.  Command modifiers are special prefixes attached to the command. They provide
  14073.  extra control over the commands in a description block. You can use more
  14074.  than one modifier for a single command. Table 10.1 describes the three NMAKE
  14075.  command modifiers.
  14076.  
  14077.  Table 10.1  Command Modifiers
  14078.  
  14079. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  14080.  Character                         Action
  14081.  ────────────────────────────────────────────────────────────────────────────
  14082.  @                            Prevents NMAKE from displaying the
  14083.                                    command as it executes. In the example
  14084.                                    below, the at sign (@) suppresses
  14085.                                    display of the ECHO command line:
  14086.  
  14087.                                    sort.exe : sort.obj
  14088.                                         @ECHO Now sorting.
  14089.  
  14090.                                    The output of the ECHO command is not
  14091.                                    suppressed.
  14092.  
  14093.  Character                         Action
  14094.  ────────────────────────────────────────────────────────────────────────────
  14095. 
  14096.  -«number»                         Turns off error checking for the command.
  14097.                                    Spaces and tabs can appear before the
  14098.                                    command. If the dash is followed by a
  14099.                                    number, NMAKE checks the exit code
  14100.                                    returned by the command and stops if the
  14101.                                    code is greater than the number. No
  14102.                                    space or tab can appear between the dash
  14103.                                    and number. (See Section 10.12, "Using
  14104.                                    Exit Codes with NMAKE.")
  14105.  
  14106.                                    In the following example, if the program
  14107.                                     sample  returns an exit code, NMAKE
  14108.                                    does not stop but continues to execute
  14109.                                    commands; if sort  returns an exit code
  14110.                                    greater than 5, NMAKE stops:
  14111.  
  14112.                                    light.lst : light.txt
  14113.                                      -sample light.txt
  14114.  Character                         Action
  14115.  ────────────────────────────────────────────────────────────────────────────
  14116.                                     -sample light.txt
  14117.                                       -5 sort light.txt
  14118.  
  14119.  !                                 Executes the command for each dependent
  14120.                                    file if the command preceded by the
  14121.                                    exclamation point uses the predefined
  14122.                                    macros $** or $?. (See Section 10.3.4,
  14123.                                    "Macros.") The $** macro refers to all
  14124.                                    dependent files in the description block.
  14125.                                    The $? macro refers to all dependent
  14126.                                    files in the description block that have
  14127.                                    a more recent modification time than the
  14128.                                    target. For example,
  14129.  
  14130.                                    print : one.txt two.txt three.txt
  14131.                                         !print $** lpt1:
  14132.  
  14133.                                    generates the following commands:
  14134.  
  14135.  Character                         Action
  14136.  ────────────────────────────────────────────────────────────────────────────
  14137. 
  14138.                                    print one.txt lpt1:
  14139.                                    print two.txt lpt1:
  14140.                                    print three.txt lpt1:
  14141.  
  14142.  ────────────────────────────────────────────────────────────────────────────
  14143.  
  14144.  
  14145.  
  14146.  
  14147.  10.3.1.7  Using Special Characters as Literals
  14148.  
  14149.  You may need to specify as a literal character one of the characters that
  14150.  NMAKE uses for a special purpose. These characters are
  14151.  
  14152.  : ; # ( ) $ ^ \ { } ! @  ─
  14153.  
  14154.  To use one of these characters literally, place a caret (^) in front of it.
  14155.  For example, suppose you define a macro that ends with a backslash:
  14156.  
  14157.    exepath=c:\bin\
  14158.  
  14159.  The line above is intended to define a macro named  exepath  with the value
  14160.  c:\bin\. But the second backslash has an unintended side effect. Since the
  14161.  backslash is NMAKE's line-continuation character, the line actually defines
  14162.  exepath  as  c:\bin, followed by whatever appears on the next line of the
  14163.  description file. You can avoid this problem by placing a caret in front of
  14164.  the second backslash:
  14165.  
  14166.    exepath=c:\bin^\
  14167.  
  14168.  You can also use a caret to insert a literal newline character in a string
  14169.  or macro:
  14170.  
  14171.    XYZ=abc^
  14172.    def
  14173.  
  14174.  The caret tells NMAKE to interpret the newline character as part of the
  14175.  macro, not a line break. Note that this effect differs from using a
  14176.  backslash ( \ ) to continue a line. A newline character that follows a
  14177.  backslash is replaced with a space.
  14178.  
  14179.  NMAKE ignores carets that precede characters other than the special
  14180.  characters listed above. The line
  14181.  
  14182.    ign^ore : these ca^rets
  14183.  
  14184.  is interpreted as
  14185.  
  14186.    ignore : these carets
  14187.  
  14188.  A caret within a quoted string is treated as a literal caret character.
  14189.  
  14190.  
  14191.  10.3.1.8  Specifying a Target in Multiple Description Blocks
  14192.  
  14193.  You can specify a target in more than one description block by placing two
  14194.  colons (::) after the target. This feature is useful for building a complex
  14195.  target, such as a library, that contains components created with different
  14196.  commands. For example,
  14197.  
  14198.    target.lib :: a.asm b.asm c.asm
  14199.        ML a.asm b.asm c.asm
  14200.        LIB target -+a.obj -+b.obj -+c.obj;
  14201.    target.lib :: d.c e.c
  14202.        CL /c d.c e.c
  14203.        LIB target -+d.obj -+e.obj;
  14204.  
  14205.  Both description blocks update the library named TARGET.LIB. If any of the
  14206.  assembly-language files have changed more recently than the library, NMAKE
  14207.  executes the commands in the first block to assemble the source files and
  14208.  update the library. Similarly, if any of the C-language files have changed,
  14209.  NMAKE executes the second group of commands to compile the C files and
  14210.  update the library.
  14211.  
  14212.  If you use a single colon in the example above, NMAKE issues an error
  14213.  message. It is legal, however, to use single colons if the target appears in
  14214.  only one block. In this case, dependency lines are cumulative. For example,
  14215.  
  14216.  
  14217.    target : jump.bas
  14218.    target : up.c
  14219.        echo Building target...
  14220.  
  14221.  is equivalent to
  14222.  
  14223.    target : jump.bas up.c
  14224.        echo Building target...
  14225.  
  14226.  No commands can appear between cumulative dependency lines, but blank lines,
  14227.  comment lines, macro definitions, and directives can appear.
  14228.  
  14229.  
  14230.  10.3.2  Pseudotargets
  14231.  
  14232.  A "pseudotarget" is similar to a target, but it is not a file. It is a name
  14233.  used as a label for executing a group of commands. In the following example,
  14234.   UPDATE  is a pseudotarget.
  14235.  
  14236.    UPDATE : *.*
  14237.        !COPY $** a:\product
  14238.  
  14239.  NMAKE always considers the pseudotarget to be out-of-date. In the previous
  14240.  example, NMAKE copies all the dependent files to the specified drive and
  14241.  directory.
  14242.  
  14243.  Like target names, pseudotarget names are not case sensitive.
  14244.  
  14245.  
  14246.  10.3.3  Comments
  14247.  
  14248.  You can place comments in a description file by preceding them with a number
  14249.  sign (#):
  14250.  
  14251.    # Comment on line by itself
  14252.    OPTIONS = /MAP  # Comment on macro's line
  14253.    all.exe : one.obj two.obj  # Comment on dependency line
  14254.        link $(OPTIONS) one.obj two.obj;
  14255.  
  14256.  A comment extends to the end of the line in which it appears. Command lines
  14257.  (and dependency lines containing commands) cannot contain comments.
  14258.  
  14259.  To specify a literal #, precede it with a caret (^ ), as in the following:
  14260.  
  14261.    DEF=^#define #Macro representing a C preprocessing directive
  14262.  
  14263.  
  14264.  10.3.4  Macros
  14265.  
  14266.  Macros offer a convenient way to replace a particular string in the
  14267.  description file with another string. Macros are useful for a variety of
  14268.  tasks, including the following:
  14269.  
  14270.  
  14271.    ■   Creating a single description file that works for several projects.
  14272.        You can define a macro that replaces a dummy filename in the
  14273.        description file with the specific filename for a particular project.
  14274.  
  14275.    ■   Controlling the options NMAKE passes to the compiler or linker. When
  14276.        you specify options in a macro, you can change options throughout the
  14277.        description file in a single step.
  14278.  
  14279.  
  14280.  You can define your own macros or use predefined macros. This section
  14281.  describes user-defined macros first.
  14282.  
  14283.  
  14284.  10.3.4.1  User-Defined Macros
  14285.  
  14286.  You can define a macro with this syntax:
  14287.  
  14288.    macroname=string
  14289.  
  14290.  The macroname can be any combination of letters, digits, and the underscore
  14291.  ( _ ) character. Macro names are case sensitive. NMAKE interprets  MyMacro
  14292.  and  MYMACRO  as different macro names.
  14293.  
  14294.  The string can be any sequence of zero or more characters. (A string of zero
  14295.  characters is called a "null string." A string consisting only of spaces,
  14296.  tabs, or both is also considered a null string.) For example,
  14297.  
  14298.    linkcmd=LINK /map
  14299.  
  14300.  defines a macro named  linkcmd  and assigns it the string  LINK /map.
  14301.  
  14302.  You can define macros in the description file, on the command line, in a
  14303.  command file (see Section 10.5, "NMAKE Command File"), or in TOOLS.INI (see
  14304.  Section 10.6, "The TOOLS.INI File"). Each macro defined in the description
  14305.  file must appear on a separate line. The line cannot start with a space or
  14306.  tab.
  14307.  
  14308.  When you define a macro in the description file, NMAKE ignores spaces on
  14309.  either side of the equal sign. The string itself can contain embedded
  14310.  spaces. You do not need to enclose string in quotation marks (if you do,
  14311.  they become part of the string).
  14312.  
  14313.  Slightly different rules apply when you define a macro on the command line
  14314.  or in a command file. The command-line parser treats spaces as argument
  14315.  delimiters. Therefore, the string itself, or the entire macro, must be
  14316.  enclosed in double quotation marks if it contains embedded spaces. All three
  14317.  forms of the following command-line macro are legal and equivalent:
  14318.  
  14319.    NMAKE program=sample
  14320.    NMAKE "program=sample"
  14321.    NMAKE "program = sample"
  14322.  
  14323.  The macro  program  is passed to NMAKE, with an assigned value of  sample.
  14324.  
  14325.  If the string contains spaces, either the string or the entire macro must
  14326.  appear within quotes. Either form of the following command-line macro is
  14327.  allowed:
  14328.  
  14329.    NMAKE linkcmd="LINK /map"
  14330.    NMAKE "linkcmd=LINK /map"
  14331.  
  14332.  However, the following form of the same macro is not allowed. It contains
  14333.  spaces that are not enclosed by quotation marks:
  14334.  
  14335.    NMAKE linkcmd = "LINK /map"
  14336.  
  14337.  A macro name can be given a null value. Both of the following definitions
  14338.  assign a null value to the macro  linkoptions:
  14339.  
  14340.    NMAKE linkoptions=
  14341.    NMAKE linkoptions="    "
  14342.  
  14343.  A macro name can be "undefined" with the !UNDEF preprocessing directive (see
  14344.  Section 10.3.7, "Preprocessing Directives"). Assigning a null value to a
  14345.  macro name does not undefine it; the name is still defined, but with a null
  14346.  value.
  14347.  
  14348.  A macro can be followed by a comment, using the syntax described in the
  14349.  preceding section on comments.
  14350.  
  14351.  
  14352.  10.3.4.2  Using Macros
  14353.  
  14354.  Use a macro by enclosing its name in parentheses preceded by a dollar sign
  14355.  ($). For example, you can use the  linkcmd  macro defined above by
  14356.  specifying
  14357.  
  14358.    $(linkcmd)
  14359.  
  14360.  NMAKE replaces every occurrence of  $(linkcmd)  with  LINK /map.
  14361.  
  14362.  The following description file defines and uses three macros:
  14363.  
  14364.    program=sample
  14365.    L=LINK
  14366.    options=
  14367.  
  14368.    $(program).exe : $(program).obj
  14369.        $(L)  $(options)  $(program).obj;
  14370.  
  14371.  NMAKE interprets the description block as
  14372.  
  14373.    sample.exe : sample.obj
  14374.        LINK sample.obj;
  14375.  
  14376.  NMAKE replaces every occurrence of  $(program)  with  sample, every instance
  14377.  of  $(L)  with  LINK, and every instance of  $(options)  with a null string.
  14378.  
  14379.  
  14380.  An undefined macro is replaced by a null string.
  14381.  
  14382.  If you use as a macro a name that has never been defined, or was undefined,
  14383.  NMAKE treats that name as a null string. No error occurs.
  14384.  
  14385.  To use the dollar sign ($) as a literal character, specify two dollar signs
  14386.  ($$).
  14387.  
  14388.  The parentheses are optional if macroname is a single character. For
  14389.  example,  $L  is equivalent to  $(L). However, parentheses are recommended
  14390.  for consistency.
  14391.  
  14392.  
  14393.  10.3.4.3  Special Macros
  14394.  
  14395.  NMAKE provides several special macros to represent various filenames and
  14396.  commands. One use for these macros is in predefined inference rules. (See
  14397.  Section 10.3.5.4.) Like user-defined macro names, special macro names are
  14398.  case sensitive. For example, NMAKE interprets  CC  and  cc  as different
  14399.  macro names.
  14400.  
  14401.  Tables 10.2 through 10.5 summarize the four categories of special macros.
  14402.  The filename macros offer a convenient representation of filenames from a
  14403.  dependency line; these are listed in Table 10.2. The recursion macros,
  14404.  listed in Table 10.3, allow you to call NMAKE from within your description
  14405.  file. Tables 10.4 and 10.5 describe the command macros and options macros
  14406.  that make it convenient for you to invoke the Microsoft language compilers.
  14407.  
  14408.  
  14409.  The filename macros conveniently represent filenames from the dependency
  14410.  line.
  14411.  
  14412.  Table 10.2 lists macros that are predefined to represent file names. As with
  14413.  all one-character macros, these do not need to be enclosed in parentheses.
  14414.  (The $$@ and $** macros are exceptions to the parentheses rule for macros;
  14415.  they do not require parentheses even though they contain two characters.)
  14416.  Note that the macros in Table 10.2 represent filenames as you have specified
  14417.  them in the dependency line, and not the full specification of the filename.
  14418.  
  14419.  
  14420.  Table 10.2  Filename Macros
  14421.  
  14422. ╓┌────────────────┌──────────────────────────────────────────────────────────╖
  14423.  Macro
  14424.  Reference        Meaning
  14425.  ────────────────────────────────────────────────────────────────────────────
  14426.  $@          The current target's full name, as currently specified.
  14427.                   This is not necessarily the full path name.
  14428.  
  14429.  Macro
  14430.  Reference        Meaning
  14431.  ────────────────────────────────────────────────────────────────────────────
  14432. 
  14433.  $*               The current target's full name minus the file extension.
  14434.  
  14435.  $**              The dependents of the current target.
  14436.  
  14437.  $?               The dependents that have a more recent modification time
  14438.                   than the current target.
  14439.  
  14440.  $$@         The target that NMAKE is currently evaluating. You can
  14441.                   use this macro only to specify a dependent.
  14442.  
  14443.  $<               The dependent file that has a more recent modification
  14444.                   time than the current target (evaluated only for
  14445.                   inference rules).
  14446.  
  14447.  ────────────────────────────────────────────────────────────────────────────
  14448.  
  14449.  
  14450.  
  14451.  The example below uses the $? macro, which represents all dependents that
  14452.  are more recent than the target. The ! command modifier causes NMAKE to
  14453.  execute a command once for each dependent in the list (see Table 10.1). As a
  14454.  result, the LIB command is executed up to three times, each time replacing a
  14455.  module with a newer version.
  14456.  
  14457.    trig.lib : sin.obj cos.obj arctan.obj
  14458.        !LIB trig.lib -+$?;
  14459.  
  14460.  In the next example, NMAKE updates files in another directory by replacing
  14461.  them with files of the same name from the current directory. The $@ macro is
  14462.  used to represent the current target's full name:
  14463.  
  14464.    #Files in objects directory depend on versions in current directory
  14465.    DIR=c:\objects
  14466.    $(DIR)\globals.obj : globals.obj
  14467.        COPY globals.obj $@
  14468.    $(DIR)\types.obj : types.obj
  14469.        COPY types.obj $@
  14470.    $(DIR)\macros.obj : macros.obj
  14471.        COPY macros.obj $@
  14472.  
  14473.  Macro modifiers specify parts of the predefined filename macros.
  14474.  
  14475.  You can append one of the modifiers in the following list to any of the
  14476.  filename macros to extract part of a filename. If you add one of these
  14477.  modifiers to the macro, you must enclose the macro name and the modifier in
  14478.  parentheses.
  14479.  
  14480.  Modifier                          Resulting Filename Part
  14481.  ────────────────────────────────────────────────────────────────────────────
  14482.  D                                 Drive plus directory
  14483.  
  14484.  B                                 Base name
  14485.  
  14486.  F                                 Base name plus extension
  14487.  
  14488.  R                                 Drive plus directory plus base name
  14489.  
  14490.  For example, assume that $@ has the value C:\SOURCE\PROG\SORT.OBJ. The
  14491.  following list shows the effect of combining each modifier with $@:
  14492.  
  14493.  Macro Reference                   Value
  14494.  ────────────────────────────────────────────────────────────────────────────
  14495.  $(@D)                             C:\SOURCE\PROG
  14496.  
  14497.  $(@F)                             SORT.OBJ
  14498.  
  14499.  $(@B)                             SORT
  14500.  
  14501.  $(@R)                             C:\SOURCE\PROG\SORT
  14502.  
  14503.  If $@ has the value SORT.OBJ without a preceding directory, the value of
  14504.  $(@R) is just SORT, and the value of $(@D) is a dot (.) to represent the
  14505.  current directory.
  14506.  
  14507.  Recursion macros let you use NMAKE to call NMAKE.
  14508.  
  14509.  Table 10.3 lists three macros that you can use when you want to call NMAKE
  14510.  recursively from within a description file.
  14511.  
  14512.  Table 10.3  Recursion Macros
  14513.  
  14514.  Macro
  14515.  Reference        Meaning
  14516.  ────────────────────────────────────────────────────────────────────────────
  14517.  $(MAKE)          The name used to call NMAKE recursively. The line on
  14518.                   which it appears is executed even if the /N command-line
  14519.                   option is specified.
  14520.  
  14521.  $(MAKEDIR)       The directory from which NMAKE is called.
  14522.  
  14523.  $(MAKEFLAGS)     The NMAKE options currently in effect. This macro is
  14524.                   passed automatically when you call NMAKE recursively. You
  14525.                   cannot redefine this macro. Use the preprocessing
  14526.                   directive !CMDSWITCHES to update the MAKEFLAGS macro.
  14527.                   (See Section 10.3.7, "Preprocessing Directives.")
  14528.  
  14529.  ────────────────────────────────────────────────────────────────────────────
  14530.  
  14531.  
  14532.  To call NMAKE recursively, use the command
  14533.  
  14534.    $(MAKE) /$(MAKEFLAGS)
  14535.  
  14536.  The MAKE macro is useful for building different versions of a program. The
  14537.  following description file calls NMAKE recursively to build targets in the
  14538.  \VERS1 and \VERS2 directories.
  14539.  
  14540.    all : vers1 vers2
  14541.  
  14542.    vers1 :
  14543.        cd \vers1
  14544.        $(MAKE)
  14545.        cd ..
  14546.  
  14547.    vers2 :
  14548.        cd \vers2
  14549.        $(MAKE)
  14550.        cd ..
  14551.  
  14552.  The example changes to the \VERS1 directory and then calls NMAKE
  14553.  recursively, causing NMAKE to process the file MAKEFILE in that directory.
  14554.  Then it changes to the \VERS2 directory and calls NMAKE again, processing
  14555.  the file MAKEFILE in that directory.
  14556.  
  14557.  You can add options to the ones already in effect for NMAKE by following the
  14558.  MAKE macro with the options in the same syntax as you would specify them on
  14559.  the command line. You can also pass the name of a description file with the
  14560.  /F option instead of using a file named MAKEFILE.
  14561.  
  14562.  Deeply recursive build procedures can exhaust NMAKE's run-time stack,
  14563.  causing an error. If this occurs, use the EXEHDR utility to increase NMAKE's
  14564.  run-time stack. The following command, for example, gives NMAKE.EXE a stack
  14565.  size of 16,384 (0x4000) bytes:
  14566.  
  14567.    exehdr /stack:0x4000 nmake.exe
  14568.  
  14569.  Command macros are shortcut calls to Microsoft compilers.
  14570.  
  14571.  NMAKE defines several macros to represent commands for Microsoft products.
  14572.  (See Table 10.4.) You can use these macros as commands in a description
  14573.  block, or invoke them using a predefined inference rule. (See Section
  14574.  10.3.5, "Inference Rules.") You can redefine these macros to represent part
  14575.  or all of a command line, including options.
  14576.  
  14577.  Table 10.4  Command Macros
  14578.  
  14579. ╓┌────────────────┌─────────────────────────────────────────┌────────────────
  14580.  Macro Reference  Command Action                            Predefined Value
  14581.  ─────────────────────────────────────────────────────────────────────────────
  14582.  $(AS)            Invokes the Microsoft Macro               AS=ml
  14583.                   Assembler
  14584.  
  14585.  $(BC)            Invokes the Microsoft Basic               BC=bc
  14586.                   Compiler
  14587.  
  14588.  $(CC)            Invokes the Microsoft C Compiler          CC=cl
  14589.  
  14590.  $(COBOL)         Invokes the Microsoft COBOL Compiler      COBOL=cobol
  14591.  
  14592.  $(FOR)           Invokes the Microsoft FORTRAN             FOR=fl
  14593.                   Compiler
  14594.  
  14595.  $(PASCAL)        Invokes the Microsoft Pascal              PASCAL=pl
  14596.                   Compiler
  14597.  Macro Reference  Command Action                            Predefined Value
  14598.  ─────────────────────────────────────────────────────────────────────────────
  14599.                  Compiler
  14600.  
  14601.  $(RC)            Invokes the Microsoft Resource Compiler   RC=rc
  14602.  
  14603.  ─────────────────────────────────────────────────────────────────────────────
  14604.  
  14605.  
  14606.  
  14607.  Options macros pass preset options to Microsoft compilers.
  14608.  
  14609.  The macros in Table 10.5 are used by NMAKE to represent options to be passed
  14610.  to the commands for Microsoft languages. By default, these macros are
  14611.  undefined. You can define them to mean the options you want to pass to the
  14612.  commands. Whether or not they are defined, the macros are used automatically
  14613.  in the predefined inference rules. If the macros are undefined, or if they
  14614.  are defined to be null strings, a null string is generated in the command
  14615.  line. (See Section 10.3.5.4, "Predefined Inference Rules.")
  14616.  
  14617.  Table 10.5  Options Macros
  14618.  
  14619. ╓┌─────────────────────────┌─────────────────────────────────────────────────╖
  14620.  Macro Reference           Passed to
  14621.  ────────────────────────────────────────────────────────────────────────────
  14622.  $(AFLAGS)                 Microsoft Macro Assembler
  14623.  $(BFLAGS)                 Microsoft Basic Compiler
  14624.  $(CFLAGS)                 Microsoft C Compiler
  14625.  $(COBFLAGS)               Microsoft COBOL Compiler
  14626.  $(FFLAGS)                 Microsoft FORTRAN Compiler
  14627.  $(PFLAGS)                 Microsoft Pascal Compiler
  14628.  $(RFLAGS)                 Microsoft Resource Compiler
  14629.  ────────────────────────────────────────────────────────────────────────────
  14630.  
  14631.  
  14632.  
  14633.  10.3.4.4  Substitution within Macros
  14634.  
  14635.  You can replace text in a macro as well as in the description file.
  14636.  
  14637.  Just as macros allow you to substitute text in a description file, you can
  14638.  also substitute text within a macro itself. The substitution is temporary;
  14639.  it applies only to the current use of the macro and does not modify the
  14640.  original macro definition. Use the following form:
  14641.  
  14642.    $(macroname:string1=string2)
  14643.  
  14644.  Every occurrence of string1 is replaced by string2 in the macro macroname.
  14645.  Do not put any spaces or tabs between macroname and the colon. Spaces
  14646.  between the colon and string1 or between string1 and the equal sign are part
  14647.  of string1. Spaces between the equal sign and string2 or between string2 and
  14648.  the right parenthesis are part of string2. If string2 is a null string, all
  14649.  occurrences of string1 are deleted from the macroname macro.
  14650.  
  14651.  Macro substitution is case sensitive. This means that the case as well as
  14652.  the characters in string1 must exactly match the target string in the macro,
  14653.  or the substitution is not performed. It also means that the string2
  14654.  substitution is exactly as specified.
  14655.  
  14656.  
  14657.  Example 1
  14658.  
  14659.  The following description file illustrates macro substitution:
  14660.  
  14661.    SOURCES = project.for one.for two.for
  14662.  
  14663.    project.exe : $(SOURCES:.for=.obj)
  14664.        LINK  $**;
  14665.  
  14666.    COPY : $(SOURCES)
  14667.        !COPY $** c:\backup
  14668.  
  14669.  The predefined macro $** stands for the names of all the dependent files
  14670.  (see Table 10.2).
  14671.  
  14672.  If you invoke the example file with a command line that specifies both
  14673.  targets,
  14674.  
  14675.    NMAKE project.exe copy
  14676.  
  14677.  NMAKE executes the following commands:
  14678.  
  14679.    LINK project.obj one.obj two.obj;
  14680.    COPY project.for c:\backup
  14681.    COPY one.for c:\backup
  14682.    COPY two.for c:\backup
  14683.  
  14684.  The macro substitution does not alter the  SOURCES  macro definition.
  14685.  Rather, it replaces the listed characters. When NMAKE builds the target
  14686.  PROJECT.EXE, it gets the definition for the predefined macro $** (the
  14687.  dependent list) from the dependency line, which specifies the macro
  14688.  substitution in  SOURCES.
  14689.  
  14690.  The same is true for the second target,  COPY. In this case, however, no
  14691.  macro substitution is requested, so  SOURCES  retains its original value,
  14692.  and $** represents the names of the FORTRAN source files. (In the example
  14693.  above, the target  COPY  is a pseudotarget; Section 10.3.2 describes
  14694.  pseudotargets.)
  14695.  
  14696.  
  14697.  Example 2
  14698.  
  14699.  If the macro OBJS is defined as
  14700.  
  14701.    OBJS=ONE.OBJ TWO.OBJ THREE.OBJ
  14702.  
  14703.  with exactly one space between each object name, you can replace each space
  14704.  in the defined value of OBJS with a space, followed by a plus sign, followed
  14705.  by a newline, by using
  14706.  
  14707.    $(OBJS: = +^
  14708.    )
  14709.  
  14710.  The caret (^) tells NMAKE to treat the end of the line as a literal newline
  14711.  character. This example is useful for creating response files.
  14712.  
  14713.  
  14714.  10.3.4.5  Substitution within Predefined Macros
  14715.  
  14716.  You can also substitute text in any predefined macro except $$@. The
  14717.  principle is the same as for other macros. The command in the following
  14718.  description block substitutes within a predefined macro. Note that even
  14719.  though $@ is a singlecharacter macro, the substitution makes it a
  14720.  multi-character macro invocation, so it must be enclosed in parentheses.
  14721.  
  14722.    target.abc : depend.xyz
  14723.        echo $(@:targ=blank)
  14724.  
  14725.  If dependent  depend.xyz  has a later modification time than target
  14726.  target.abc, then NMAKE executes the command
  14727.  
  14728.    echo blanket.abc
  14729.  
  14730.  The example uses the predefined macro $@, which equals the full name of the
  14731.  current target (target.abc). It substitutes  blank  for  targ  in the
  14732.  target, resulting in  blanket.abc.
  14733.  
  14734.  
  14735.  10.3.4.6  Inherited Macros
  14736.  
  14737.  When NMAKE executes, it inherits macro definitions equivalent to every
  14738.  environment variable. The inherited macro names are converted to uppercase.
  14739.  
  14740.  
  14741.  Inherited macros can be used like other macros. You can also redefine them.
  14742.  The following example redefines the inherited macro  PATH:
  14743.  
  14744.    PATH = c:\tools\bin
  14745.  
  14746.    sample.exe : sample.obj
  14747.        LINK sample;
  14748.  
  14749.  Inherited macros take their definitions from environment variables.
  14750.  
  14751.  No matter what value the environment variable PATH had before, it has the
  14752.  value  c:\tools\bin  when NMAKE executes the LINK command in this
  14753.  description block. Redefining the inherited macro does not affect the
  14754.  original environment variable; when NMAKE terminates, PATH still has its
  14755.  original value.
  14756.  
  14757.  Inherited macros have one restriction: in a recursive call to NMAKE, the
  14758.  only macros that are preserved are those defined on the command line or in
  14759.  environment variables. Macros defined in the description file are not
  14760.  inherited when NMAKE is called recursively. To pass a macro to a recursive
  14761.  call:
  14762.  
  14763.  
  14764.    ■   Use the SET command before the recursive call to set the variable for
  14765.        the entire NMAKE session.
  14766.  
  14767.    ■   Define the macro on the command line for the recursive call.
  14768.  
  14769.  
  14770.  The /E option causes macros inherited from environment variables to override
  14771.  any macros with the same name in the description file.
  14772.  
  14773.  
  14774.  10.3.4.7  Precedence among Macro Definitions
  14775.  
  14776.  If you define the same macro name in more than one place, NMAKE uses the
  14777.  macro with the highest precedence. The precedence from highest to lowest is
  14778.  as follows:
  14779.  
  14780.  
  14781.    1.  A macro defined on the command line
  14782.  
  14783.    2.  A macro defined in a description file or include file
  14784.  
  14785.    3.  An inherited environment-variable macro
  14786.  
  14787.    4.  A macro defined in the TOOLS.INI file
  14788.  
  14789.    5.  A predefined macro such as CC and AS
  14790.  
  14791.  
  14792.  
  14793.  10.3.5  Inference Rules
  14794.  
  14795.  Inference rules are templates that define how a file with one extension is
  14796.  created from a file with a different extension. When NMAKE encounters a
  14797.  description block that has no commands, it searches for an inference rule
  14798.  that matches the extensions of the target and dependent files. Similarly, if
  14799.  a dependent file doesn't exist, NMAKE looks for an inference rule that shows
  14800.  how to create the missing dependent from another file with the same base
  14801.  name.
  14802.  
  14803.  Inference rules tell NMAKE how to create files with a specific extension.
  14804.  
  14805.  Inference rules provide a convenient shorthand for common operations. For
  14806.  instance, you can use an inference rule to avoid repeating the same command
  14807.  in several description blocks. You can define your own inference rules or
  14808.  use predefined inference rules.
  14809.  
  14810.  ────────────────────────────────────────────────────────────────────────────
  14811.  NOTE
  14812.  An inference rule is useful only when a target and dependent have the same
  14813.  base name, and have a one-to-one correspondence. For example, you cannot
  14814.  define an inference rule that replaces several modules in a library, because
  14815.  the modules would have different base names than the target library.
  14816.  ────────────────────────────────────────────────────────────────────────────
  14817.  
  14818.  Inference rules can exist only for dependents with extensions that are
  14819.  listed in the .SUFFIXES directive. (For information on the .SUFFIXES
  14820.  directive, see Section 10.3.6, "Directives.") NMAKE searches in the current
  14821.  or specified directory for a file whose base name matches the target and
  14822.  whose extension is listed in the .SUFFIXES list. If it finds such a file, it
  14823.  applies the inference rule that matches the extensions of the target and the
  14824.  located file.
  14825.  
  14826.  The .SUFFIXES list specifies an order of priority for NMAKE to use when
  14827.  searching for files. If more than one file is found, and thus more than one
  14828.  rule matches a dependency line, NMAKE searches the .SUFFIXES list and uses
  14829.  the rule whose extension appears earlier in the list. For example, the
  14830.  dependency line
  14831.  
  14832.    project.exe :
  14833.  
  14834.  can be matched to several predefined inference rules and possibly one or
  14835.  more user-defined rules, all of which describe a command for creating an
  14836.  .EXE file. NMAKE uses the inference rule corresponding to the first matching
  14837.  file it finds.
  14838.  
  14839.  
  14840.  10.3.5.1  Inference Rule Syntax
  14841.  
  14842.  An inference rule has the following syntax:
  14843.  
  14844.    .fromext.toext:
  14845.       commands
  14846.  
  14847.  The first line lists two extensions: fromext extension represents the
  14848.  filename extension of a dependent file, and toext represents the extension
  14849.  of a target file. Extensions are not case sensitive.
  14850.  
  14851.  The second line of the inference rule gives the command to create a target
  14852.  file of toext from a dependent file of fromext. Use the same rules for
  14853.  commands in inference rules as in description blocks. (See Section 10.3.1,
  14854.  "Description Blocks.")
  14855.  
  14856.  
  14857.  10.3.5.2  Inference Rule Search Paths
  14858.  
  14859.  The inference-rule syntax described above tells NMAKE to look for the
  14860.  specified files in the current directory. You can also specify directories
  14861.  to be searched by NMAKE when it looks for files with the extensions fromext
  14862.  and toext. An inference rule that specifies paths has the following syntax:
  14863.  
  14864.  
  14865.    {frompath}.fromext {topath}.toext:
  14866.        commands
  14867.  
  14868.  NMAKE searches in the frompath directory for files with the fromext
  14869.  extension. It uses commands to create files with the toext extension in the
  14870.  topath directory, if the fromext file has a later modification time than the
  14871.  toext file.
  14872.  
  14873.  The paths in the inference rule must exactly match the paths explicitly
  14874.  specified in the dependency line of a description block.
  14875.  
  14876.  If you use a path on one element of the inference rule, you must use paths
  14877.  on both. You can specify the current directory for either element by using
  14878.  the operating system notation for the current directory, which is a dot (.),
  14879.  or by specifying an empty pair of braces.
  14880.  
  14881.  You can specify only one path for each element in an inference rule. To
  14882.  specify more than one path, repeat the inference rule with the alternate
  14883.  path.
  14884.  
  14885.  
  14886.  10.3.5.3  User-Defined Inference Rules
  14887.  
  14888.  You can define inference rules in the description file or in TOOLS.INI (see
  14889.  Section 10.6, "The TOOLS.INI File"). An inference rule lists two file
  14890.  extensions and one or more commands.
  14891.  
  14892.  
  14893.  Example 1
  14894.  
  14895.  The following inference rule tells NMAKE how to build a .OBJ file from a .C
  14896.  file:
  14897.  
  14898.    .c.obj:
  14899.        CL /c $<
  14900.  
  14901.  In this example, the predefined macro $< represents the name of a dependent
  14902.  that has a more recent modification time than the target.
  14903.  
  14904.  NMAKE applies this inference rule to the following description block:
  14905.  
  14906.    sample.obj :
  14907.  
  14908.  The description block lists only a target, SAMPLE.OBJ. Both the dependent
  14909.  and the command are missing. However, given the target's base name and
  14910.  extension, plus the inference rule, NMAKE has enough information to build
  14911.  the target.
  14912.  
  14913.  NMAKE first looks for a file with the same base name as the target and with
  14914.  one of the extensions in the .SUFFIXES list. If SAMPLE.C exists (and no
  14915.  files with higher-priority extensions exist), NMAKE compares its time to
  14916.  that of SAMPLE.OBJ. If SAMPLE.C has changed more recently, NMAKE compiles it
  14917.  using the CL command listed in the inference rule:
  14918.  
  14919.    CL /c sample.c
  14920.  
  14921.  
  14922.  Example 2
  14923.  
  14924.  The following inference rule compares a .C file in the current directory
  14925.  with the corresponding .OBJ file in another directory:
  14926.  
  14927.    {.}.c{c:\objects}.obj:
  14928.        cl /c $<;
  14929.  
  14930.  The path for the .C file is represented by a dot. A path for the dependent
  14931.  extension is required because one is specified for the target extension.
  14932.  
  14933.  This inference rule matches a dependency line containing the same
  14934.  combination of paths, such as:
  14935.  
  14936.    c:\objects\test.obj : test.c
  14937.  
  14938.  This rule does not match a dependency line such as:
  14939.  
  14940.    test.obj : test.c
  14941.  
  14942.  In this case, NMAKE uses the predefined inference rule .c.obj when building
  14943.  the target.
  14944.  
  14945.  
  14946.  10.3.5.4  Predefined Inference Rules
  14947.  
  14948.  NMAKE provides predefined inference rules containing commands for creating
  14949.  object, executable, and resource files. Table 10.6 describes the predefined
  14950.  inference rules.
  14951.  
  14952.  Table 10.6  Predefined Inference Rules
  14953.  
  14954. ╓┌──────────┌─────────────────────────────────────┌──────────────────────────╖
  14955.  Rule       Command                               Default Action
  14956.  ────────────────────────────────────────────────────────────────────────────
  14957.  .asm.obj   $(AS) $(AFLAGS) /c $*.asm             ML /c $*.ASM
  14958.  .asm.exe   $(AS) $(AFLAGS) $*.asm                ML $*.ASM
  14959.  .bas.obj   $(BC) $(BFLAGS) $*.bas;               BC $*.BAS;
  14960.  .c.obj     $(CC) $(CFLAGS) /c $*.c               CL /c $*.C
  14961.  .c.exe     $(CC) $(CFLAGS) $*.c                  CL $*.C
  14962.  .cbl.obj   $(COBOL) $(COBFLAGS) $*.cbl;          COBOL $*.CBL;
  14963.  .cbl.exe   $(COBOL) $(COBFLAGS) $*.cbl, $*.exe;  COBOL $*.CBL, $*.EXE;
  14964.  .for.obj   $(FOR) /c $(FFLAGS) $*.for            FL /c $*.FOR
  14965.  .for.exe   $(FOR) $(FFLAGS) $*.for               FL $*.FOR
  14966.  .pas.obj   $(PASCAL) /c $(PFLAGS) $*.pas         PL /c $*.PAS
  14967.  .pas.exe   $(PASCAL) $(PFLAGS) $*.pas            PL $*.PAS
  14968.  .rc.res    $(RC) $(RFLAGS) /r $*                 RC /r $*
  14969.  ────────────────────────────────────────────────────────────────────────────
  14970.  
  14971.  
  14972.  For example, assume you have the following description file:
  14973.  
  14974.    sample.exe :
  14975.  
  14976.  This description block lists a target without any dependents or commands.
  14977.  NMAKE looks at the target's extension (.EXE) and searches for an inference
  14978.  rule that describes how to create an .EXE file. Table 10.6 shows that more
  14979.  than one inference rule exists for building an .EXE file. NMAKE looks for a
  14980.  file in the current or specified directory that has the same base name as
  14981.  the target  sample  and one of the extensions in the .SUFFIXES list. For
  14982.  example, if a file called SAMPLE.FOR exists, NMAKE applies the  .for.exe
  14983.  inference rule. If more than one file with the base name SAMPLE is found,
  14984.  NMAKE applies the inference rule for the extension listed earliest in the
  14985.  .SUFFIXES list. In this example, if both SAMPLE.C and SAMPLE.FOR exist,
  14986.  NMAKE uses the  .c.exe inference rule to compile SAMPLE.C and links the
  14987.  resulting file SAMPLE.OBJ to create SAMPLE.EXE.
  14988.  
  14989.  ────────────────────────────────────────────────────────────────────────────
  14990.  NOTE
  14991.  
  14992.  By default, the options macros such as CFLAGS shown in Table 10.5 are
  14993.  undefined. As explained in Section 10.3.4.2, "Using Macros," this causes no
  14994.  problem; NMAKE replaces an undefined macro with a null string. Because the
  14995.  predefined options macros are included in the inference rules, you can
  14996.  define these macros and have their assigned values passed automatically to
  14997.  the predefined inference rules. The predefined inference rules are listed in
  14998.  Table 10.6.
  14999.  ────────────────────────────────────────────────────────────────────────────
  15000.  
  15001.  
  15002.  10.3.5.5  Precedence among Inference Rules
  15003.  
  15004.  If the same inference rule is defined in more than one place, NMAKE uses the
  15005.  rule with the highest precedence. The precedence from highest to lowest is
  15006.  
  15007.  
  15008.    1.  An inference rule defined in the description file. If more than one,
  15009.        the last one applies.
  15010.  
  15011.    2.  An inference rule defined in the TOOLS.INI file. If more than one, the
  15012.        last one applies.
  15013.  
  15014.    3.  A predefined inference rule.
  15015.  
  15016.  
  15017.  User-defined inference rules always override predefined inference rules.
  15018.  NMAKE uses a predefined inference rule only if no user-defined inference
  15019.  rule exists for a given target and dependent.
  15020.  
  15021.  If two inference rules could produce a target with the same extension, NMAKE
  15022.  uses the inference rule whose dependent's extension appears first in the
  15023.  .SUFFIXES list. See Table 10.7 in the next section, "Directives."
  15024.  
  15025.  
  15026.  10.3.6  Directives
  15027.  
  15028.  The directives in Table 10.7 provide additional control of NMAKE operations.
  15029.  You can use them in a description file outside of a description block or in
  15030.  the TOOLS.INI file. The four directives listed in the table are case
  15031.  sensitive and must appear in all uppercase letters. (Preprocessing
  15032.  directives are not case sensitive; see Section 10.3.7, "Preprocessing
  15033.  Directives.")
  15034.  
  15035.  Table 10.7  Directives
  15036.  
  15037.  Directive                         Action
  15038.  ────────────────────────────────────────────────────────────────────────────
  15039.  .IGNORE :                         Ignores exit codes returned by programs
  15040.                                    called from the description file. This
  15041.                                    directive has the same effect as
  15042.                                    invoking NMAKE with the /I option.
  15043.  
  15044.  .PRECIOUS : target...             Tells NMAKE not to delete targets if the
  15045.                                    commands that build them quit or are
  15046.                                    interrupted. Overrides the NMAKE default,
  15047.                                    which is to delete the target if
  15048.                                    building was interrupted by CTRL+C or
  15049.                                    CTRL+BREAK.
  15050.  
  15051.  .SILENT :                         Does not display lines as they are
  15052.                                    executed. This directive has the same
  15053.                                    effect as invoking NMAKE with the /S
  15054.                                    option.
  15055.  
  15056.  .SUFFIXES : list                  Lists file suffixes for NMAKE to try
  15057.                                    when building a target file for which no
  15058.                                    dependents are specified. This list is
  15059.                                    used together with inference rules. See
  15060.                                    Section
  15061.                                    10.3.5, "Inference Rules."
  15062.  
  15063.  ────────────────────────────────────────────────────────────────────────────
  15064.  
  15065.  
  15066.  The .IGNORE and .SILENT directives affect the file from their location
  15067.  onward. Location within the file does not matter for the .PRECIOUS and
  15068.  .SUFFIXES directives; they affect the entire description file.
  15069.  
  15070.  NMAKE refers to the value of the .SUFFIXES directive when using inference
  15071.  rules. When NMAKE finds a target without dependents, it searches the current
  15072.  directory for a file with the same base name as the target and a suffix from
  15073.  list. If NMAKE finds such a file, and if an inference rule applies to the
  15074.  file, then NMAKE treats the file as a dependent of the target. The order of
  15075.  the suffixes in the list defines the order in which NMAKE searches for the
  15076.  file. The list is predefined as follows:
  15077.  
  15078.    .SUFFIXES : .exe .obj .asm .c .bas .cbl .for .pas .res .rc
  15079.  
  15080.  To add additional suffixes to the end of the list, specify  .SUFFIXES :
  15081.  followed by the additional suffixes. To clear the list, specify  .SUFFIXES :
  15082.   by itself. To change the list order or to specify an entirely new list,
  15083.  clear the list and specify a new  .SUFFIXES :  setting.
  15084.  
  15085.  
  15086.  10.3.7  Preprocessing Directives
  15087.  
  15088.  NMAKE preprocessing directives are similar to compiler preprocessing
  15089.  directives. You can use the !IF, !IFDEF, !IFNDEF, !ELSE, and !ENDIF
  15090.  directives to conditionally process the description file. With other
  15091.  preprocessing directives you can display error messages, include other
  15092.  files, undefine a macro, and turn certain options on or off. NMAKE reads and
  15093.  executes the preprocessing directives before processing the description file
  15094.  as a whole.
  15095.  
  15096.  Preprocessing directives (listed in Table 10.8) begin with an exclamation
  15097.  point (!), which must appear at the beginning of the line. You can place
  15098.  spaces between the exclamation point and the directive keyword. These
  15099.  directives are not case sensitive.
  15100.  
  15101.  Table 10.8  Preprocessing Directives
  15102.  
  15103. ╓┌─────────────────────────┌─────────────────────────────────────────────────╖
  15104.  Directive                 Description
  15105.  ────────────────────────────────────────────────────────────────────────────
  15106.  !CMDSWITCHES              Turns on or off NMAKE options /D, /I, /N, and /S.
  15107.  {+| -}opt...              (See Section 10.4, "Command-Line Options.") Do
  15108.                            not specify the slash ( / ). If !CMDSWITCHES is
  15109.                            specified with no options, all options are reset
  15110.                            to the values they had when NMAKE was started.
  15111.                            This directive updates the MAKEFLAGS macro. Turn
  15112.                            an option on by preceding it with a plus sign (+
  15113.                            ), or turn it off by preceding it with a minus
  15114.                            sign (-).
  15115.  
  15116.  !ERROR text               Prints text, then stops execution.
  15117.  
  15118.  !IF constantexpression    Reads the statements between the !IF keyword and
  15119.                            the next !ELSE or !ENDIF keyword if
  15120.                            constantexpression evaluates to a nonzero value.
  15121.  
  15122.  Directive                 Description
  15123.  ────────────────────────────────────────────────────────────────────────────
  15124. 
  15125.  !IFDEF macroname          Reads the statements between the !IFDEF keyword
  15126.                            and the next !ELSE or !ENDIF keyword if
  15127.                            macroname is defined. NMAKE considers a macro
  15128.                            with a null value to be defined.
  15129.  
  15130.  !IFNDEF macroname         Reads the statements between the !IFNDEF keyword
  15131.                            and the next !ELSE or !ENDIF keyword if
  15132.                            macroname is not defined.
  15133.  
  15134.  !ELSE                     Reads the statements between the !ELSE and
  15135.                            !ENDIF keywords if the preceding !IF, !IFDEF, or
  15136.                            !IFNDEF statement evaluated to zero. Anything
  15137.                            following !ELSE on the same line is ignored.
  15138.  
  15139.  !ENDIF                    Marks the end of an !IF, !IFDEF, or !IFNDEF
  15140.                            block. Anything following !ENDIF on the same
  15141.                            line is ignored.
  15142.  
  15143.  Directive                 Description
  15144.  ────────────────────────────────────────────────────────────────────────────
  15145. 
  15146.  
  15147.  !INCLUDE filename         Reads and evaluates the description file
  15148.                            filename before continuing with the current
  15149.                            description file. If filename is enclosed by
  15150.                            angle brackets (< >), NMAKE searches for the
  15151.                            file first in the current directory and then in
  15152.                            the directories specified by the INCLUDE macro.
  15153.                            Otherwise, it looks only in the current
  15154.                            directory. The INCLUDE macro is initially set to
  15155.                            the value of the INCLUDE environment variable.
  15156.  
  15157.  !UNDEF macroname          Marks macroname as undefined in NMAKE's symbol
  15158.                            table.
  15159.  
  15160.  ────────────────────────────────────────────────────────────────────────────
  15161.  
  15162.  
  15163.  
  15164.  
  15165.  10.3.7.1  Expressions in Preprocessing
  15166.  
  15167.  The constantexpression used with the !IF directive can consist of integer
  15168.  constants, string constants, or program invocations. Integer constants can
  15169.  use the unary operators for numerical negation (-), one's complement (~),
  15170.  and logical negation (!). They can also use any binary operator listed in
  15171.  Table 10.9.
  15172.  
  15173.  Table 10.9  Preprocessing-Directive Binary Operators
  15174.  
  15175. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  15176.  Operator                          Description
  15177.  ────────────────────────────────────────────────────────────────────────────
  15178.  +                                 Addition
  15179.  
  15180.  -                                 Subtraction
  15181.  
  15182.  *                                 Multiplication
  15183.  
  15184.  /                                 Division
  15185.  Operator                          Description
  15186.  ────────────────────────────────────────────────────────────────────────────
  15187. /                                 Division
  15188.  
  15189.  %                                 Modulus
  15190.  
  15191.  &                                 Bitwise AND
  15192.  
  15193.  |                                 Bitwise OR
  15194.  
  15195.  ^                                 Bitwise XOR
  15196.  
  15197.  &&                                Logical AND
  15198.  
  15199.  ||                                Logical OR
  15200.  
  15201.  <<                                Left shift
  15202.  
  15203.  >>                                Right shift
  15204.  
  15205.  ==                                Equality
  15206.  Operator                          Description
  15207.  ────────────────────────────────────────────────────────────────────────────
  15208. ==                                Equality
  15209.  
  15210.  !=                                Inequality
  15211.  
  15212.  <                                 Less than
  15213.  
  15214.  >                                 Greater than
  15215.  
  15216.  <=                                Less than or equal to
  15217.  
  15218.  >=                                Greater than or equal to
  15219.  
  15220.  ────────────────────────────────────────────────────────────────────────────
  15221.  
  15222.  
  15223.  
  15224.  You can group expressions by enclosing them in parentheses. NMAKE treats
  15225.  numbers as decimal unless they start with 0 (octal) or 0x (hexadecimal). Use
  15226.  the equality (==) operator to compare two strings for equality, or the
  15227.  inequality (!=) operator to compare for inequality. Enclose strings in
  15228.  double quotation marks.
  15229.  
  15230.  
  15231.  Example
  15232.  
  15233.  The following example shows how preprocessing directives can be used to
  15234.  control whether the linker inserts CodeView information into the .EXE file:
  15235.  
  15236.  
  15237.    !INCLUDE <infrules.txt>
  15238.    !CMDSWITCHES +D
  15239.    winner.exe : winner.obj
  15240.    !IFDEF debug
  15241.    !   IF "$(debug)"=="y"
  15242.           LINK /CO winner.obj;
  15243.    !  ELSE
  15244.           LINK winner.obj;
  15245.    !   ENDIF
  15246.    !ELSE
  15247.    !   ERROR Macro named debug is not defined.
  15248.    !ENDIF
  15249.  
  15250.  In this example, the !INCLUDE directive inserts the INFRULES.TXT file into
  15251.  the description file. The !CMDSWITCHES directive sets the /D option, which
  15252.  displays the times of the files as they are checked. The !IFDEF directive
  15253.  checks to see if the macro  debug  is defined. If it is defined, the !IF
  15254.  directive checks to see if it is set to  y. If it is, NMAKE reads the LINK
  15255.  command with the /CO option; otherwise, NMAKE reads the LINK command without
  15256.  /CO. If the  debug  macro is not defined, the !ERROR directive prints the
  15257.  specified message and NMAKE stops.
  15258.  
  15259.  
  15260.  10.3.7.2  Executing a Program in Preprocessing
  15261.  
  15262.  NMAKE can invoke programs and check their status.
  15263.  
  15264.  You can invoke any program from within NMAKE by placing the program's name
  15265.  or path name within square brackets ( [ ] ). The program is executed during
  15266.  preprocessing, and its exit code replaces the program specification in the
  15267.  
  15268.  description file. A nonzero exit code usually indicates an error. You can
  15269.  use this value to control execution, as in the following example:
  15270.  
  15271.    !IF [c:\util\checkdsk] != 0
  15272.    !    ERROR Not enough disk space; NMAKE terminating.
  15273.    !ENDIF
  15274.  
  15275.  
  15276.  10.3.8  Extracting Filename Components
  15277.  
  15278.  "Special Macros," Section 10.3.4.3, showed how qualifiers could be added to
  15279.  macros that represented filenames in order to select components of the name
  15280.  or path. This feature is especially useful when creating a general-purpose
  15281.  description block that works with the name of any dependent.
  15282.  
  15283.  Besides these macro modifiers, NMAKE offers another feature that allows you
  15284.  to extract components of the name of the first dependent file as you have
  15285.  specified it in the description file or on the command line (not the full
  15286.  filename specification on disk). The components can then be recombined with
  15287.  specific paths, extensions, or directories to create the particular name or
  15288.  path you need, without having to specify the exact name or path when you
  15289.  write the description block.
  15290.  
  15291.  The first dependent file is the first file listed to the right of the colon
  15292.  on a dependency line. If a dependent is implied from an inference rule,
  15293.  NMAKE considers it to be the first dependent file. If more than one
  15294.  dependent is implied from inference rules, the .SUFFIXES list determines
  15295.  which dependent is first.
  15296.  
  15297.  You can use either of the following syntaxes:
  15298.  
  15299.    %s
  15300.  
  15301.    %|«parts»F
  15302.  
  15303.  where parts can be one or more of the following letters, or can be omitted:
  15304.  
  15305.  
  15306.  Letter                    Description
  15307.  ────────────────────────────────────────────────────────────────────────────
  15308.  No letter                 Complete name
  15309.  d                         Drive
  15310.  p                         Path
  15311.  f                         File base name
  15312.  e                         File extension
  15313.  
  15314.  You can specify more than one letter. The order of the letters is not
  15315.  significant; NMAKE constructs the filename that meets (or comes closest to
  15316.  meeting) all the specifications. The letters are case sensitive.
  15317.  
  15318.  The  %s  option substitutes the complete name; it is equivalent to both  %|F
  15319.   and  %|dpfeF.
  15320.  
  15321.  NMAKE interprets any percent symbol (%) within a command line (either in a
  15322.  description block or an inference rule) as the start of a file specifier
  15323.  using this syntax. Therefore, if you need to use a literal percent symbol
  15324.  within a command line, you must specify it as a double percent symbol (%%).
  15325.  
  15326.  
  15327.  
  15328.  Example
  15329.  
  15330.  The following example demonstrates this special syntax:
  15331.  
  15332.    sample.exe : c:\project\sample.obj
  15333.        LINK %|dpfF, a:%|pfF.exe;
  15334.  
  15335.  This example represents the following command:
  15336.  
  15337.    LINK c:\project\sample, a:\project\sample.exe;
  15338.  
  15339.  In this example, the sequence  %|dpfF  represents the same drive, path, and
  15340.  base name as the dependent on the dependency line, while the sequence  %|pfF
  15341.   represents only the path and base name of the dependent. The command tells
  15342.  the LINK utility to build the executable file on another drive in a
  15343.  directory of the same name.
  15344.  
  15345.  
  15346.  10.4  Command-Line Options
  15347.  
  15348.  NMAKE accepts a number of options, listed in Table 10.10. You can specify
  15349.  options in uppercase or lowercase and use either a slash or dash. For
  15350.  example, -A, /A, -a, and /a all represent the same option. This book uses a
  15351.  slash and uppercase letters.
  15352.  
  15353.  Table 10.10  NMAKE Options
  15354.  
  15355. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  15356.  Option                            Action
  15357.  ────────────────────────────────────────────────────────────────────────────
  15358.  /A                                Forces execution of all commands in
  15359.                                    description blocks in the description
  15360.                                    file even if targets are not out-of-date
  15361.                                    with respect to their dependents. Does
  15362.                                    not affect the behavior of incremental
  15363.                                    commands such as ILINK; using /A does
  15364.                                    not force a full link.
  15365.  
  15366.  /C                                Suppresses nonfatal error or warning
  15367.                                    messages and the NMAKE copyright message.
  15368.  
  15369.  /D                                Displays the modification time of each
  15370.                                    file.
  15371.  
  15372.  /E                                Causes environment variables to override
  15373.                                    macro definitions in description files.
  15374.  Option                            Action
  15375.  ────────────────────────────────────────────────────────────────────────────
  15376.                                   macro definitions in description files.
  15377.                                    See Section 10.3.4, "Macros."
  15378.  
  15379.  /F filename                       Specifies filename as the name of the
  15380.                                    description file. If you supply a dash (
  15381.                                    -) instead of a filename, NMAKE gets
  15382.                                    description-file input from the standard
  15383.                                    input device. (Terminate keyboard input
  15384.                                    with either F6 or CTRL+Z.) If you omit
  15385.                                    /F, NMAKE searches the current directory
  15386.                                    for a file called
  15387.                                    MAKEFILE and uses it as the description
  15388.                                    file. If MAKEFILE doesn't exist, NMAKE
  15389.                                    uses inference rules for the
  15390.                                    command-line targets.
  15391.  
  15392.  /HELP                             Calls the QuickHelp utility. If NMAKE
  15393.                                    cannot locate the help file or QuickHelp,
  15394.                                    it displays a brief summary of NMAKE
  15395.  Option                            Action
  15396.  ────────────────────────────────────────────────────────────────────────────
  15397.                                   it displays a brief summary of NMAKE
  15398.                                    command-line syntax and exits to the
  15399.                                    operating system.
  15400.  
  15401.  /I                                Ignores exit codes from commands listed
  15402.                                    in the description file. NMAKE processes
  15403.                                    the whole description file even if
  15404.                                    errors occur.
  15405.  
  15406.  /N                                Displays but does not execute the
  15407.                                    description file's commands. This option
  15408.                                    is useful for debugging description
  15409.                                    files and checking which targets are
  15410.                                    out-of-date.
  15411.  
  15412.  /NOLOGO                           Suppresses the NMAKE copyright message.
  15413.  
  15414.  /P                                Displays all macro definitions,
  15415.                                    inference rules, target descriptions,
  15416.  Option                            Action
  15417.  ────────────────────────────────────────────────────────────────────────────
  15418.                                   inference rules, target descriptions,
  15419.                                    and the .SUFFIXES list on the standard
  15420.                                    output device.
  15421.  
  15422.  /Q                                Checks modification times for
  15423.                                    command-line targets (or first target in
  15424.                                    description file if no command-line
  15425.                                    targets are specified). NMAKE returns a
  15426.                                    zero exit code if all such targets are
  15427.                                    up-to-date and a nonzero exit code if
  15428.                                    any target is out-of-date. Only
  15429.                                    preprocessing commands in the
  15430.                                    description file are executed. This
  15431.                                    option is useful when running NMAKE from
  15432.                                    a batch file.
  15433.  
  15434.  /R                                Ignores inference rules and macros that
  15435.                                    are defined in the TOOLS.INI file or
  15436.                                    that are predefined.
  15437.  Option                            Action
  15438.  ────────────────────────────────────────────────────────────────────────────
  15439.                                   that are predefined.
  15440.  
  15441.  /S                                Suppresses the display of commands
  15442.                                    listed in the description file.
  15443.  
  15444.  /T                                Changes modification times for
  15445.                                    command-line targets (or first target in
  15446.                                    description file if no command-line
  15447.                                    targets are specified). Only
  15448.                                    preprocessing commands in the
  15449.                                    description file are executed. Contents
  15450.                                    of target files are not modified.
  15451.  
  15452.  /X filename                       Sends all error output to filename,
  15453.                                    which can be a file or a device. If you
  15454.                                    supply a dash (-) instead of a filename,
  15455.                                    error output is sent to the standard
  15456.                                    output device.
  15457.  
  15458.  Option                            Action
  15459.  ────────────────────────────────────────────────────────────────────────────
  15460. 
  15461.  /Z                                Used for internal communication between
  15462.                                    NMAKE (or NMK) and PWB.
  15463.  
  15464.  /?                                Displays a brief summary of NMAKE
  15465.                                    command-line syntax and exits to the
  15466.                                    operating system.
  15467.  
  15468.  ────────────────────────────────────────────────────────────────────────────
  15469.  
  15470.  
  15471.  
  15472.  
  15473.  Example
  15474.  
  15475.  The following command line specifies two NMAKE options:
  15476.  
  15477.    NMAKE /F sample.mak /C targ1 targ2
  15478.  
  15479.  The /F option tells NMAKE to read the description file SAMPLE.MAK. The /C
  15480.  option tells NMAKE not to display nonfatal error messages and warnings. The
  15481.  command specifies two targets (targ1  and  targ2) to update.
  15482.  
  15483.  In the following example, NMAKE updates the target  targ1:
  15484.  
  15485.    NMAKE /D /N targ1
  15486.  
  15487.  Since no description file is specified, NMAKE searches the current directory
  15488.  for a description file named MAKEFILE. The /D option displays the
  15489.  modification time of each file; the /N option displays the commands in
  15490.  MAKEFILE without executing them.
  15491.  
  15492.  
  15493.  10.5  NMAKE Command File
  15494.  
  15495.  If you find yourself repeatedly using the same sequence of command-line
  15496.  arguments, you can place them in a text file and pass the file's name as a
  15497.  command-line argument to NMAKE. NMAKE opens the command file and reads the
  15498.  arguments. This feature is especially useful if the argument list exceeds
  15499.  the maximum length of a command line (128 characters in DOS, 256 in OS/2).
  15500.  
  15501.  To provide input to NMAKE with a command file, type
  15502.  
  15503.  NMAKE @commandfile
  15504.  
  15505.  In the commandfile field, enter the name of a file containing the
  15506.  information NMAKE expects on the command line. You can split input between
  15507.  the command line and a command file. Use the name of the command file
  15508.  (preceded by @) in place of the input information on the command line.
  15509.  
  15510.  
  15511.  Example 1
  15512.  
  15513.  Assume you have created a filenamed UPDATE containing this line:
  15514.  
  15515.    /S "program = sample" sort.exe search.exe
  15516.  
  15517.  If you start NMAKE with the command
  15518.  
  15519.    NMAKE @update
  15520.  
  15521.  then NMAKE reads its command-line arguments from UPDATE. The at sign (@)
  15522.  tells NMAKE to read arguments from the file. The effect is the same as if
  15523.  you typed the arguments directly on the command line:
  15524.  
  15525.    NMAKE /S "program = sample" sort.exe search.exe
  15526.  
  15527.  NMAKE treats the file as if it were a single set of arguments and replaces
  15528.  each line break with a space. Macro definitions that contain spaces must be
  15529.  enclosed in quotation marks, just as if you had typed them on the command
  15530.  line.
  15531.  
  15532.  The quotation marks that delimit a macro force all characters between them
  15533.  to be interpreted literally. Therefore, if you split a macro between lines,
  15534.  an unwanted line break is inserted into the macro. Macros that span multiple
  15535.  lines must be continued by ending each line except the last with a backslash
  15536.  ( \ ):
  15537.  
  15538.    /S "program \
  15539.    = sample" sort.exe search.exe
  15540.  
  15541.  This file is equivalent to the first example. The backslash allows the macro
  15542.  definition ("program = sample") to span two lines.
  15543.  
  15544.  
  15545.  Example 2
  15546.  
  15547.  If the command-file UPDATE contains this line:
  15548.  
  15549.    /S "program = sample" sort.exe
  15550.  
  15551.  you can give NMAKE the same command-line input as in the example above by
  15552.  specifying the command
  15553.  
  15554.    NMAKE @update search.exe
  15555.  
  15556.  
  15557.  10.6  The TOOLS.INI File
  15558.  
  15559.  You can customize NMAKE by placing commonly used macros, inference rules,
  15560.  and description blocks in the TOOLS.INI initialization file. Settings for
  15561.  NMAKE must follow a line that begins with [NMAKE]. This section of the
  15562.  initialization file can contain macro definitions, .SUFFIXES lists, and
  15563.  inference rules. For example, if TOOLS.INI contains the following section:
  15564.  
  15565.    [NMAKE]
  15566.    CC=qcl
  15567.    CFLAGS=/Gc /Gs /W3 /Oat
  15568.    .c.obj:
  15569.        $(CC) /c $(CFLAGS) $*.c
  15570.  
  15571.  NMAKE reads and applies the lines following  [NMAKE]. The example redefines
  15572.  the macro CC to invoke the Microsoft QuickC (R) Compiler, defines the macro
  15573.  CFLAGS, and redefines the inference rule for making .OBJ files from .C
  15574.  sources. (Note that macros are case sensitive; a macro called cc is not
  15575.  substituted in a rule that uses $(CC).)
  15576.  
  15577.  NMAKE looks for TOOLS.INI in the current directory. If it isn't there, NMAKE
  15578.  searches the directory specified by the INIT environment variable.
  15579.  
  15580.  Macros and inference rules appearing in TOOLS.INI can be overridden. See
  15581.  Section 10.3.4.7, "Precedence among Macro Definitions," and Section
  15582.  10.3.5.5, "Precedence among Inference Rules."
  15583.  
  15584.  
  15585.  10.7  Inline Files
  15586.  
  15587.  NMAKE can create "inline files" which contain any text you specify. One use
  15588.  of inline files is to write a response file for another utility such as LINK
  15589.  or LIB. This eliminates the need to maintain a separate response file and
  15590.  removes the restraint on the maximum length of a command line.
  15591.  
  15592.  Use this syntax to create an inline file called filename:
  15593.  
  15594.  target : dependents  command << «filename» inlinetext <<«KEEP | NOKEEP»
  15595.  
  15596.  All inlinetext between the two sets of double angle brackets (<<) is placed
  15597.  in the inline file. The filename is optional. If you don't supply filename,
  15598.  NMAKE gives the inline file a unique name. NMAKE places the inline file in
  15599.  the directory specified by the TMP environment variable. If TMP is not
  15600.  defined, the inline file is placed in the current directory.
  15601.  
  15602.  Directives are not allowed in an inline file. NMAKE treats a directive in an
  15603.  inline file as literal text.
  15604.  
  15605.  The inline file can be temporary or permanent. If you don't specify the
  15606.  option, or if you specify NOKEEP, the file is temporary. Specify KEEP to
  15607.  retain the file after the build ends.
  15608.  
  15609.  
  15610.  Example
  15611.  
  15612.  The following description block creates a LIB response file named LIB.LRF:
  15613.  
  15614.    OBJECTS=add.obj sub.obj mul.obj div.obj
  15615.    math.lib : $(OBJECTS)
  15616.        LIB @<<lib.lrf
  15617.    $*.lib
  15618.    -+$(OBJECTS: = &^
  15619.    -+)
  15620.    listing;
  15621.    <<KEEP
  15622.  
  15623.  The resulting response file tells LIB which library to use, the commands to
  15624.  execute, and the name of the listing file to produce:
  15625.  
  15626.    math.lib
  15627.    -+add.obj &
  15628.    -+sub.obj &
  15629.    -+mul.obj &
  15630.    -+div.obj
  15631.    listing;
  15632.  
  15633.  The file MATH.LIB must exist beforehand for this example to work.
  15634.  
  15635.  
  15636.  Multiple Inline Files
  15637.  
  15638.  The inline file specification can create more than one inline file. For
  15639.  instance,
  15640.  
  15641.    target.abc : depend.xyz
  15642.        cat <<file1 <<file2
  15643.    I am the contents of file1.
  15644.    <<KEEP
  15645.    I am the contents of file2.
  15646.    <<KEEP
  15647.  
  15648.  The example creates the two inline files, FILE1 and FILE2. All inline text
  15649.  is written to the files sequentially. Therefore, the text
  15650.  
  15651.    I am the contents of file1.
  15652.  
  15653.  goes into FILE1, not FILE2, even though the text is nested between the angle
  15654.  brackets for FILE2 and the  <<KEEP  statement which follows. NMAKE then
  15655.  executes the command
  15656.  
  15657.    cat file1 file2
  15658.  
  15659.  The KEEP keywords tell NMAKE not to delete FILE1 and FILE2 when done.
  15660.  
  15661.  
  15662.  10.8  Sequence of NMAKE Operations
  15663.  
  15664.  When you are writing a complex description file, it can be helpful to know
  15665.  the sequence in which NMAKE performs operations. This section describes
  15666.  those operations and their order.
  15667.  
  15668.  NMAKE first looks for a description file.
  15669.  
  15670.  When you run NMAKE from the command line, NMAKE's first task is to find the
  15671.  description file:
  15672.  
  15673.  
  15674.    1.  If the /F option is used, NMAKE searches for the filename specified in
  15675.        the option. If NMAKE cannot find that file, it returns an error.
  15676.  
  15677.    2.  If the /F option is not used, NMAKE looks for a file named MAKEFILE in
  15678.        the current directory. If there are targets on the command line, NMAKE
  15679.        builds them according to the instructions in MAKEFILE. If there are no
  15680.        targets on the command line, NMAKE builds only the first target it
  15681.        finds in MAKEFILE.
  15682.  
  15683.    3.  If NMAKE cannot find MAKEFILE, NMAKE looks for target files on the
  15684.        command line and attempts to build them using inference rules (either
  15685.        defined by the user in TOOLS.INI or predefined by NMAKE). If no target
  15686.        is specified, NMAKE returns an error.
  15687.  
  15688.  
  15689.  Macro definitions follow a priority.
  15690.  
  15691.  NMAKE then assigns macro definitions with the following precedence (highest
  15692.  first):
  15693.  
  15694.  
  15695.    1.  Macros defined on the command line
  15696.  
  15697.    2.  Macros defined in a description file or include file
  15698.  
  15699.    3.  Inherited macros
  15700.  
  15701.    4.  Macros defined in the TOOLS.INI file
  15702.  
  15703.    5.  Predefined macros (such as CC and RFLAGS)
  15704.  
  15705.  
  15706.  Macro definitions are assigned in order of priority, not in the order in
  15707.  which NMAKE encounters them. For example, a macro defined in an include file
  15708.  overrides a macro with the same name from the TOOLS.INI file. Note that a
  15709.  macro within a description file can be redefined; the most recent definition
  15710.  in the description file is used.
  15711.  
  15712.  Inference rules also follow a priority.
  15713.  
  15714.  NMAKE also assigns inference rules, using the following precedence (highest
  15715.  first):
  15716.  
  15717.  
  15718.    1.  Inference rules defined in a description file or include file
  15719.  
  15720.    2.  Inference rules defined in the TOOLS.INI file
  15721.  
  15722.    3.  Predefined inference rules (such as .c.obj)
  15723.  
  15724.  
  15725.  You can use command-line options to change some of these precedences.
  15726.  
  15727.  
  15728.    ■   The /E option allows macros inherited from the environment to override
  15729.        macros defined in the description file.
  15730.  
  15731.    ■   The /R option tells NMAKE to ignore macros and inference rules that
  15732.        are defined in TOOLS.INI or are predefined.
  15733.  
  15734.  
  15735.  NMAKE preprocesses directives before running the description-file commands.
  15736.  
  15737.  
  15738.  Next, NMAKE evaluates any preprocessing directives. If an expression for
  15739.  conditional preprocessing contains a program in square brackets ( [ ] ), the
  15740.  program is invoked during preprocessing, and the program's exit code is used
  15741.  in the expression. If an !INCLUDE directive is specified for a file, NMAKE
  15742.  preprocesses the included file before continuing to preprocess the rest of
  15743.  the description file. Preprocessing determines the final description file
  15744.  that NMAKE reads.
  15745.  
  15746.  NMAKE updates targets in the description file.
  15747.  
  15748.  NMAKE is now ready to update the targets. If you specified targets on the
  15749.  command line, NMAKE updates only those targets. If you did not specify
  15750.  targets on the command line, NMAKE updates just the first target it finds in
  15751.  the description file. (This behavior differs from the MAKE utility's
  15752.  default; see Section 10.10, "Differences between NMAKE and MAKE.") If you
  15753.  specify a pseudotarget, NMAKE always updates the target. If you use the /A
  15754.  option, NMAKE always updates the target, even if the file is not
  15755.  out-of-date.
  15756.  
  15757.  If the dependents of the targets are themselves out-of-date or do not exist
  15758.  yet, NMAKE updates them first. If the target has no explicit dependent,
  15759.  NMAKE looks in the current directory for one or more files with the same
  15760.  base name as the target and whose extensions are in the .SUFFIXES list. (See
  15761.  Section 10.3.6, "Directives," for a description of the .SUFFIXES list.) If
  15762.  it finds such files, NMAKE treats them as dependents and updates the target
  15763.  according to the commands.
  15764.  
  15765.  Errors usually stop the build.
  15766.  
  15767.  NMAKE normally stops processing the description file when a command returns
  15768.  a nonzero exit code. In addition, if NMAKE cannot tell whether the target
  15769.  was built successfully, it deletes the target. If you use the /I
  15770.  command-line option, NMAKE ignores error codes and attempts to continue
  15771.  processing. The .IGNORE directive has the same effect as the /I option. To
  15772.  prevent NMAKE from deleting the partially created target if you interrupt
  15773.  the build with CTRL+C or CTRL+BREAK, specify the target name in the
  15774.  .PRECIOUS directive.
  15775.  
  15776.  Alternatively, you can use the dash (-) command modifier to ignore the error
  15777.  code for an individual command. An optional number after the dash tells
  15778.  NMAKE to continue if the command returns an exit code that is less than or
  15779.  equal to the number, and to stop if the exit code is greater than the
  15780.  number.
  15781.  
  15782.  You can document errors by using the !ERROR directive to print descriptive
  15783.  text. The directive causes NMAKE to print some text, then stop, even if you
  15784.  use /I, .IGNORE, or the dash (-) modifier.
  15785.  
  15786.  
  15787.  10.9  A Sample NMAKE Description File
  15788.  
  15789.  The following example illustrates many of NMAKE's features. The description
  15790.  file creates an executable file from C-language source files:
  15791.  
  15792.    #  This description file builds SAMPLE.EXE from SAMPLE.C,
  15793.    #  ONE.C, and TWO.C, then deletes intermediate files.
  15794.  
  15795.    CFLAGS   = /c /AL /Od $(CODEVIEW)  # controls compiler options
  15796.    LFLAGS   = /CO                     # controls linker options
  15797.    CODEVIEW = /Zi                     # controls CodeView data
  15798.  
  15799.    OBJS = sample.obj one.obj two.obj
  15800.    all : sample.exe
  15801.  
  15802.    sample.exe : $(OBJS)
  15803.        link $(LFLAGS) @<<sample.lrf
  15804.    $(OBJS: =+^
  15805.    )
  15806.    sample.exe
  15807.    sample.map;
  15808.    <<KEEP
  15809.  
  15810.    sample.obj : sample.c sample.h common.h
  15811.         CL $(CFLAGS) sample.c
  15812.  
  15813.    one.obj : one.c one.h common.h
  15814.         CL $(CFLAGS) one.c
  15815.  
  15816.    two.obj : two.c two.h common.h
  15817.         CL $(CFLAGS) two.c
  15818.  
  15819.    clean :
  15820.        -del *.obj
  15821.        -del *.map
  15822.        -del *.lrf
  15823.  
  15824.  Assume that this description file is named SAMPLE.MAK. To invoke it, enter
  15825.  
  15826.    NMAKE /F SAMPLE.MAK all clean
  15827.  
  15828.  NMAKE then builds SAMPLE.EXE and deletes intermediate files.
  15829.  
  15830.  Here is how the description file works. The CFLAGS, CODEVIEW, and LFLAGS
  15831.  macros define the default options for the compiler, linker, and inclusion of
  15832.  CodeView information. You can redefine these options from the command line
  15833.  to alter or delete them. For example,
  15834.  
  15835.    NMAKE /F SAMPLE.MAK CODEVIEW= CFLAGS= all clean
  15836.  
  15837.  creates an .EXE file that does not contain CodeView information.
  15838.  
  15839.  The OBJS macro specifies the object files that make up SAMPLE.EXE, so they
  15840.  can be reused without having to type them again. Their names are separated
  15841.  by exactly one space so that the space can be replaced with a plus sign (+)
  15842.  and a carriage return in the link response file. (This is illustrated in the
  15843.  second example in Section 10.3.4.4, "Substitution within Macros.")
  15844.  
  15845.  The  all  pseudotarget points to the real target,  SAMPLE.EXE. If you do not
  15846.  specify any target on the command line, NMAKE ignores the  clean
  15847.  pseudotarget but still builds  all, since  all  is the first target in the
  15848.  description file.
  15849.  
  15850.  The dependency line containing the target  sample.exe  makes the object
  15851.  files specified in OBJS the dependents of SAMPLE.EXE. The command section of
  15852.  the block contains only link instructions. No compilation instructions are
  15853.  given, since they are given explicitly later in the file. (You could also
  15854.  define an inference rule to specify how an object file is to be created from
  15855.  a C source file.)
  15856.  
  15857.  The link command is unusual in that the link parameters and options are not
  15858.  passed directly to LINK. Rather, an inline response file is created
  15859.  containing these elements. This eliminates the need to maintain a separate
  15860.  link response file. It also allows the LINK command line to exceed the
  15861.  normal limit on the length of a command line (128 characters in DOS, 256
  15862.  characters in OS/2).
  15863.  
  15864.  The next three dependencies define the relationship of the source code to
  15865.  the object files. The .H (header or include) files are also dependents,
  15866.  since any changes to them would require recompilation.
  15867.  
  15868.  The  clean  pseudotarget deletes unneeded files after a build. The dash
  15869.  modifier (-) tells NMAKE to ignore errors returned by the deletion commands.
  15870.  If you want to save any of these files, don't specify  clean  on the command
  15871.  line; NMAKE then ignores the  clean  pseudotarget.
  15872.  
  15873.  
  15874.  10.10  Differences between NMAKE and MAKE
  15875.  
  15876.  NMAKE replaces the Microsoft MAKE program. NMAKE differs from MAKE in the
  15877.  following ways:
  15878.  
  15879.  
  15880.    ■   NMAKE does not evaluate targets sequentially. Instead, NMAKE updates
  15881.        the targets you specify when you invoke it, regardless of their
  15882.        positions in the description file. If no targets are specified, NMAKE
  15883.        updates only the first target in the file.
  15884.  
  15885.    ■   NMAKE requires a special syntax when specifying a target in more than
  15886.        one dependency line. (See Section 10.3.1.8, "Specifying a Target in
  15887.        Multiple Description Blocks.")
  15888.  
  15889.    ■   NMAKE accepts command-line arguments from a file.
  15890.  
  15891.    ■   NMAKE provides more command-line options.
  15892.  
  15893.    ■   NMAKE provides more predefined macros.
  15894.  
  15895.    ■   NMAKE permits substitutions within macros.
  15896.  
  15897.    ■   NMAKE supports directives placed in the description file.
  15898.  
  15899.    ■   NMAKE allows you to specify include files in the description file.
  15900.  
  15901.  
  15902.  The first item in the list deserves special emphasis. While MAKE updates
  15903.  every target, working from beginning to end of the description file, NMAKE
  15904.  expects you to specify targets on the command line. If you do not, NMAKE
  15905.  builds only the first target in the description file.
  15906.  
  15907.  This difference is clear if you run NMAKE using a typical MAKE description
  15908.  file, which lists a series of subordinate targets followed by a higher-level
  15909.  target that depends on the following subordinates:
  15910.  
  15911.    pmapp.obj : pmapp.c
  15912.        CL /c /G2sw /W3 pmapp.c
  15913.  
  15914.    pmapp.exe : pmapp.obj pmapp.def
  15915.        LINK pmapp, /align:16, NUL, os2, pmapp
  15916.  
  15917.  MAKE builds both targets (PMAPP.OBJ and PMAPP.EXE), but NMAKE builds only
  15918.  the first target (PMAPP.OBJ).
  15919.  
  15920.  Because of these performance differences, you may want to convert MAKE files
  15921.  to NMAKE files. MAKE description files are easy to convert. One way is to
  15922.  create a new description block at the beginning of the file. Give this block
  15923.  a pseudotarget named  all  and list the top-level target as a dependent of
  15924.  all. To build  all, NMAKE must update every file upon which the target  all
  15925.  depends:
  15926.  
  15927.    all : pmapp.exe
  15928.  
  15929.    pmapp.obj : pmapp.c
  15930.        CL /c /G2sw /W3 pmapp.c
  15931.  
  15932.    pmapp.exe : pmapp.obj pmapp.def
  15933.        LINK pmapp, /align:16, NUL, os2, pmapp
  15934.  
  15935.  If the above file is named MAKEFILE, you can update the target PMAPP.EXE
  15936.  with the command
  15937.  
  15938.    NMAKE
  15939.  
  15940.  or the command
  15941.  
  15942.    NMAKE all
  15943.  
  15944.  It is not necessary to list PMAPP.OBJ as a dependent of  all. NMAKE builds a
  15945.  dependency tree for the entire description file and builds whatever files
  15946.  are needed to update PMAPP.EXE. If PMAPP.C has a later modification time
  15947.  than PMAPP.OBJ, NMAKE compiles PMAPP.C to create PMAPP.OBJ, then links
  15948.  PMAPP.OBJ to create PMAPP.EXE.
  15949.  
  15950.  The same technique is suitable for description files with more than one
  15951.  top-level target. List all the top-level targets as dependents of  all:
  15952.  
  15953.    all : pmapp.exe second.exe another.exe
  15954.  
  15955.  The example updates the targets PMAPP.EXE, SECOND.EXE, and ANOTHER.EXE.
  15956.  
  15957.  If the description file lists a single, top-level target, you can use an
  15958.  even simpler technique. Move the top-level block to the beginning of the
  15959.  file:
  15960.  
  15961.    pmapp.exe : pmapp.obj pmapp.def
  15962.        LINK pmapp, /align:16, NUL, os2, pmapp
  15963.    pmapp.obj : pmapp.c
  15964.        CL /c /G2sw /W3 pmapp.c
  15965.  
  15966.  NMAKE updates the second target (PMAPP.OBJ) whenever needed to keep the
  15967.  first target (PMAPP.EXE) current.
  15968.  
  15969.  
  15970.  10.11  Using NMK
  15971.  
  15972.  When you maintain a project under DOS or in a DOS session under OS/2, you
  15973.  will probably need to use the NMK utility. NMK uses only 5K of memory,
  15974.  leaving room for the programs called during the build. You run NMK the same
  15975.  way you run NMAKE, using the same command-line syntax and the same
  15976.  description-file syntax. NMK calls NMAKE to read the description file and
  15977.  perform the build.
  15978.  
  15979.  The behavior of NMK is slightly different from that of NMAKE. The
  15980.  fundamental difference is that NMAKE rechecks the update status of all files
  15981.  after each build step, whereas NMK checks file status only once, at the
  15982.  start of the build process. If your description file simply compiles a
  15983.  series of files and then links them, this difference never causes a problem.
  15984.  But consider the following example, which uses a pseudotarget to clean up
  15985.  old files during the build:
  15986.  
  15987.    all : clean example.exe
  15988.  
  15989.    example.exe : example.asm
  15990.        ML example
  15991.  
  15992.    clean :
  15993.        del example.obj
  15994.        del example.exe
  15995.  
  15996.  This description file erases EXAMPLE.OBJ and EXAMPLE.EXE, then recompiles.
  15997.  Under NMAKE, it works as intended; that is, it
  15998.  
  15999.  
  16000.    1.  Erases files
  16001.  
  16002.    2.  Checks the status of EXAMPLE.EXE
  16003.  
  16004.    3.  Rebuilds EXAMPLE.EXE because EXAMPLE.EXE is no longer present
  16005.  
  16006.  
  16007.  However, NMK checks the status of the environment only at the beginning of
  16008.  the build. Since EXAMPLE.EXE exists when the build starts, the preceding
  16009.  description file
  16010.  
  16011.  
  16012.    1.  Erases files
  16013.  
  16014.    2.  Stops execution, because EXAMPLE.EXE was present and up-to-date at the
  16015.        beginning of the process
  16016.  
  16017.  
  16018.  PWB never generates a description file that requires dynamic status checking
  16019.  to run correctly, so you can use PWB-created description files with either
  16020.  NMAKE or NMK.
  16021.  
  16022.  
  16023.  10.12  Using Exit Codes with NMAKE
  16024.  
  16025.  NMAKE stops execution if a program executed by one of the commands in the
  16026.  NMAKE description file encounters an error. The exit code returned by the
  16027.  program is displayed as part of the error message.
  16028.  
  16029.  Assume the NMAKE description file  TEST  contains the following lines:
  16030.  
  16031.    TEST.OBJ : TEST.FOR
  16032.        FL /c TEST.FOR
  16033.  
  16034.  If the source code in  TEST.FOR  causes an error (but not a warning), you
  16035.  would see the following message the first time you use NMAKE with the NMAKE
  16036.  description file  TEST:
  16037.  
  16038.    NMAKE : fatal error U1077: 'FL /c TEST.FOR' - return code '2'
  16039.  
  16040.  This error message indicates that the command  FL /c TEST.FOR  in the NMAKE
  16041.  description file returned exit code 2.
  16042.  
  16043.  You can cause NMAKE to ignore an exit code for a command by preceding the
  16044.  command with a dash modifier (-). If you specify a number after the dash
  16045.  modifier (-n), NMAKE stops only if the exit code is greater than the
  16046.  specified number. (See Table 10.1.) You disable this behavior for the entire
  16047.  description file by invoking NMAKE with the /I option.
  16048.  
  16049.  You can also test exit codes in NMAKE description files with the !IF
  16050.  preprocessing directive. See Section 10.3.7.2, "Executing a Program in
  16051.  Preprocessing."
  16052.  
  16053.  If you prefer to use DOS batch files instead of NMAKE description files, you
  16054.  can test the code returned with the IF command. See a DOS manual for more
  16055.  information.
  16056.  
  16057.  NMAKE returns an exit code to the operating system or the calling program. A
  16058.  value of 0 indicates execution of NMAKE with no errors. Warnings return exit
  16059.  code 0.
  16060.  
  16061.  Code               Meaning
  16062.  ────────────────────────────────────────────────────────────────────────────
  16063.  0                  No error
  16064.  2                  Program error
  16065.  4                  System error─out of memory
  16066.  
  16067.  
  16068.  10.13  Related Topics in Online Help
  16069.  
  16070.  In addition to information covered in this chapter, information on the
  16071.  following topics can be found in online help.
  16072.  
  16073.  Topics                                Access
  16074.  ────────────────────────────────────────────────────────────────────────────
  16075.  Syntax and procedural information on  From the list of Utilities on the
  16076.  NMAKE                                 "Microsoft Advisor Contents" screen,
  16077.                                        choose "NMAKE"
  16078.  
  16079.  Using TOOLS.INI                       From the "Microsoft Advisor Contents"
  16080.                                        screen, choose "Programmer's
  16081.                                        WorkBench"; then choose "Using
  16082.                                        TOOLS.INI" from the list of topics
  16083.                                        relating to customizing PWB
  16084.  
  16085.  
  16086.  
  16087.  
  16088.  
  16089.  
  16090.  
  16091.  Chapter 11  Creating Help Files with HELPMAKE
  16092.  ────────────────────────────────────────────────────────────────────────────
  16093.  
  16094.  If you've used the Programmer's WorkBench (PWB) or one of the Microsoft
  16095.  Quick languages, you already know the advantages of online help, or the
  16096.  Microsoft Advisor. The Microsoft Help File Maintenance utility (HELPMAKE)
  16097.  lets you extend these advantages by customizing the help files supplied with
  16098.  Microsoft language products, or by creating your own help files for them.
  16099.  
  16100.  HELPMAKE translates help text files into a help database accessible within
  16101.  these environments:
  16102.  
  16103.  
  16104.    ■   Microsoft Programmer's WorkBench (PWB)
  16105.  
  16106.    ■   Microsoft QuickHelp utility
  16107.  
  16108.    ■   Microsoft CodeView debugger
  16109.  
  16110.    ■   Microsoft Editor version 1.02
  16111.  
  16112.    ■   Microsoft QuickC compiler versions 2.0 and later
  16113.  
  16114.    ■   Microsoft QuickBasic(tm) versions 4.5 and later
  16115.  
  16116.    ■   Microsoft QuickPascal(tm) version 1.0
  16117.  
  16118.    ■   Microsoft Word version 5.5
  16119.  
  16120.  
  16121.  This chapter describes how to create and modify help files using the
  16122.  HELPMAKE utility.
  16123.  
  16124.  
  16125.  11.1  Structure and Contents of a Help Database
  16126.  
  16127.  HELPMAKE creates a help database from one or more input files that contain
  16128.  information formatted for the help system. This section defines some of the
  16129.  terms involved in formatting and outlines the formats that HELPMAKE can
  16130.  process.
  16131.  
  16132.  
  16133.  11.1.1  Contents of a Help File
  16134.  
  16135.  Each help input file consists of one or more help "topics." A topic is the
  16136.  fundamental unit of help information. It is usually a screenful of
  16137.  information about a particular subject. You identify the subject by one or
  16138.  more "context strings," which are the words and phrases for which you want
  16139.  to be able to request help. When help is requested on a context string, the
  16140.  topic is displayed.
  16141.  
  16142.  The .context command defines a context string for the topic that follows it.
  16143.  In the source file for C help, for example, this line introduces help for
  16144.  the #include directive:
  16145.  
  16146.    .context #include
  16147.  
  16148.  The .context command and other formatting elements are described in Section
  16149.  11.5, "Help Text Conventions."
  16150.  
  16151.  Whether a context string contains one word or several words depends on the
  16152.  application. For example, because Microsoft QuickBasic considers spaces to
  16153.  be delimiters, a context string in QuickBasic help files is limited to a
  16154.  single word. Other applications, such as PWB, can handle context strings
  16155.  that span several words. In either case, the application hands the context
  16156.  string to an internal "help engine" that searches the database for
  16157.  information.
  16158.  
  16159.  Often, especially with library routines, the same information applies to
  16160.  more than one subject. For example, the C-language string-to-number
  16161.  functions strtod, strtol, and strtoul share the same help text. The help
  16162.  file lists all three function names as contexts for one block of topic text.
  16163.  The converse, however, is not true. You cannot associate a single context
  16164.  string with several blocks of topic text located at different places in the
  16165.  help file.
  16166.  
  16167.  Cross-references help you navigate a help database.
  16168.  
  16169.  Cross-references make it possible to view information about related topics,
  16170.  including header files and code examples. The help for the C-language open
  16171.  function, for example, references the access function. Cross-references can
  16172.  point to other contexts in the same help database, to contexts in other help
  16173.  databases, or even to ASCII files outside the database.
  16174.  
  16175.  Help files can have two kinds of cross-references:
  16176.  
  16177.  
  16178.    ■   Implicit
  16179.  
  16180.    ■   Explicit, or hyperlinks
  16181.  
  16182.  
  16183.  Implicit cross-references are coded with an ordinary .context command.
  16184.  
  16185.  The word "open" is an implicit cross-reference throughout Microsoft C help,
  16186.  and introduces help for the open function. If you select the word "open"
  16187.  anywhere in C help, the help system displays information on the open
  16188.  function. The context for open begins with an ordinary .context command. As
  16189.  a result, anywhere that you select "open," the help system references this
  16190.  context.
  16191.  
  16192.  Hyperlinks are explicit cross-references marked by invisible text.
  16193.  
  16194.  A "hyperlink" is an explicit cross-reference tied to a word or phrase at a
  16195.  specific location in the help file. You create hyperlinks when you write the
  16196.  help text. The hyperlink consists of a word or phrase followed by invisible
  16197.  text that gives the context to which the hyperlink refers.
  16198.  
  16199.  For example, to cause an instance of the word "formatting" to display help
  16200.  on the printf function, you would create an explicit cross-reference from
  16201.  the word "formatting" to the context "printf." Elsewhere in the file,
  16202.  "formatting" has no special significance, but at that one position, it
  16203.  references the help for printf. For details on how to create hyperlinks, see
  16204.  Section 11.5.4.
  16205.  
  16206.  Formatting flags let you change the appearance of text.
  16207.  
  16208.  Help text can also include formatting attributes to control the appearance
  16209.  of the text on the screen. Using these attributes, you can make certain
  16210.  words appear in various colors, inverse video, and so forth, depending on
  16211.  the application displaying help and the graphics capabilities of your
  16212.  computer.
  16213.  
  16214.  
  16215.  11.1.2  Help File Formats
  16216.  
  16217.  You can create sources for help text files in any of three formats:
  16218.  
  16219.  
  16220.    ■   QuickHelp format
  16221.  
  16222.    ■   Rich Text Format (RTF)
  16223.  
  16224.    ■   Minimally formatted ASCII
  16225.  
  16226.  
  16227.  In addition, you can reference unformatted ASCII files, such as include
  16228.  files, from within a help database.
  16229.  
  16230.  An entire help system (such as the ones supplied with Microsoft C, FORTRAN,
  16231.  MASM, or QuickBasic) can use any combination of files formatted with
  16232.  different format types. With C, for example, the README.DOC information file
  16233.  is encoded as minimally formatted ASCII; the help files for the PWB, C
  16234.  language, and run-time library are written in QuickHelp format before being
  16235.  compressed by HELPMAKE. The database also cross-references the header
  16236.  (include) files, which are unformatted ASCII files stored outside the
  16237.  database.
  16238.  
  16239.  
  16240.  QuickHelp
  16241.  
  16242.  QuickHelp format is the default format into which HELPMAKE decodes help
  16243.  databases. Any text editor can create a QuickHelp-format help text file.
  16244.  QuickHelp format also lends itself to a relatively easy automated
  16245.  translation from other document formats.
  16246.  
  16247.  QuickHelp files can contain any kind of cross-reference or formatting
  16248.  attribute. Typically, you use QuickHelp format when modifying a
  16249.  Microsoft-supplied database.
  16250.  
  16251.  QuickHelp format makes use of dot commands (such as .context─see the
  16252.  description of QuickHelp dot commands in Section 11.6.1). To use dot
  16253.  commands other than .context and .comment, the / T option is required for
  16254.  encoding and decoding. For details, see Section 11.3, "Helpmake Options."
  16255.  
  16256.  
  16257.  Rich Text Format
  16258.  
  16259.  Rich Text Format (RTF) is a Microsoft word-processing format that several
  16260.  word processors support, including Microsoft Word version 5.0 and later, and
  16261.  Microsoft Word for Windows. You can use RTF as an intermediate format to
  16262.  simplify transferring help files from one format to another. Like QuickHelp
  16263.  files, RTF files can contain formatting attributes and cross-references.
  16264.  
  16265.  An RTF word processor provides the easiest way to create an RTF file, but
  16266.  you can manually insert RTF codes with an ordinary text editor. There are
  16267.  also utility programs that convert text files in other formats to RTF
  16268.  format.
  16269.  
  16270.  See Section 11.6.2, "Rich Text Format," for more information.
  16271.  
  16272.  
  16273.  Minimally Formatted ASCII
  16274.  
  16275.  Minimally formatted ASCII files define contexts and their topic text; they
  16276.  cannot contain screen-formatting commands or explicit cross-references.
  16277.  (Implicit cross-references work the same way they do in the other formats.)
  16278.  Minimally formatted ASCII files are often used to display text in a
  16279.  README.DOC or small help files that do not require compression. See Section
  16280.  11.6.3, "Minimally Formatted ASCII Format," for more information.
  16281.  
  16282.  
  16283.  Unformatted ASCII
  16284.  
  16285.  Unformatted ASCII files are exactly what their name implies: regular ASCII
  16286.  files with no formatting commands, context definitions, or special
  16287.  information. HELPMAKE does not process unformatted ASCII files in any
  16288.  special way. An unformatted ASCII file does not become part of the help
  16289.  database; only its name is used as the object of a cross-reference.
  16290.  Unformatted ASCII files are useful for storing program examples. Any word
  16291.  that is an implicit cross-reference in other help files is also an implicit
  16292.  cross-reference in unformatted ASCII files.
  16293.  
  16294.  
  16295.  11.2  Invoking HELPMAKE
  16296.  
  16297.  The HELPMAKE program can encode to create new help files or decode to modify
  16298.  existing ones. Encoding converts a text file to a compressed help database.
  16299.  HELPMAKE can encode text files written in QuickHelp, RTF, and minimally
  16300.  formatted ASCII format. Decoding converts a help database to a text file for
  16301.  editing. Regardless of the source format, HELPMAKE always decodes a help
  16302.  database into a QuickHelp-format text file.
  16303.  
  16304.  You invoke HELPMAKE with the following syntax:
  16305.  
  16306.    HELPMAKE {/E«n» | /D«c» |
  16307.    / H| /?} [[options]] sourcefiles
  16308.  
  16309.  The options modify the action of HELPMAKE; they are described in Section
  16310.  11.3, "HELPMAKE Options."
  16311.  
  16312.  You must supply either the /E (encode) or the /D (decode) option. When
  16313.  encoding, you must also use the /O option to specify the file name of the
  16314.  database.
  16315.  
  16316.  The sourcefiles field is required. It specifies the input file(s) for
  16317.  HELPMAKE. If you use the /D (decode) option, sourcefiles can be one or more
  16318.  help database files (such as PWB.HLP). HELPMAKE decodes the database files
  16319.  to the standard output device. If you use the /E (encode) option,
  16320.  sourcefiles can be one or more help text files (such as PWB.SRC). File names
  16321.  are separated with a space. You can use standard wild-card characters to
  16322.  specify a group of related files.
  16323.  
  16324.  The example below invokes HELPMAKE with the /V, /E, and /O options (see
  16325.  Section 11.3.1, "Options for Encoding"). HELPMAKE reads input from the text
  16326.  file  my.txt  and writes the compressed help database in the file  my.hlp.
  16327.  The /E option, without a compression specification, maximizes compression.
  16328.  Note that the DOS or OS/2 redirection symbol (>) sends a log of HELPMAKE
  16329.  activity to the file  my.log. You may want to redirect the log file because,
  16330.  in its verbose mode (given by /V), HELPMAKE can generate a lengthy log.
  16331.  
  16332.    HELPMAKE /V /E /Omy.hlp my.txt > my.log
  16333.  
  16334.  The example below invokes HELPMAKE to decode the help database  my.hlp into
  16335.  the text file  my.src, given with the /O option. Once again, the /V option
  16336.  results in verbose output, and the output is directed to the log file
  16337.  my.log. Section 11.3.2 describes additional options for decoding.
  16338.  
  16339.    HELPMAKE /V /D /Omy.src my.hlp > my.log
  16340.  
  16341.  
  16342.  11.3  HELPMAKE Options
  16343.  
  16344.  HELPMAKE accepts the command-line options described below. You can specify
  16345.  options in uppercase or lowercase letters and precede them with either a
  16346.  forward slash ( / ) or a dash ( - ). Most options apply only to encoding,
  16347.  others apply only to decoding, and a few apply to both. The /T option is
  16348.  required if you want to use dot commands with the QuickHelp format (which is
  16349.  the default format).
  16350.  
  16351.  
  16352.  11.3.1  Options for Encoding
  16353.  
  16354.  When you encode a file─that is, when you build a help database─you must
  16355.  specify the /E option. HELPMAKE also accepts other options to control
  16356.  encoding. The encoding options are listed below:
  16357.  
  16358. ╓┌───────────┌───────────────────────────────┌───────────────────────────────╖
  16359.  Option      Action
  16360.  ────────────────────────────────────────────────────────────────────────────
  16361.  Option      Action
  16362.  ────────────────────────────────────────────────────────────────────────────
  16363.  /Ac         Specifies c as an
  16364.              application-specific control
  16365.              character for the help
  16366.              database file. The character
  16367.              marks a line that contains
  16368.              special information for
  16369.              internal use by the
  16370.              application. For example, the
  16371.              Microsoft Advisor uses the
  16372.              colon (:).
  16373.  
  16374.  /C          Makes context strings for this
  16375.              help file case sensitive.
  16376.  
  16377.  /E«n»       Creates (encodes) a help
  16378.              database from a specified text
  16379.              file. The n specifies the
  16380.              type(s) of compression. If n
  16381.              is omitted, HELPMAKE
  16382.  Option      Action
  16383.  ────────────────────────────────────────────────────────────────────────────
  16384.             is omitted, HELPMAKE
  16385.              compresses the file as much as
  16386.              possible (about 50%). The
  16387.              value of n is in the range 0
  16388.              -15. It is the sum of
  16389.              successive integral powers of
  16390.              2 representing various
  16391.              compression techniques:
  16392.  
  16393.              Value                           Technique
  16394.  
  16395.              0                               No compression
  16396.  
  16397.              1                               Run-length compression
  16398.  
  16399.              2                               Keyword compression
  16400.  
  16401.              4                               Extended keyword compression
  16402.  
  16403.  Option      Action
  16404.  ────────────────────────────────────────────────────────────────────────────
  16405. 
  16406.              8                               Huffman compression
  16407.  
  16408.              Add values to combine
  16409.              compression techniques. For
  16410.              example, use / E3 to get
  16411.              run-length and keyword compres-
  16412.  
  16413.              sion. Use / E0 in the testing
  16414.              stages of help database
  16415.              creation where you need to
  16416.              create the database quickly
  16417.              and are not yet concerned with
  16418.              size.
  16419.  
  16420.  /Kfilename  Optimizes keyword compression
  16421.              by supplying a list of
  16422.              characters that act as word
  16423.              separators. The filename is a
  16424.  Option      Action
  16425.  ────────────────────────────────────────────────────────────────────────────
  16426.             separators. The filename is a
  16427.              file containing your list of
  16428.              separator characters.
  16429.  
  16430.  
  16431.              The / E2 and / E3 options tell
  16432.              HELPMAKE to identify
  16433.              "keywords"─words occurring
  16434.              often enough to justify
  16435.              replacing them with shorter
  16436.              character sequences. A word is
  16437.              any series of characters that
  16438.              do not appear in the separator
  16439.              list. The default separator
  16440.              list includes all ASCII
  16441.              characters from 0 to 32, ASCII
  16442.              character 127, and the
  16443.              following characters:
  16444.  
  16445.  Option      Action
  16446.  ────────────────────────────────────────────────────────────────────────────
  16447. 
  16448.              ! " # & ` ' ( ) * + - , / : ;
  16449.              < = > ? @ [ \ ] ^ _ { | } ~
  16450.  
  16451.              You can improve keyword
  16452.              compression by designing a
  16453.              separator list tailored to a
  16454.              specific help file. If your
  16455.              help file contains #include
  16456.              directives, #include is
  16457.              encoded (by default) as
  16458.              include. To encode #include as
  16459.              a keyword, create a separator
  16460.              list that omits the #:
  16461.  
  16462.              !   " & ` ' ( ) * + - , / : ;
  16463.              < = > ? @ [ \ ] ^ _ { | } ~
  16464.  
  16465.              Characters in the range 0 -31
  16466.  Option      Action
  16467.  ────────────────────────────────────────────────────────────────────────────
  16468.             Characters in the range 0 -31
  16469.              are always separators, so you
  16470.              need not include them. A
  16471.              customized list must include
  16472.              all other separators, however,
  16473.              including the space (which
  16474.              follows ! in the list above).
  16475.              If you omit the space,
  16476.              HELPMAKE encodes sequences of
  16477.              words as keywords.
  16478.  
  16479.  /L          Locks the generated file so
  16480.              that it cannot later be
  16481.              decoded.
  16482.  
  16483.  /NOLOGO     Suppresses the HELPMAKE
  16484.              copyright message.
  16485.  
  16486.  /Ooutfile   Specifies outfile as the name
  16487.  Option      Action
  16488.  ────────────────────────────────────────────────────────────────────────────
  16489. /Ooutfile   Specifies outfile as the name
  16490.              of the help database.
  16491.  
  16492.  /Sn         Specifies the type of input
  16493.              file, according to the
  16494.              following n values:
  16495.  
  16496.              Option                          File Type
  16497.  
  16498.              /S1                             Rich Text Format (RTF)
  16499.  
  16500.              /S2                             QuickHelp (default)
  16501.  
  16502.              /S3                             Minimally formatted ASCII
  16503.  
  16504.  /T          Translates dot commands into
  16505.              internal format. If your help
  16506.              file contains dot commands
  16507.              other than .context and
  16508.  Option      Action
  16509.  ────────────────────────────────────────────────────────────────────────────
  16510.             other than .context and
  16511.              .comment, you must supply this
  16512.              option when encoding it. Dot
  16513.              commands are described in
  16514.              Section 11.6.1,"QuickHelp
  16515.              Format," and in later sections.
  16516.              The /T option causes the
  16517.              option /A: to be assumed.
  16518.  
  16519.  
  16520.  /V«n»       Controls verbosity of
  16521.              diagnostic and informational
  16522.              output. Larger values of n add
  16523.              more information. Omitting n
  16524.              produces a full listing. The
  16525.              values of n are listed below:
  16526.  
  16527.              Option                          Output
  16528.  
  16529.  Option      Action
  16530.  ────────────────────────────────────────────────────────────────────────────
  16531. 
  16532.              /V                              Maximum diagnostic output
  16533.  
  16534.              /V0                             No diagnostic output and no
  16535.                                              banner
  16536.  
  16537.              /V1                             HELPMAKE banner only
  16538.  
  16539.              /V2                             Pass names
  16540.  
  16541.              /V3                             Contexts on first pass
  16542.  
  16543.              /V4                             Contexts on each pass
  16544.  
  16545.              /V5                             Any intermediate steps within
  16546.                                              each pass
  16547.  
  16548.              /V6                             Statistics on help file and
  16549.                                              compression
  16550.  Option      Action
  16551.  ────────────────────────────────────────────────────────────────────────────
  16552.                                             compression
  16553.  
  16554.  /Wwidth     Indicates the fixed width of
  16555.              the resulting help text in
  16556.              number of characters. The
  16557.              value of width can range from
  16558.              11 to 255. If the /W option is
  16559.              omitted, the default is 76.
  16560.              When encoding an RTF source
  16561.              (/S1), HELPMAKE automatically
  16562.              formats the text to width.
  16563.              When encoding QuickHelp (/S2)
  16564.              or minimally formatted ASCII
  16565.              (/S3) files, HELPMAKE
  16566.              truncates lines to this width.
  16567.  
  16568.  
  16569.  
  16570.  
  16571.  11.3.2  Options for Decoding
  16572.  
  16573.  The /D option decodes a help database into QuickHelp files. HELPMAKE also
  16574.  accepts other options to control decoding. The decoding options are listed
  16575.  below:
  16576.  
  16577. ╓┌────────────┌──────────────────────────────┌───────────────────────────────╖
  16578.  Option       Action
  16579.  ────────────────────────────────────────────────────────────────────────────
  16580.  /D«c»        Decodes the input file into
  16581.               its original text or
  16582.               component parts. If a
  16583.               destination file is not
  16584.               specified with the /O option,
  16585.               the help file is decoded to
  16586.               the standard output device.
  16587.               The form of decoding is
  16588.               controlled by the form of /D«
  16589.               c» specified:
  16590.  
  16591.               Form                           Effect
  16592.  Option       Action
  16593.  ────────────────────────────────────────────────────────────────────────────
  16594.              Form                           Effect
  16595.  
  16596.               /D                             Fully decodes the help
  16597.                                              database, leaving all
  16598.                                              cross-references and
  16599.                                              formatting information intact.
  16600.  
  16601.               /DS                            Splits a concatenated help
  16602.                                              database into its components
  16603.                                              using their original names. If
  16604.                                              the database was not created
  16605.                                              by concatenation, HELPMAKE
  16606.                                              copies it to a file with its
  16607.                                              original name. The database is
  16608.                                              not decompressed.
  16609.  
  16610.               /DU                            Decompresses the database and
  16611.                                              removes all screen formatting
  16612.                                              and cross-
  16613.  Option       Action
  16614.  ────────────────────────────────────────────────────────────────────────────
  16615.                                             and cross-
  16616.                                              references. The output can be
  16617.                                              used later for input and
  16618.                                              recompression, but all screen
  16619.                                              formatting and
  16620.                                              cross-references are lost.
  16621.  
  16622.               /NOLOGO                        Suppresses the HELPMAKE
  16623.                                              copyright message.
  16624.  
  16625.  /O«outfile»  Specifies outfile for the
  16626.               decoded output from HELPMAKE.
  16627.               If outfile is omitted, the
  16628.               help database is decoded to
  16629.               the standard output device.
  16630.               HELPMAKE always decodes help
  16631.               database files into QuickHelp
  16632.               format.
  16633.  
  16634.  Option       Action
  16635.  ────────────────────────────────────────────────────────────────────────────
  16636. 
  16637.  /T           Translates dot commands from
  16638.               internal format into
  16639.               dot-command format. You must
  16640.               always supply this option
  16641.               when decoding a help database
  16642.               that contains dot commands
  16643.               other than .context and
  16644.               .comment.
  16645.  
  16646.  
  16647.  
  16648.  
  16649.  /V«n»        Controls verbosity of
  16650.               diagnostic and informational
  16651.               output. Larger values of n
  16652.               add more information.
  16653.               Omitting n produces a full
  16654.               listing. The values of n are
  16655.  Option       Action
  16656.  ────────────────────────────────────────────────────────────────────────────
  16657.              listing. The values of n are
  16658.               listed below:
  16659.  
  16660.               Option                         Output
  16661.  
  16662.               /V                             Maximum diagnostic output
  16663.  
  16664.               /V0                            No diagnostic output and no
  16665.                                              banner
  16666.  
  16667.               /V1                            HELPMAKE banner only
  16668.  
  16669.               /V2                            Pass names
  16670.  
  16671.               /V3                            Contexts on first pass
  16672.  
  16673.  
  16674.  
  16675.  
  16676.  11.3.3  Options for Help
  16677.  
  16678.  The following are the options for help.
  16679.  
  16680.  Option                            Action
  16681.  ────────────────────────────────────────────────────────────────────────────
  16682.  / ?                               Displays a brief summary of HELPMAKE
  16683.                                    command-line syntax and exits without
  16684.                                    encoding or decoding any files. All
  16685.                                    other information on the command line is
  16686.  
  16687.                                    ignored.
  16688.  
  16689.  / «HELP»                          Calls the QuickHelp utility and displays
  16690.                                    help about HELPMAKE. If HELPMAKE cannot
  16691.                                    find QuickHelp or the help file, it
  16692.                                    displays the same information as with
  16693.                                    the /? option. No files are encoded or
  16694.                                    decoded. All other information on the
  16695.                                    command line is ignored.
  16696.  
  16697.  
  16698.  
  16699.  11.4  Creating a Help Database
  16700.  
  16701.  There are two ways to create a Microsoft-compatible help database.
  16702.  
  16703.  The first method is to decompress an existing help database, modify the
  16704.  resulting help text file, and recompress the help text file to form a new
  16705.  database.
  16706.  
  16707.  The second method is to append a new help database to an existing help
  16708.  database. This method involves the following steps:
  16709.  
  16710.  
  16711.    1.  Create a help text file in QuickHelp format, RTF, or minimally
  16712.        formatted ASCII.
  16713.  
  16714.    2.  Use HELPMAKE to create a help database file. The example below invokes
  16715.        HELPMAKE, using  yourhelp.txt  as the input file and producing a help
  16716.        database file named  yourhelp.hlp:
  16717.  
  16718.        HELPMAKE /V /E /Oyourhelp.hlp yourhelp.txt > yourhelp.log
  16719.  
  16720.  
  16721.    3.  Back up the existing database.
  16722.  
  16723.    4.  Append the new help database file to the existing database. The
  16724.        example below appends the new database  yourhelp.hlp  to the
  16725.        alang.hlp  database. (In the example, the / b modifier for the DOS
  16726.        COPY command combines the files as binary files.)
  16727.  
  16728.        COPY alang.hlp /b + yourhelp.hlp /b
  16729.  
  16730.  
  16731.    5.  Test the database. Assume  yourhelp.hlp  contains the context  sample.
  16732.        If you type  sample  in PWB and request help on it, the help window
  16733.        should display the text associated with the context  sample.
  16734.  
  16735.  
  16736.  ────────────────────────────────────────────────────────────────────────────
  16737.  WARNING
  16738.  
  16739.  The PWB editor truncates lines longer than about 250 characters. Some
  16740.  databases contain lines longer than this. To edit or create database files
  16741.  with extremely long lines, you must either use an editor (such as Microsoft
  16742.  Word) that does not restrict line length, or extend long lines using the
  16743.  backslash (\) line-continuation character.
  16744.  ────────────────────────────────────────────────────────────────────────────
  16745.  
  16746.  
  16747.  11.5  Help Text Conventions
  16748.  
  16749.  The source text that HELPMAKE uses to create Microsoft help databases must
  16750.  follow specific organizational conventions. The following sections explain
  16751.  these conventions.
  16752.  
  16753.  
  16754.  11.5.1  Structure of the Help Text File
  16755.  
  16756.  The Microsoft help system is simply a data-retrieval tool. It imposes no
  16757.  restrictions on the content or organization of help data. However, the
  16758.  HELPMAKE utility and the data-display routines in the help system expect a
  16759.  help file to follow a standard format. This section explains how to create
  16760.  correctly formatted help text files.
  16761.  
  16762.  In all three help text formats, the help text source file is a sequence of
  16763.  topics, each preceded by one or more context definitions. The following
  16764.  table lists the various formats and the corresponding context definition
  16765.  statements:
  16766.  
  16767.  Format                            Context Definition
  16768.  ────────────────────────────────────────────────────────────────────────────
  16769.  QuickHelp                         .context context
  16770.  
  16771.  RTF                               \ par >>context \ par
  16772.  
  16773.  Minimally formatted ASCII         >>context
  16774.  
  16775.  Unformatted ASCII                 None
  16776.  
  16777.  In QuickHelp format, each topic begins with one or more .context statements.
  16778.  These statements link the context string to its topic text. The topic text
  16779.  consists of all subsequent lines up to the next .context statement.
  16780.  
  16781.  In RTF format, each context definition must be in a paragraph of its own
  16782.  (denoted by \ par), beginning with the help delimiter (>>). As in QuickHelp,
  16783.  the topic text consists of all subsequent paragraphs up to the next context
  16784.  definition.
  16785.  
  16786.  In minimally formatted ASCII, each context definition must be on a separate
  16787.  line, and each must begin with the help delimiter (>>). As in RTF and
  16788.  QuickHelp files, all subsequent lines up to the next context definition
  16789.  constitute the topic text.
  16790.  
  16791.  See Section 11.6, "Using Help Database Formats," for detailed information
  16792.  about these three formats.
  16793.  
  16794.  ────────────────────────────────────────────────────────────────────────────
  16795.  WARNING
  16796.  
  16797.  HELPMAKE warns you if it encounters a duplicate context string definition
  16798.  within a given help source file. Each context string must be unique.
  16799.  ────────────────────────────────────────────────────────────────────────────
  16800.  
  16801.  
  16802.  11.5.2  Local Contexts
  16803.  
  16804.  Context strings beginning with the "at" sign (@) are "local." Making a
  16805.  context local saves file space and speeds access. However, local contexts
  16806.  cannot be cross-referenced with an implicit link, and they have no meaning
  16807.  outside the local file.
  16808.  
  16809.  When you use a local context, HELPMAKE does not generate a global context
  16810.  string (a context string that is known throughout the help system). Instead,
  16811.  it embeds an encoded cross-reference that has meaning only within the
  16812.  current context. For example,
  16813.  
  16814.    .context normal
  16815.    This is a normal topic, accessible by the context string "normal".
  16816.    [button\v@local\v] is a cross-reference to the following topic.
  16817.  
  16818.    .context @local
  16819.  
  16820.    This topic can be reached only by the explicit cross-reference
  16821.    in the previous topic (or by browsing the file sequentially).
  16822.  
  16823.  In the example above, the text  button\v@local\v  references  local  as a
  16824.  local context. If the user selects the text  button  or scrolls through the
  16825.  file, the help system displays the topic text that follows the context
  16826.  definition for  local. Because  local  is defined with the "at" sign @, it
  16827.  can be accessed only by a hyperlink within the same help file or by
  16828.  sequentially browsing the file.
  16829.  
  16830.  If you want a topic to be accessible in both local and global contexts, you
  16831.  simply mark the topic text with both global and local .context statements.
  16832.  For example, to make  topic  both global and local, add the following
  16833.  statements:
  16834.  
  16835.    .context topic
  16836.    .context @topic
  16837.  
  16838.  Naturally, both .context statements must appear immediately before the topic
  16839.  text to which they point.
  16840.  
  16841.  To create a context that begins with a literal @, precede it with a
  16842.  backslash ( \ ).
  16843.  
  16844.  
  16845.  11.5.3  Context Prefixes
  16846.  
  16847.  Microsoft help databases use several "context prefixes." A context prefix is
  16848.  a single letter followed by a period. It appears before a context string
  16849.  with a predefined meaning. These contexts may appear in the resulting text
  16850.  file when you decode a Microsoft help database.
  16851.  
  16852.  Context prefixes are used internally by Microsoft.
  16853.  
  16854.  Except for the h. prefix described below, the context prefixes are used by
  16855.  Microsoft to mark environment- or product-specific features. You would not
  16856.  normally add them to the help files you write.
  16857.  
  16858.  You can use the h. prefix to identify standard help-file contexts. For
  16859.  instance, h.default identifies the default help screen (the screen that
  16860.  normally appears when you select top-level help). Table 11.1 lists the
  16861.  standard h. contexts.
  16862.  
  16863.  Table 11.1  Standard h. Contexts
  16864.  
  16865. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  16866.  Context                           Description
  16867.  ────────────────────────────────────────────────────────────────────────────
  16868.  h.contents                        The table of contents for the help file.
  16869.                                    You should also define the string
  16870.                                    "contents" for direct reference to this
  16871.                                    context.
  16872.  
  16873.  h.default                         The default help screen, typically
  16874.                                    displayed when the user presses SHIFT+F1
  16875.                                    at the "top level" in some applications.
  16876.  
  16877.  h.index                           The index for the help file. You can
  16878.                                    also define the string "index" for
  16879.                                    direct reference to this context.
  16880.  
  16881.  h.notfound                        The help text displayed by some
  16882.                                    applications when the help system cannot
  16883.                                    find information about the requested
  16884.                                    context. The text could be an index of
  16885.                                    contexts, a topical list, or general
  16886.  Context                           Description
  16887.  ────────────────────────────────────────────────────────────────────────────
  16888.                                   contexts, a topical list, or general
  16889.                                    information about using help.
  16890.  
  16891.  h.pg#                             A specific page within the help file.
  16892.                                    This is used in response to a "go to
  16893.                                    page #" request.
  16894.  
  16895.  h.pg$                             The help text that is logically last in
  16896.                                    the file. This is used by some
  16897.                                    applications in response to a "go to the
  16898.                                    end" request made within the help window.
  16899.  
  16900.  h.pg1                             The help text that is logically first in
  16901.                                    the file. This is used by some
  16902.                                    applications in response to a "go to the
  16903.                                    beginning" request made within the help
  16904.                                    window.
  16905.  
  16906.  h.title                           The title of the help database.
  16907.  Context                           Description
  16908.  ────────────────────────────────────────────────────────────────────────────
  16909. h.title                           The title of the help database.
  16910.  
  16911.  ────────────────────────────────────────────────────────────────────────────
  16912.  
  16913.  
  16914.  
  16915.  The context prefixes in Table 11.2 are internal to Microsoft products. They
  16916.  appear in decompressed databases, but you do not need to use them.
  16917.  
  16918.  Table 11.2  Microsoft Product Context Prefixes
  16919.  
  16920. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  16921.  Prefix                            Purpose
  16922.  ────────────────────────────────────────────────────────────────────────────
  16923.  d.                                Dialog box. Each dialog box is assigned
  16924.                                    a number. Its help context string is d.
  16925.                                    followed by the number (for example,
  16926.                                    d.12).
  16927.  
  16928.  Prefix                            Purpose
  16929.  ────────────────────────────────────────────────────────────────────────────
  16930. 
  16931.  e.                                Error number. If a product supports the
  16932.                                    error-numbering scheme used by Microsoft
  16933.                                    languages, it displays help for each
  16934.                                    error using this prefix. For example,
  16935.                                    the context  e.P0105  refers to the
  16936.                                    Microsoft QuickPascal Compiler error
  16937.                                    message number P0105.
  16938.  
  16939.  h.                                Help item. Prefixes miscellaneous help
  16940.                                    context strings that may be constructed
  16941.                                    or otherwise hidden from the user. For
  16942.                                    example, most applications look for the
  16943.                                    context string h.contents when Contents
  16944.                                    is chosen from the Help menu.
  16945.  
  16946.  m.                                Menu item. Contexts that relate to
  16947.                                    product menu items are defined by their
  16948.                                    shortcut keys. For example, the Exit
  16949.  Prefix                            Purpose
  16950.  ────────────────────────────────────────────────────────────────────────────
  16951.                                   shortcut keys. For example, the Exit
  16952.                                    selection on the File menu item is
  16953.                                    accessed by ALT+F, X and is referenced
  16954.                                    in help by  m.f.x.
  16955.  
  16956.  n.                                Message number. Each message box is
  16957.                                    assigned a number. Its help context
  16958.                                    string is n. plus the number (for
  16959.                                    example,  n.5).
  16960.  
  16961.  ────────────────────────────────────────────────────────────────────────────
  16962.  
  16963.  
  16964.  
  16965.  
  16966.  11.5.4  Hyperlinks
  16967.  
  16968.  Explicit cross-references, or hyperlinks, are marked with invisible text in
  16969.  the help text file. A hyperlink is a word or phrase followed by invisible
  16970.  text that names the context to which the hyperlink refers.
  16971.  
  16972.  The keystroke that activates the hyperlink depends on the application.
  16973.  Consult the documentation for each product for the specific keystroke.
  16974.  
  16975.  When the user activates the hyperlink, the help system displays the topic
  16976.  referenced by the invisible text. The invisible cross-reference text is
  16977.  formatted as one of the following:
  16978.  
  16979.  Hidden Text                       Action
  16980.  ────────────────────────────────────────────────────────────────────────────
  16981.  contextstring                     Displays the topic associated with
  16982.                                    contextstring. For example,  exeformat
  16983.                                    displays the topic text for the context
  16984.                                    exeformat.
  16985.  
  16986.  filename!                         Treats filename as a single topic to be
  16987.                                    displayed. For example,
  16988.                                    $INCLUDE:stdio.h!  searches the
  16989.                                    directories in the INCLUDE environment
  16990.                                    variable for file  stdio.h  and displays
  16991.                                    it as a single help topic.
  16992.  
  16993.  filename!contextstring            Works the same as contextstring, except
  16994.                                    only the help file filename is searched
  16995.                                    for the context. If the file is not
  16996.                                    already open, the help system finds it
  16997.                                    (by searching either the current path or
  16998.                                    an explicit environment variable) and
  16999.                                    opens it. For example,
  17000.                                    $BIN:readme.doc!patches  searches for
  17001.                                    readme.doc  in the BIN environment
  17002.                                    variable and displays the topic
  17003.                                    associated with  patches.
  17004.  
  17005.  !command                          Executes the command specified after the
  17006.                                    exclamation point (!).
  17007.  
  17008.  In the following example, the word  Example  is a hyperlink. The \b,\p, and
  17009.  \v formatting flags mark hyperlinks in the help text. (The formatting flags
  17010.  are listed later in this chapter, in Table 11.4.)
  17011.  
  17012.    \bSee also:\p    Example\vopen.ex\v
  17013.  
  17014.  The hyperlink refers to  open.ex. If you select any of the letters of
  17015.  Example, the help system displays the topic whose context is  open.ex. On
  17016.  the screen, this line appears as follows:
  17017.  
  17018.    See also: Example
  17019.  
  17020.  An application might display  See also:  and  Example  in different colors
  17021.  or character types, depending on factors such as your default color
  17022.  selection and type of monitor.
  17023.  
  17024.  When a hyperlink needs to cross-reference more than one word, you must use
  17025.  an anchor, as in the following example:
  17026.  
  17027.    \bSee also:\p   \uExample\p\vprintf.ex\v, fprintf, scanf, sprintf,
  17028.    vfprintf, vprintf, vsprintf
  17029.                \aformatting table\vprintf.table\v
  17030.  
  17031.  This part of the example is an anchored hyperlink:
  17032.  
  17033.    \aformatting table\vprintf.table\v
  17034.  
  17035.  The anchor must fit on one line.
  17036.  
  17037.  The \ a flag creates an anchor for the cross-reference. In the example, the
  17038.  phrase following the \ a flag (formatting table) is the hyperlink. It refers
  17039.  to the context  printf.table. The first \v flag marks both the end of the
  17040.  hyperlink and the beginning of the invisible text. The name  printf.table
  17041.  is invisible; it does not appear on the screen when the help is displayed.
  17042.  The second \v flag ends the invisible text.
  17043.  
  17044.  
  17045.  11.6  Using Help Database Formats
  17046.  
  17047.  A database can be written in any of three text formats. The list below
  17048.  briefly describes these types. Sections 11.6.1-11.6.3 describe the
  17049.  formatting types in detail.
  17050.  
  17051.  An entire help system (such as the one supplied with PWB or QuickC) can
  17052.  handle any combination of formats. For example, the help files for Microsoft
  17053.  C are written in QuickHelp format, and the README.DOC file is unformatted
  17054.  ASCII.
  17055.  
  17056.  Type                              Characteristics
  17057.  ────────────────────────────────────────────────────────────────────────────
  17058.  QuickHelp                         Uses dot commands and embedded
  17059.                                    formatting characters (the default
  17060.                                    formatting type expected by HELPMAKE);
  17061.                                    supports highlighting, color, and
  17062.                                    cross-references. Files in this format
  17063.                                    must be compressed before use.
  17064.  
  17065.  RTF                               Uses a subset of standard RTF; supports
  17066.                                    highlighting, color, and
  17067.                                    cross-references; supports some dot
  17068.                                    commands. Files in this format must be
  17069.                                    compressed before use.
  17070.  
  17071.  Minimally formatted ASCII         Uses a help delimiter (>>) to define
  17072.                                    help contexts; does not support
  17073.                                    highlighting, color, or crossreferences.
  17074.                                    Files in this format can be compressed,
  17075.                                    but compression is not required.
  17076.  
  17077.  
  17078.  11.6.1  QuickHelp Format
  17079.  
  17080.  The QuickHelp format uses a dot command and embedded formatting flags to
  17081.  convey information to HELPMAKE.
  17082.  
  17083.  
  17084.  11.6.1.1  QuickHelp Dot Commands
  17085.  
  17086.  QuickHelp provides a number of dot commands that identify topics and convey
  17087.  other topic-related information to the help system. If your help file
  17088.  contains dot commands other than .context or .comment, you must supply the /
  17089.  T option when encoding and decoding with HELPMAKE.
  17090.  
  17091.  You can define more than one context for a single topic.
  17092.  
  17093.  The most important dot command is the .context command. Every topic in a
  17094.  QuickHelp file begins with one or more .context commands. Each .context
  17095.  command defines a context string for the topic text. You can define more
  17096.  than one context for a single topic, as long as you do not place any topic
  17097.  text between them.
  17098.  
  17099.  Typical .context commands are shown below. The first defines a context for
  17100.  the  #include C preprocessor directive. The second set illustrates multiple
  17101.  contexts for one block of topic text. In this case, the same topic text
  17102.  explains all of the string-to-number conversion routines in C.
  17103.  
  17104.    .context #include
  17105.           .
  17106.           . description of #include goes here
  17107.           .
  17108.    .context strtod
  17109.    .context strtol
  17110.    .context strtoul
  17111.           .
  17112.           . description of string-to-number functions goes here
  17113.           .
  17114.  
  17115.  The QuickHelp format includes several other dot commands. Table 11.3 lists
  17116.  the dot commands available in QuickHelp format.
  17117.  
  17118.  Table 11.3  QuickHelp Dot Commands
  17119.  
  17120. ╓┌─────────────────────────────────────┌─────────────────────────────────────╖
  17121.  Command                               Action
  17122.  ────────────────────────────────────────────────────────────────────────────
  17123.  .category string                      Lists the category in which the
  17124.                                        current topic appears and its
  17125.                                        position in the list of topics. The
  17126.                                        category name is used by the
  17127.                                        QuickHelp Categories command, which
  17128.                                        displays the topics list. Supported
  17129.                                        only by QuickHelp.
  17130.  
  17131.  .command                              Indicates that the topic text is not
  17132.                                        a displayable help topic. Use this
  17133.                                        command to hide hyperlink topics and
  17134.                                        other internal information.
  17135.  
  17136.  .comment string                       The string is a comment that appears
  17137.  .. string                             only in the help source file.
  17138.  Command                               Action
  17139.  ────────────────────────────────────────────────────────────────────────────
  17140. .. string                             only in the help source file.
  17141.                                        Comments are not inserted in the
  17142.                                        help database, so they cannot be
  17143.                                        restored when you decompress a help
  17144.                                        file.
  17145.  
  17146.  .context string                       The string introduces a topic.
  17147.  
  17148.  .end                                  Ends a paste section. See the .paste
  17149.                                        command below. Supported only by
  17150.                                        QuickHelp.
  17151.  
  17152.  .freeze numlines                      Locks the first numlines lines at
  17153.                                        the top of the screen. This can be
  17154.                                        used to preserve a bar of
  17155.                                        cross-reference buttons for a help
  17156.                                        topic and prevent it from being
  17157.                                        scrolled.
  17158.  
  17159.  Command                               Action
  17160.  ────────────────────────────────────────────────────────────────────────────
  17161. 
  17162.  .length topiclength                   Indicates the default window size,
  17163.                                        in topiclength lines, of the topic
  17164.                                        about to be displayed.
  17165.  
  17166.  .line number                          Tells HELPMAKE to reset the line
  17167.                                        number to begin at number for
  17168.                                        subsequent lines of the input file.
  17169.                                        Line numbers appear in HELPMAKE
  17170.                                        error messages. HELPMAKE does not
  17171.                                        put the .line command into the help
  17172.                                        database, so it is not restored
  17173.                                        during decompression. See .source.
  17174.  
  17175.  .list                                 Indicates that the current topic
  17176.                                        contains a list of topics. QuickHelp
  17177.                                        displays a highlighted line; you can
  17178.                                        choose a topic by moving the
  17179.                                        highlighted line over the desired
  17180.  Command                               Action
  17181.  ────────────────────────────────────────────────────────────────────────────
  17182.                                       highlighted line over the desired
  17183.                                        topic and pressing ENTER. Help
  17184.                                        searches for the first word of the
  17185.                                        line. Supported only by QuickHelp.
  17186.  
  17187.  .mark name «column»                   Defines a mark immediately preceding
  17188.                                        the following line of text. The
  17189.                                        marked line shows a script command
  17190.                                        where the display of a topic begins.
  17191.                                        The name identifies the mark. The
  17192.                                        column is an integer value
  17193.                                        specifying a column location within
  17194.                                        the marked line. Supported only by
  17195.                                        QuickHelp.
  17196.  
  17197.  
  17198.  
  17199.  
  17200.  .next context                         Tells the help system to look up the
  17201.  Command                               Action
  17202.  ────────────────────────────────────────────────────────────────────────────
  17203. .next context                         Tells the help system to look up the
  17204.                                        next topic using
  17205.                                        context instead of the topic that
  17206.                                        physically follows it in the file.
  17207.                                        You can use this command to skip
  17208.                                        large blocks of .command or .popup
  17209.                                        topics.
  17210.  
  17211.  .paste pastename                      Begins a paste section. The
  17212.                                        pastename appears in the QuickHelp
  17213.                                        Paste menu. Supported only by
  17214.                                        QuickHelp.
  17215.  
  17216.  .popup                                Tells the help system to display the
  17217.                                        current topic as a popup instead of
  17218.                                        a normal, scrollable topic.
  17219.                                        Supported only by QuickHelp.
  17220.  
  17221.  .previous context                     Tells the help system to look up the
  17222.  Command                               Action
  17223.  ────────────────────────────────────────────────────────────────────────────
  17224. .previous context                     Tells the help system to look up the
  17225.                                        previous topic using context instead
  17226.                                        of the topic that physically
  17227.                                        precedes it in the file. You can use
  17228.                                        this command to skip large blocks of
  17229.                                        .command or .popup topics.
  17230.  
  17231.  .raw                                  Turns off special processing of
  17232.                                        certain characters by the
  17233.                                        application.
  17234.  
  17235.  .ref topic «, topic» ...              Tells the help system to display the
  17236.                                        topic in the Reference menu. You can
  17237.                                        list as many topics as needed;
  17238.                                        separate each additional topic with
  17239.                                        a comma. A .ref command is formatted
  17240.                                        without regard to the /W option.
  17241.                                        Supported only by QuickHelp.
  17242.  
  17243.  Command                               Action
  17244.  ────────────────────────────────────────────────────────────────────────────
  17245. 
  17246.                                        If no topic is specified, QuickHelp
  17247.                                        searches the line immediately
  17248.                                        following for a See: or See Also:
  17249.                                        reference; if present, the reference
  17250.                                        must be the first non-white-space
  17251.                                        characters on the line.
  17252.  
  17253.  .source filename                      Tells HELPMAKE that subsequent
  17254.                                        topics come from filename. By
  17255.                                        default, when an error occurs, the
  17256.                                        error message contains the name and
  17257.                                        line number of the input file. The
  17258.                                        .source command tells HELPMAKE to
  17259.                                        use filename in the error message
  17260.                                        instead of the name of the input
  17261.                                        file and to reset the line number to
  17262.                                        1. This is useful when you
  17263.                                        concatenate several sources to form
  17264.  Command                               Action
  17265.  ────────────────────────────────────────────────────────────────────────────
  17266.                                       concatenate several sources to form
  17267.                                        the input file. HELPMAKE does not
  17268.                                        put the .source command into the
  17269.                                        help database, so it is not restored
  17270.                                        during decompression. See .line.
  17271.  
  17272.  .topic text                           Defines text as the name or title to
  17273.                                        be displayed in place of the context
  17274.                                        string if the application help
  17275.                                        displays a title. This command is
  17276.                                        always the first line in the context
  17277.                                        unless you also use the .length or
  17278.                                        .freeze commands.
  17279.  
  17280.  ────────────────────────────────────────────────────────────────────────────
  17281.  
  17282.  
  17283.  
  17284.  
  17285.  11.6.1.2  QuickHelp Formatting Flags
  17286.  
  17287.  The QuickHelp format provides a number of formatting flags that are used to
  17288.  highlight parts of the help database and to mark hyperlinks in the help
  17289.  text.
  17290.  
  17291.  Each formatting flag consists of a backslash ( \ ) followed by a character.
  17292.  Table 11.4 lists the formatting flags.
  17293.  
  17294.  Table 11.4  QuickHelp Formatting Flags
  17295.  
  17296. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  17297.  Formatting Flag                   Action
  17298.  ────────────────────────────────────────────────────────────────────────────
  17299.  \ a                               Anchors text for cross-references
  17300.  
  17301.  \ b, \ B                          Turns boldface on or off
  17302.  
  17303.  \ i, \ I                          Turns italics on or off
  17304.  
  17305.  \ p, \ P                          Turns off all attributes
  17306.  Formatting Flag                   Action
  17307.  ────────────────────────────────────────────────────────────────────────────
  17308. \ p, \ P                          Turns off all attributes
  17309.  
  17310.  \ u, \ U                          Turns underlining on or off
  17311.  
  17312.  \ v, \V                           Turns invisibility on or off
  17313.                                    (hides cross-references in text)
  17314.  
  17315.  \\                                Inserts a single backslash in text
  17316.  
  17317.  ────────────────────────────────────────────────────────────────────────────
  17318.  
  17319.  
  17320.  
  17321.  On monochrome monitors, text labeled with the bold, italic, and underline
  17322.  attributes appears in various ways, depending on the application (for
  17323.  example, high intensity and reverse video are commonly displayed). On color
  17324.  monitors, these attributes are translated by the application into suitable
  17325.  colors, depending on the user's default color selections.
  17326.  
  17327.  The \ b, \ i, \ u, and \v options are toggles, turning on and off their
  17328.  respective attributes. You can use several of these on the same text. Use
  17329.  the \ p attribute to turn off all attributes. Use the \v attribute to hide
  17330.  cross-references and hyperlinks in the text.
  17331.  
  17332.  HELPMAKE truncates the lines in QuickHelp files to the width specified with
  17333.  the / W option. Only visible characters count toward the character-width
  17334.  limit. Lines that begin with an application-specific control character are
  17335.  truncated to 255 characters regardless of the width specification. See
  17336.  Section 11.3.1, "Options for Encoding," for more information on truncation
  17337.  and application-specific control characters.
  17338.  
  17339.  In the example below, the \ b flag initiates boldface text for  Returns:,
  17340.  and the \ p flag changes the remaining text to plain text.
  17341.  
  17342.    \bReturns:\p    a handle if successful, or -1 if not.
  17343.                errno:  EACCES, EEXIST, EMFILE, ENOENT
  17344.  
  17345.  In the example below, the \ a flag anchors text for the hyperlink  Example.
  17346.  The \v flags define the cross-reference  sample_prog  and make the text
  17347.  between the \v flags invisible. Cross-references are described in the
  17348.  following section.
  17349.  
  17350.    \aExample \vsample_prog\v
  17351.  
  17352.  
  17353.  11.6.1.3  QuickHelp Cross-References
  17354.  
  17355.  Help databases contain two types of cross-references, implicit and explicit.
  17356.  They are described in Section 11.1.1, "Contents of a Help File."
  17357.  
  17358.  Any word that appears as a global context is implicitly cross-referenced.
  17359.  For example, any time you request help in PWB on close, the help window
  17360.  displays information about that function. You do not code implicit
  17361.  cross-references into your help text files.
  17362.  
  17363.  Insert formatting flags to mark explicit cross-references.
  17364.  
  17365.  Explicit cross-references (hyperlinks) are words or phrases on the screen
  17366.  that point to a context. For example, almost every "See:" and "See also:"
  17367.  reference in online help has a hyperlink pointing to the appropriate
  17368.  context. You can view the cross-referenced material immediately by
  17369.  activating the hyperlink, without having to search the help system's menus
  17370.  for the topic. You must insert formatting flags in your help text files to
  17371.  mark explicit cross-references.
  17372.  
  17373.  If the hyperlink consists of a single word, you can use invisible text to
  17374.  flag it in the source file. The \v formatting flag creates invisible text,
  17375.  as follows:
  17376.  
  17377.    hyperlink\vcontext\v
  17378.  
  17379.  Put the first \v flag immediately following the word you want to be the
  17380.  hyperlink. Following the flag, insert the context that the hyperlink points
  17381.  to. The second \v flag marks the end of the context; that is, the end of the
  17382.  invisible text. HELPMAKE generates a cross-reference whose context is the
  17383.  invisible text and whose hyperlink is the word.
  17384.  
  17385.  If the hyperlink consists of a phrase, rather than a single word, you must
  17386.  use anchored text to create explicit cross-references. Use the \ a and \v
  17387.  flags to create anchored text as follows:
  17388.  
  17389.    \ahyperlink-words\vcontext\v
  17390.  
  17391.  The \ a flag marks an anchor for the cross-reference. The text that follows
  17392.  the \ a flag is the hyperlink. The hyperlink must fit entirely on one line.
  17393.  The first \v flag marks both the end of the hyperlink and the beginning of
  17394.  the invisible text that contains the cross-reference context. The second \v
  17395.  flag marks the end of the invisible text.
  17396.  
  17397.  The C functions abs, cabs, and fabs in the following examples are implicit
  17398.  cross-references because they have a global context in the help system.
  17399.  
  17400.    See also: abs, cabs, fabs
  17401.  
  17402.  The next example shows the encoding for an explicit cross-reference to an
  17403.  example program and a function template from the help database for the
  17404.  Microsoft C run-time library:
  17405.  
  17406.    See also: Example\vopen.ex\v, Template\vopen.tm\v, close
  17407.  
  17408.  Here, the hyperlinks are  Example  and  Template, which reference the
  17409.  contexts  open.ex  and  open.tm. The example also contains an implicit
  17410.  cross-reference to the close function.
  17411.  
  17412.  The final example shows the encoding for an explicit cross-reference to an
  17413.  entire family of functions:
  17414.  
  17415.    See also: \ais... functions\vis_functions\v, atoi
  17416.  
  17417.  The cross-reference uses anchored text to associate a phrase, rather than
  17418.  just a word, with a context. In this example, the hyperlink is the anchored
  17419.  phrase  is... functions, and it cross-references the context  is_functions.
  17420.  In addition, the example contains an implicit cross-reference to the
  17421.  C-language atoi routine.
  17422.  
  17423.  
  17424.  11.6.1.4  QuickHelp Example
  17425.  
  17426.  The code below is an example in QuickHelp format that contains a single
  17427.  entry:
  17428.  
  17429.    .context open
  17430.    .length 13
  17431.    \bInclude:\p   <fcntl.h>, <io.h>, <sys\\types.h>, <sys\\stat.h>
  17432.  
  17433.    \bPrototype:\p  int open(char *path, int flag[, int mode]);
  17434.             oflag:  O_APPEND O_BINARY O_CREAT O_EXCL O_RDONLY
  17435.                     O_RDWR    O_TEXT    O_TRUNC  O_WRONLY
  17436.                     (can be joined by |)
  17437.             pmode:  S_IWRITE  S_IREAD   S_IREAD | S_IWRITE
  17438.  
  17439.    \bReturns:\p    a handle if successful, or -1 if not.
  17440.                errno:  EACCES, EEXIST, EMFILE, ENOENT
  17441.  
  17442.    \bSee also:\p  \uExample\p\vopen.ex\v, \uTemplate\p\vopen.tp\v,
  17443.                 access, chmod, close, creat, dup, dup2, fopen, sopen,
  17444.    umask
  17445.  
  17446.  The .length command near the beginning of the example specifies the size of
  17447.  the initial window for the help text. Here, the initial window displays 13
  17448.  lines.
  17449.  
  17450.  The manifest constants (such as O_WRONLY and EEXIST), the C keywords (such
  17451.  as int and char), and the other functions (such as access and sopen) are
  17452.  implicit cross-references. The words  Example  and  Template  are explicit
  17453.  cross-references to the example  open.ex  and to the open template  open.tp,
  17454.  respectively. Note the use of double backslashes in the include file names.
  17455.  
  17456.  
  17457.  
  17458.  11.6.2  Rich Text Format
  17459.  
  17460.  Rich Text Format (RTF) is a Microsoft word-processing format supported by
  17461.  several word processors, including Microsoft Word 5.0 and Microsoft Word for
  17462.  Windows. RTF allows documents to be transferred between applications without
  17463.  loss of formatting. The HELPMAKE utility recognizes a subset of the full RTF
  17464.  syntax. If your file contains RTF codes that are not part of the subset,
  17465.  HELPMAKE discards them.
  17466.  
  17467.  To create an RTF-formatted file, enter the text and format it as you want it
  17468.  to appear: bold, underlined, hidden, italic, and so forth. (You can combine
  17469.  attributes.) You can also format paragraphs, selecting body and first-line
  17470.  indenting. The only items you need to insert into an RTF file manually are
  17471.  the help delimiter (>>) and the context string that start each entry.
  17472.  
  17473.  When you have entered and formatted the text, save it in RTF format. In
  17474.  Microsoft Word 5.0, for example, this means choosing Transfer Save, then
  17475.  highlighting RTF in the format: field.
  17476.  
  17477.  You do not see the RTF formatting codes when you load an RTF file into a
  17478.  compatible word processor; the word processor removes them and displays the
  17479.  text with the specified attribute(s). However, you can view these codes by
  17480.  loading an RTF file into a plain-text word processor.
  17481.  
  17482.  HELPMAKE recognizes the subset of RTF codes listed in Table 11.5.
  17483.  
  17484.  Table   11.5 RTF Formatting Codes
  17485.  
  17486. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  17487.  RTF Code
  17488.  ────────────────────────────────────────────────────────────────────────────
  17489.  \ b                               Boldface. The application decides how to
  17490.                                    display this; often it is
  17491.                                    intensified text.
  17492.  
  17493.  \ fin                             Paragraph first-line indent, n columns.
  17494.  
  17495.  RTF Code
  17496.  ────────────────────────────────────────────────────────────────────────────
  17497. 
  17498.  \ i                               Italic. The application decides how to
  17499.                                    display this; often it is reverse video.
  17500.  
  17501.  \ lin                             Paragraph indent from left margin, n
  17502.                                    columns.
  17503.  
  17504.  \ line                            New line (not new paragraph).
  17505.  
  17506.  \ par                             End of paragraph.
  17507.  
  17508.  \ pard                            Default paragraph formatting.
  17509.  
  17510.  \ plain                           Default attributes. On most screens,
  17511.                                    this is nonblinking normal
  17512.                                    intensity.
  17513.  
  17514.  \ tab                             Tab character.
  17515.  
  17516.  RTF Code
  17517.  ────────────────────────────────────────────────────────────────────────────
  17518. 
  17519.  \ ul                              Underline. The application decides how
  17520.                                    to display this; some adapters that do
  17521.                                    not support underlining display it as
  17522.                                    blue text.
  17523.  
  17524.  \ v                               Hidden text. Hidden text is used for
  17525.                                    cross-reference information and for some
  17526.                                    application-specific communications; it
  17527.                                    is not
  17528.                                    displayed.
  17529.  
  17530.  ────────────────────────────────────────────────────────────────────────────
  17531.  
  17532.  
  17533.  
  17534.  When HELPMAKE compresses the file, it formats the text to the width given
  17535.  with the / W option, ignoring the paragraph formats.
  17536.  
  17537.  As with the other text formats, each entry in the database source consists
  17538.  of one or more context strings, followed by topic text. An RTF file can
  17539.  contain QuickHelp dot commands.
  17540.  
  17541.  The help delimiter (>>) at the beginning of any paragraph marks the
  17542.  beginning of a new help entry. The text that follows on the same line is
  17543.  defined as a context for the topic. If the next paragraph also begins with
  17544.  the help delimiter, it also defines a context string for the same topic
  17545.  text. You can define any number of contexts for a block of topic text. The
  17546.  topic text comprises all subsequent paragraphs up to the next paragraph that
  17547.  begins with the help delimiter.
  17548.  
  17549.  The example below is a help database containing a single entry using subset
  17550.  RTF text. Note that RTF uses curly braces ( { } ) for nesting. Thus, the
  17551.  entire file is enclosed in curly braces, as is each specially formatted text
  17552.  item.
  17553.  
  17554.    {\rtf1
  17555.    \pard >>open\par
  17556.      {\b Include:}    <fcntl.h>, <io.h>, <sys\\types.h>, <sys\\stat.h>\par
  17557.    \par
  17558.      {\b Syntax:}     int open( char * filename, int oflag[, int pmode
  17559.    ] );\par
  17560.                 oflag:  O_APPEND  O_BINARY  O_CREAT  O_EXCL  O_RDONLY\par
  17561.  
  17562.                         O_RDWR    O_TEXT    O_TRUNC  O_WRONLY\par
  17563.                         (may be joined by |)\par
  17564.                 pmode:  S_IWRITE  S_IREAD   S_IREAD | S_IWRITE\par
  17565.    \par
  17566.      {\b Returns:}    a handle if successful, or -1 if not.\par
  17567.                 errno:  EACCES, EEXIST, EMFILE, ENOENT\par
  17568.    \par
  17569.      {\b See also:}  Examples{\v open.ex}, access, chmod, close, creat,
  17570.    dup,\par
  17571.                 dup2, fopen, sopen, umask\par
  17572.    >>open.ex\par
  17573.    To build this help file, use the following command:\par
  17574.    \par
  17575.    HELPMAKE /S1 /E15 /OOPEN.HLP OPEN.RTF\par
  17576.    \par
  17577.  
  17578.            < Back >{\v !B}
  17579.    }
  17580.  
  17581.  RTF files normally contain additional information that is not visible to the
  17582.  user; HELPMAKE ignores this extra information.
  17583.  
  17584.  
  17585.  11.6.3  Minimally Formatted ASCII Format
  17586.  
  17587.  A minimally formatted ASCII text file comprises a sequence of topics, each
  17588.  preceded by one or more unique context definitions. Each context definition
  17589.  must be on a separate line beginning with a help delimiter (>>). Subsequent
  17590.  lines up to the next context definition constitute the topic text.
  17591.  
  17592.  Minimally formatted ASCII files cannot contain highlighting.
  17593.  
  17594.  There are two ways to use a minimally formatted ASCII file. You can compress
  17595.  it with HELPMAKE, creating a help database, or an application can access the
  17596.  uncompressed file directly. Compressing minimally formatted ASCII files
  17597.  increases search speed. Uncompressed files are somewhat larger and slower to
  17598.  search. Minimally formatted ASCII files have a fixed width, and they cannot
  17599.  contain highlighting (or other nondefault attributes) or explicit
  17600.  cross-references.
  17601.  
  17602.  The following example, coded in minimally formatted ASCII, shows the same
  17603.  text as the QuickHelp example presented earlier in this section. The first
  17604.  line of the example defines  open  as a context string. The minimally
  17605.  formatted ASCII help file must begin with the help delimiter (>>), so that
  17606.  HELPMAKE or the application can verify that the file is indeed an ASCII help
  17607.  file.
  17608.  
  17609.    >>>>open
  17610.  
  17611.    Include:    <fcntl.h>, <io.h>, <sys\types.h>, <sys\stat.h>
  17612.  
  17613.    Prototype:  int open(char *path, int flag[, int mode]);
  17614.           oflag:  O_APPEND  O_BINARY  O_CREAT  O_EXCL  O_RDONLY
  17615.                   O_RDWR    O_TEXT    O_TRUNC  O_WRONLY
  17616.                   (can be joined by |)
  17617.           pmode:  S_IWRITE  S_IREAD   S_IREAD | S_IWRITE
  17618.  
  17619.    Returns:    a handle if successful, or -1 if not.
  17620.                errno:  EACCES, EEXIST, EMFILE, ENOENT
  17621.  
  17622.    See also:  access, chmod, close, creat, dup, dup2, fopen, sopen,
  17623.    umask
  17624.  
  17625.  When displayed, the help information appears exactly as it is typed into the
  17626.  file. Any formatting codes are treated as ASCII text.
  17627.  
  17628.  
  17629.  11.7  Related Topics in Online Help
  17630.  
  17631.  Information on the following related topics can be found in online help.
  17632.  
  17633.  Topic       Access
  17634.  ────────────────────────────────────────────────────────────────────────────
  17635.  HELPMAKE    Choose "HELPMAKE" from the "Microsoft Advisor Contents" screen
  17636.  QuickHelp   Choose "QH" from the "Microsoft Advisor Contents" screen
  17637.  
  17638.  
  17639.  
  17640.  
  17641.  
  17642.  
  17643.  Chapter 12  Linking Object Files with LINK
  17644.  ────────────────────────────────────────────────────────────────────────────
  17645.  
  17646.  This chapter describes the Microsoft Segmented-Executable Linker (LINK),
  17647.  which combines compiled or assembled object files into an executable file.
  17648.  It explains LINK's input syntax and fields and tells how to use options to
  17649.  control LINK. It discusses overlays in DOS programs and concludes with
  17650.  background information about LINK.
  17651.  
  17652.  
  17653.  12.1  Overview
  17654.  
  17655.  LINK combines 80x86 object files into either an executable file or a
  17656.  dynamic-link library (DLL). The object-file format is the Microsoft
  17657.  Relocatable Object-Module Format (OMF), based on the Intel 8086 OMF. LINK
  17658.  uses library files in Microsoft library format.
  17659.  
  17660.  LINK creates "relocatable" executable files and DLLs─that is, the operating
  17661.  system can load and execute these files in any unused section of memory.
  17662.  LINK can create DOS executable files with up to 1 megabyte of code and data
  17663.  (or up to 16 megabytes when using overlays), or OS/2 and Microsoft Windows
  17664.  programs with up to 16 megabytes.
  17665.  
  17666.  For more information on OMF, executable-file format, and the linking
  17667.  process, see the MS-DOS Encyclopedia.
  17668.  
  17669.  Use BIND to create an OS/2 program that also runs under DOS.
  17670.  
  17671.  The linker produces programs that run under DOS only or under OS/2 only, but
  17672.  not both. However, if an OS/2 program limits its OS/2 function calls to the
  17673.  Family API subset, you can use the Microsoft Bind Utility (BIND) to modify
  17674.  the OS/2 executable file so that it runs under both OS/2 and DOS. For more
  17675.  information, see online help.
  17676.  
  17677.  Use EXEHDR to examine the finished file.
  17678.  
  17679.  When the file (either executable or DLL) is created, you can examine the
  17680.  information that LINK puts in the file's header by using the Microsoft EXE
  17681.  File Header Utility (EXEHDR). For more information, see online help.
  17682.  
  17683.  Other programs can call LINK automatically.
  17684.  
  17685.  The Programmer's WorkBench (PWB) invokes LINK to create the final executable
  17686.  file or DLL. Therefore, if you develop your software with PWB, you might not
  17687.  need to read this chapter. However, the detailed explanations of LINK
  17688.  options might be helpful when you use the LINK Options dialog box in PWB.
  17689.  This information is also available in online help.
  17690.  
  17691.  The compiler or assembler supplied with your language (CL with C, FL with
  17692.  FORTRAN, ML with MASM) also invokes LINK. You can use most of the LINK
  17693.  options described in this chapter with this utility. Online help has more
  17694.  information about the compilers and assembler: select help for the
  17695.  appropriate language from the Compiler box of the help Contents screen.
  17696.  
  17697.  ────────────────────────────────────────────────────────────────────────────
  17698.  NOTE
  17699.  
  17700.  Unless otherwise noted, all references to "library" in this chapter refer to
  17701.  a static library, either a standard library created by the Microsoft Library
  17702.  Manager (LIB) or an import library created by the Microsoft Import Library
  17703.  Manager (IMPLIB), and not a DLL.
  17704.  ────────────────────────────────────────────────────────────────────────────
  17705.  
  17706.  
  17707.  12.2  LINK Output Files
  17708.  
  17709.  LINK is a bound application that runs under both DOS and OS/2 and can create
  17710.  executable files for DOS, OS/2, or Windows. You do not have to run LINK
  17711.  under OS/2 to create OS/2 applications, or under DOS to create DOS programs.
  17712.  The kind of file produced is determined by the way the source code is
  17713.  compiled and the information supplied to LINK, not the operating system LINK
  17714.  runs under.
  17715.  
  17716.  A program that runs under DOS is called an executable file or application. A
  17717.  program or DLL that runs under Windows or OS/2 is called a segmented
  17718.  executable file. LINK creates the appropriate file according to the
  17719.  following rules:
  17720.  
  17721.  
  17722.    ■   If a module-definition file or import library is not specified and the
  17723.        object files and libraries do not contain export definitions, LINK
  17724.        creates an application that runs under DOS.
  17725.  
  17726.    ■   If a module-definition file containing a LIBRARY statement is
  17727.        specified, LINK creates a DLL for Windows or OS/2.
  17728.  
  17729.    ■   If any other form of module-definition file is specified, or if any of
  17730.        the object files contains an exported definition, LINK creates an
  17731.        application to run under Windows or OS/2.
  17732.  
  17733.  
  17734.  LINK looks for the default run-time libraries named in the object files.
  17735.  Default libraries can be real or protected mode. (The mode is usually set
  17736.  when the language product is installed.) Protected-mode libraries contain
  17737.  export definitions. If LINK finds protected-mode default libraries, the
  17738.  output file will be a segmented executable file rather than a DOS file.
  17739.  
  17740.  The file OS2.LIB is an import library. Linking with OS2.LIB produces an OS/2
  17741.  application or DLL. When you use a Microsoft high-level language to compile
  17742.  for protected mode, the compiler automatically specifies OS2.LIB as a
  17743.  default library.
  17744.  
  17745.  LINK's output is either an executable file or a DLL. For simplicity, this
  17746.  chapter sometimes refers to this output as the "main file" or "main output."
  17747.  
  17748.  
  17749.  Map files list the segments and symbols in a program.
  17750.  
  17751.  LINK also creates a "map" file, which lists the segments in the executable
  17752.  file. The /MAP option adds public symbols to the map file, and the /LINE
  17753.  option adds line numbers.
  17754.  
  17755.  LINK produces other files when certain options are used.
  17756.  
  17757.  Other options tell LINK to create other kinds of output files. The /INCR
  17758.  option creates .ILK and .SYM files for incremental linking with ILINK. LINK
  17759.  produces a .COM file instead of an .EXE file when the /TINY option is
  17760.  specified. The combination of /CO and /TINY puts debugging information into
  17761.  a .DBG file. A Quick library results when the /Q option is specified. For
  17762.  more information on these and other options, see Section 12.5, "LINK
  17763.  Options."
  17764.  
  17765.  
  17766.  12.3  LINK Syntax and Input
  17767.  
  17768.  The LINK command has the following syntax:
  17769.  
  17770.    LINK objfiles«, «exefile» «,
  17771.    «mapfile»«, «libraries»«, deffile»
  17772.    » » »«;»
  17773.  
  17774.  The LINK fields perform the following functions:
  17775.  
  17776.  
  17777.    ■   The objfiles field is a list of the object files that are to be linked
  17778.        into an executable file or DLL. It is the only required field.
  17779.  
  17780.    ■   The exefile field lets you change the name of the output file from its
  17781.        default.
  17782.  
  17783.    ■   The mapfile field gives the map file a name other than its default
  17784.        name.
  17785.  
  17786.    ■   The libraries field specifies additional (or replacement) libraries to
  17787.        search for unresolved references.
  17788.  
  17789.    ■   The deffile field gives the name of a description file needed to
  17790.        create Windows and OS/2 applications and DLLs.
  17791.  
  17792.  
  17793.  Fields are separated by commas. You can specify all the fields or leave one
  17794.  or more fields (including objfiles) blank; LINK will then prompt you for the
  17795.  missing input. (For an explanation of how to use LINK prompts, see Section
  17796.  12.4, "Running LINK.") To leave a field blank, enter only the field's
  17797.  trailing comma.
  17798.  
  17799.  Options can be specified in any field. For descriptions of each of LINK's
  17800.  options, see Section 12.5, "LINK Options."
  17801.  
  17802.  The fields must be entered in the order shown, whether they contain input or
  17803.  are left blank. A semicolon (;) at the end of the LINK command line
  17804.  terminates the command and suppresses prompting for any missing fields. LINK
  17805.  then assumes the default values for the missing fields.
  17806.  
  17807.  If your file appears in or is to be created in another directory or device,
  17808.  you must supply the full pathname. Filenames are not case sensitive.
  17809.  
  17810.  The next five sections explain how to use each of the LINK fields.
  17811.  
  17812.  
  17813.  12.3.1  The objfiles Field
  17814.  
  17815.  The objfiles field specifies one or more object files to be linked. At least
  17816.  one filename must be entered. If you do not supply an extension, LINK
  17817.  assumes a default .OBJ extension. If the filename has no extension, add a
  17818.  period (.) at the end of its name.
  17819.  
  17820.  If you name more than one object file, separate the names with a plus sign
  17821.  (+) or a space. To extend objfiles to the following line, type a plus sign
  17822.  (+) as the last character on the current line, press ENTER, and continue. Do
  17823.  not split a name across lines.
  17824.  
  17825.  
  17826.  12.3.1.1  Load Libraries
  17827.  
  17828.  The objfiles field can also specify library files. A library specified this
  17829.  way becomes a "load library." You must specify the library's filename
  17830.  extension; otherwise, LINK assumes an .OBJ extension.
  17831.  
  17832.  LINK treats load libraries as any other object file: it puts every object
  17833.  module from a load library in the executable file, regardless of whether a
  17834.  module satisfies an unresolved external reference. The effect is the same as
  17835.  if you had specified all the library's object-module names in the objfiles
  17836.  field.
  17837.  
  17838.  Specifying a load library can therefore create an executable file or DLL
  17839.  that is larger than it needs to be. (A library named in the libraries field
  17840.  adds only those modules required to resolve external references.) However,
  17841.  loading an entire library can be useful when
  17842.  
  17843.  
  17844.    ■   Repeatedly specifying the same group of object files
  17845.  
  17846.    ■   Placing a library in an overlay
  17847.  
  17848.    ■   Debugging, so you can call library routines that would not be included
  17849.        in the release version of the program
  17850.  
  17851.  
  17852.  
  17853.  12.3.1.2  How LINK Searches for Object Files
  17854.  
  17855.  When searching for object (and load-library) files, LINK looks in the
  17856.  following locations in the order specified:
  17857.  
  17858.  
  17859.    1.  The directory specified for the file (if a path is included). If the
  17860.        file is not in that directory, the search terminates.
  17861.  
  17862.    2.  The current directory.
  17863.  
  17864.    3.  Any directories specified in the LIB environment variable.
  17865.  
  17866.  
  17867.  If LINK cannot find an object file, and a floppy drive is associated with
  17868.  that object file, LINK pauses and prompts you to insert a disk containing
  17869.  the object file.
  17870.  
  17871.  If you specify a library in the objfiles field, LINK treats it like any
  17872.  other object file. LINK therefore does not search for load libraries in
  17873.  directories named in the libraries field.
  17874.  
  17875.  
  17876.  12.3.1.3  Overlays
  17877.  
  17878.  A special syntax for the objfiles field lets you create DOS programs that
  17879.  use overlay modules. For more information about overlays, see Section 12.7,
  17880.  "Using Overlays under DOS."
  17881.  
  17882.  
  17883.  12.3.2  The exefile Field
  17884.  
  17885.  The exefile field is used to specify a name for the main output file. If you
  17886.  do not supply an extension, LINK assumes a default extension, either .EXE,
  17887.  .COM (when using the /TINY option), .DLL (when using a module-definition
  17888.  file containing a LIBRARY statement), or .QLB (when using the /Q option).
  17889.  
  17890.  If you do not specify an exefile, LINK gives the main output a default name.
  17891.  This name is the base name of the first file listed in the objfiles field,
  17892.  plus the extension appropriate for the type of executable file being
  17893.  created.
  17894.  
  17895.  LINK creates the main file in the current directory unless you specify an
  17896.  explicit path with the filename.
  17897.  
  17898.  
  17899.  12.3.3  The mapfile Field
  17900.  
  17901.  The mapfile field is used to specify a filename for the map file or to
  17902.  suppress creation of a map file. A map file lists the segments in the
  17903.  executable file or DLL.
  17904.  
  17905.  You can specify a path with the filename. The default extension is .MAP.
  17906.  Specify  NUL  to suppress the creation of a map file. The default for the
  17907.  mapfile field is one of the following:
  17908.  
  17909.  
  17910.    ■   If this field is left blank on the command line or in a response file,
  17911.        LINK creates a map file with the base name of the exefile (or the
  17912.        first object file if no exefile is specified) and the extension .MAP.
  17913.  
  17914.    ■   When using LINK prompts, LINK assumes either the default described
  17915.        above (if an empty mapfile field is specified) or  NUL.MAP, which
  17916.        suppresses creation of a map file.
  17917.  
  17918.  
  17919.  To add line numbers to the map file, use the /LINE option. To add public
  17920.  symbols, use the /MAP option. Both /LINE and /MAP force a map file to be
  17921.  created unless NULL is explicitly specified.
  17922.  
  17923.  
  17924.  12.3.4  The libraries Field
  17925.  
  17926.  You can specify one or more standard or import libraries (not DLLs) in the
  17927.  libraries field. If you name more than one library, separate the names with
  17928.  a plus sign (+) or a space. To extend libraries to the following line, type
  17929.  a plus sign (+) as the last character on the current line, press ENTER, and
  17930.  continue. Do not split a name across lines. If you specify the base name of
  17931.  a library without an extension, LINK assumes a default .LIB extension.
  17932.  
  17933.  If no library is specified, LINK searches only the default libraries named
  17934.  in the object files to resolve unresolved references. If one or more
  17935.  libraries are specified, LINK searches them in the order named before
  17936.  searching the default libraries.
  17937.  
  17938.  You can tell LINK to search additional directories for specified or default
  17939.  libraries by giving a drive name or path specification in the libraries
  17940.  field; end the specification with a backslash ( \ ). (If you don't include
  17941.  the backslash, LINK assumes the last element of the path is a library file.)
  17942.  LINK looks for files ending in .LIB in these directories.
  17943.  
  17944.  You can specify a total of 32 paths or libraries in the field. If you give
  17945.  more than 32 paths or libraries, LINK ignores the additional specifications
  17946.  without warning you.
  17947.  
  17948.  You might need to specify library names when you want to
  17949.  
  17950.  
  17951.    ■   Use a default library that has been renamed.
  17952.  
  17953.    ■   Specify a library other than the default named in the object file (for
  17954.        example, a library that handles floating-point arithmetic differently
  17955.        from the default library).
  17956.  
  17957.    ■   Search additional libraries.
  17958.  
  17959.    ■   Find a library not in the current directory and not in a directory
  17960.        specified by the LIB environment variable.
  17961.  
  17962.  
  17963.  
  17964.  12.3.4.1  Overriding Default-Library Searches
  17965.  
  17966.  Most compilers insert the names of the required language libraries in the
  17967.  object files. LINK searches for these default libraries automatically; you
  17968.  do not need to specify them in the libraries field. The libraries must
  17969.  already exist with the name expected by LINK. Default-library names usually
  17970.  refer to combined libraries built and named during setup; consult your
  17971.  compiler documentation for more information about default libraries.
  17972.  
  17973.  To make LINK ignore the default libraries, use the /NOD option. This leaves
  17974.  unresolved references in the object files, so you must use the libraries
  17975.  field to specify the alternative libraries that LINK is to search.
  17976.  
  17977.  
  17978.  12.3.4.2  Import Libraries
  17979.  
  17980.  You can specify import libraries created by the IMPLIB utility anywhere you
  17981.  can specify standard libraries. You can also use the LIB utility to combine
  17982.  import libraries and standard libraries. These combined libraries can then
  17983.  be specified in the libraries field.
  17984.  
  17985.  
  17986.  12.3.4.3  How LINK Resolves References
  17987.  
  17988.  LINK searches static libraries to resolve external references. A static
  17989.  library is either a standard library created by the LIB utility or an import
  17990.  library created by the IMPLIB utility. The linker searches first in the
  17991.  libraries and library directories you specify (in the order you specify
  17992.  them), then in the default libraries. If a default library is explicitly
  17993.  specified, it is searched in the order it is given.
  17994.  
  17995.  LINK uses only those library modules needed to resolve external references,
  17996.  not the entire library. However, if you enter a library as a load library in
  17997.  the objfiles field, all the modules of a load library are added to the main
  17998.  output.
  17999.  
  18000.  
  18001.  12.3.4.4  How LINK Searches for Library Files
  18002.  
  18003.  When searching for libraries, LINK looks in the following locations in this
  18004.  order:
  18005.  
  18006.  
  18007.    1.  The directory specified for the file (if a path is included). If the
  18008.        file is not in that directory, the search terminates. (The default
  18009.        libraries named in object files by Microsoft compilers do not include
  18010.        path specifications.)
  18011.  
  18012.    2.  The current directory.
  18013.  
  18014.    3.  Any directories in the libraries field.
  18015.  
  18016.    4.  Any directories specified in the LIB environment variable.
  18017.  
  18018.  
  18019.  If LINK cannot locate a library file, it prompts you to enter the location.
  18020.  The /BATCH option disables this prompting.
  18021.  
  18022.  
  18023.  Example
  18024.  
  18025.  The following is a specification in the libraries field:
  18026.  
  18027.    C:\TESTLIB\ NEWLIBV3 C:\MYLIBS\SPECIAL
  18028.  
  18029.  LINK searches NEWLIBV3.LIB first for unresolved references. Since no
  18030.  directory is specified for NEWLIBV3.LIB, LINK searches the following
  18031.  locations in this order:
  18032.  
  18033.  
  18034.    1.  The current directory
  18035.  
  18036.    2.  The C:\TESTLIB\ directory
  18037.  
  18038.    3.  The directories in the LIB environment variable
  18039.  
  18040.  
  18041.  If LINK still cannot find NEWLIBV3.LIB, it prompts you with the message
  18042.  
  18043.    Enter new file spec
  18044.  
  18045.  You can then enter either a path to the library or a full pathname for
  18046.  another library.
  18047.  
  18048.  If unresolved references remain after searching NEWLIBV3.LIB, LINK then
  18049.  searches the library C:\MYLIBS\SPECIAL.LIB. If LINK cannot find this
  18050.  library, it prompts you as described above for NEWLIBV3.LIB. If there are
  18051.  still unresolved references, LINK searches the default libraries.
  18052.  
  18053.  
  18054.  12.3.5  The deffile Field
  18055.  
  18056.  Use the deffile field to specify a module-definition file when you are
  18057.  linking a segmented executable file, which is an application or DLL for OS/2
  18058.  or Windows. A module-definition file is optional for an application but
  18059.  required for a DLL. If you specify a base name with no extension, LINK
  18060.  assumes a .DEF extension. If the filename has no extension, put a period (.)
  18061.  at the end of the name.
  18062.  
  18063.  By default, LINK assumes that no deffile needs to be specified. If you are
  18064.  linking for DOS, use a semicolon to terminate the command line before the
  18065.  deffile field (or accept the default NUL.DEF at the  Definitions File
  18066.  prompt).
  18067.  
  18068.  
  18069.  12.3.5.1  How LINK Searches for Module-Definition Files
  18070.  
  18071.  LINK searches for the module-definition file in the following order:
  18072.  
  18073.  
  18074.    1.  The directory specified for the file (if a path is included). If the
  18075.        file is not in that directory, the search terminates.
  18076.  
  18077.    2.  The current directory.
  18078.  
  18079.  
  18080.  For information on module-definition files, see Chapter 13.
  18081.  
  18082.  
  18083.  12.3.6  Examples
  18084.  
  18085.  The following examples illustrate various uses of the LINK command line.
  18086.  
  18087.  
  18088.  Example 1
  18089.  
  18090.    LINK FUN+TEXT+TABLE+CARE, , FUNLIST, XLIB.LIB;
  18091.  
  18092.  This command line links the object files FUN.OBJ, TEXT.OBJ, TABLE.OBJ, and
  18093.  CARE.OBJ. By default, the executable file is named FUN.EXE, because the base
  18094.  name of the first object file is  FUN, and no name is specified for the
  18095.  executable file. The map file is named FUNLIST.MAP. LINK searches for
  18096.  unresolved external references in the library XLIB.LIB before searching in
  18097.  the default libraries. LINK does not prompt for a .DEF file because a
  18098.  semicolon appears before the deffile field.
  18099.  
  18100.  
  18101.  Example 2
  18102.  
  18103.    LINK FUN, , ;
  18104.  
  18105.  This command produces a map file named FUN.MAP because a comma appears as a
  18106.  placeholder for the mapfile field on the command line.
  18107.  
  18108.  
  18109.  Example 3
  18110.  
  18111.    LINK FUN, ;
  18112.    LINK FUN;
  18113.  
  18114.  Neither of these commands produces a map file, because commas do not appear
  18115.  as placeholders for the mapfile field. The semicolon (;) terminates the
  18116.  command line and accepts all remaining defaults without prompting; the
  18117.  prompting default for the map file is not to create one.
  18118.  
  18119.  
  18120.  Example 4
  18121.  
  18122.    LINK MAIN+GETDATA+PRINTIT, , MAIN ;
  18123.  
  18124.  This command links the files MAIN.OBJ, GETDATA.OBJ, and PRINTIT.OBJ into a
  18125.  DOS executable file because no module-definition file is specified. The map
  18126.  file MAIN.MAP is created.
  18127.  
  18128.  
  18129.  Example 5
  18130.  
  18131.    LINK GETDATA+PRINTIT, , , , MODDEF
  18132.  
  18133.  This command links GETDATA.OBJ and PRINTIT.OBJ into a DLL if MODDEF.DEF
  18134.  contains a LIBRARY statement. Otherwise, it links them into a segmented
  18135.  executable file for OS/2 or Windows. LINK creates a map file named
  18136.  GETDATA.MAP.
  18137.  
  18138.  
  18139.  12.4  Running LINK
  18140.  
  18141.  The simplest use of LINK is to combine one or more object files with a
  18142.  run-time library to create an executable file. You type  LINK  at the
  18143.  command-line prompt, followed by the names of the object files and a
  18144.  semicolon (;). LINK combines the object files with language libraries
  18145.  specified in the object files to create an executable file. By default, the
  18146.  executable file takes the name of the first object file in the list.
  18147.  
  18148.  To interrupt LINK and return to the operating-system prompt, press CTRL+C at
  18149.  any time.
  18150.  
  18151.  LINK expects you to supply at least one input field (the objfiles field),
  18152.  and as many as five. There are several ways to supply the input fields LINK
  18153.  expects:
  18154.  
  18155.  
  18156.    ■   Enter all the required input directly on the command line.
  18157.  
  18158.    ■   Omit one or more of the input fields and respond when LINK prompts for
  18159.        the missing fields.
  18160.  
  18161.    ■   Put the input in a response file and enter the response-file name in
  18162.        place of the expected input.
  18163.  
  18164.  
  18165.  These methods can be used in combination. The LINK command line was
  18166.  discussed in Section 12.3. The following sections explain the other two
  18167.  methods.
  18168.  
  18169.  
  18170.  12.4.1  Specifying Input with LINK Prompts
  18171.  
  18172.  If any field is missing from the LINK command line and the line does not end
  18173.  with a semicolon, or if any of the supplied fields are invalid, LINK prompts
  18174.  you for the missing or incorrect information. LINK displays one prompt at a
  18175.  time and waits until you respond:
  18176.  
  18177.    Object Modules [.OBJ]:
  18178.    Run File [basename.EXE]:
  18179.    List File [NUL.MAP]:
  18180.    Libraries [.LIB]:
  18181.    Definitions File [NUL.DEF]:
  18182.  
  18183.  The LINK prompts correspond to the command-line fields described earlier in
  18184.  this chapter. If you want LINK to prompt you for every input field,
  18185.  including objfiles, type the command  LINK  by itself.
  18186.  
  18187.  Options can be entered anywhere in any field, before the semicolon if
  18188.  specified.
  18189.  
  18190.  
  18191.  12.4.1.1  Defaults
  18192.  
  18193.  The default values for each field are shown in brackets. Press ENTER to
  18194.  accept the default, or type in the filename(s) you want. The basename is the
  18195.  base name of the first object file you specified. To select the default
  18196.  responses for all the remaining prompts and terminate prompting, type a
  18197.  semicolon (;) and press ENTER.
  18198.  
  18199.  If you specify a filename without giving an extension, LINK adds the
  18200.  appropriate default extension. To specify a filename that does not have an
  18201.  extension, type a period (.) after the name.
  18202.  
  18203.  Use a space or plus sign (+) to separate multiple filenames in the objfiles
  18204.  and libraries fields. To extend a long objfiles or libraries response to a
  18205.  new line, type a plus sign (+) as the last character on the current line and
  18206.  press ENTER. You can continue entering your response when the same prompt
  18207.  appears on a new line. Do not split a filename or a pathname across lines.
  18208.  
  18209.  
  18210.  12.4.2  Specifying Input in a Response File
  18211.  
  18212.  You can supply input to LINK in a response file. A response file is a text
  18213.  file containing the input LINK expects on the command line or in response to
  18214.  prompts. Response files can be used to hold frequently used options or
  18215.  responses, or to overcome the 128-character limit on the length of a DOS
  18216.  command line.
  18217.  
  18218.  
  18219.  12.4.2.1  Usage
  18220.  
  18221.  Specify the name of the response file in place of the expected command-line
  18222.  input or in response to a prompt. Precede the name with an at sign (@), as
  18223.  in @responsefile. You must specify an extension if the response file has
  18224.  one; there is no default extension. You can specify a path with the
  18225.  filename.
  18226.  
  18227.  You can specify a response file in any field (either on the command line or
  18228.  when responding to prompts) to supply input for one or more consecutive
  18229.  fields or all remaining fields. Note that LINK assumes nothing about the
  18230.  contents of the response file; LINK simply reads the fields from the file
  18231.  and applies them, in order, to the fields for which it has no input. LINK
  18232.  ignores any fields in the response file or on the command line after the
  18233.  five expected fields are satisfied or a semicolon (;) appears.
  18234.  
  18235.  
  18236.  Example
  18237.  
  18238.  The following command invokes LINK and supplies all input in a response
  18239.  file, except the last input field:
  18240.  
  18241.    LINK @input.txt, mydefs
  18242.  
  18243.  
  18244.  12.4.2.2  Contents of the Response File
  18245.  
  18246.  Each input field must appear on a separate line or be separated from other
  18247.  fields on the same line by a comma. You can extend a field to the following
  18248.  line by adding a plus sign (+) at the end of the current line. A blank field
  18249.  can be represented by either a blank line or a comma.
  18250.  
  18251.  Options can be entered anywhere in any field, before the semicolon if
  18252.  specified.
  18253.  
  18254.  If a response file does not specify all the fields, LINK prompts you for the
  18255.  rest. Use a semicolon (;) to suppress prompting and accept the default
  18256.  responses for all remaining fields.
  18257.  
  18258.  
  18259.  Example
  18260.  
  18261.    FUN TEXT TABLE+
  18262.    CARE
  18263.    /MAP
  18264.    FUNLIST
  18265.    GRAF.LIB ;
  18266.  
  18267.  If the response file above is named  FUN.LNK, the command
  18268.  
  18269.    LINK @FUN.LNK
  18270.  
  18271.  causes LINK to
  18272.  
  18273.  
  18274.    ■   Link the four object files FUN.OBJ, TEXT.OBJ, TABLE.OBJ, and CARE.OBJ
  18275.        into an executable file named FUN.EXE.
  18276.  
  18277.    ■   Include public symbols and addresses in the map file.
  18278.  
  18279.    ■   Make the name of the map file FUNLIST.MAP.
  18280.  
  18281.    ■   Link any needed routines from the library file GRAF.LIB.
  18282.  
  18283.    ■   Assume no module-definition file.
  18284.  
  18285.  
  18286.  
  18287.  12.5  LINK Options
  18288.  
  18289.  This section explains how to use options to control LINK's behavior and
  18290.  modify LINK's output. It contains a description of each option following a
  18291.  brief introduction on how to specify options.
  18292.  
  18293.  
  18294.  12.5.1  Specifying Options
  18295.  
  18296.  The following paragraphs discuss rules for using options.
  18297.  
  18298.  
  18299.  12.5.1.1  Syntax
  18300.  
  18301.  All options begin with a slash ( / ). You can specify an option by using the
  18302.  shortest sequence of characters that uniquely identifies the option. The
  18303.  description for each option shows the minimum legal abbreviation with the
  18304.  optional part enclosed in double brackets. No gaps or transpositions of
  18305.  letters are allowed. For example,
  18306.  
  18307.    /B«ATCH»
  18308.  
  18309.  indicates that either /B or /BATCH can be used, as can /BA, /BAT, or /BATC.
  18310.  Option names are not case sensitive, so you can also specify /batch or
  18311.  /Batch. This chapter uses meaningful yet legal forms of the option names.
  18312.  
  18313.  
  18314.  12.5.1.2  Usage
  18315.  
  18316.  LINK options can appear on the command line, in response to a prompt, or as
  18317.  part of a field in a response file. They can also be specified in the LINK
  18318.  environment variable. (For more information, see Section 12.6, "Setting
  18319.  Options with the LINK Environment Variable.") Options can appear in any
  18320.  field before the last input, except as noted in the descriptions.
  18321.  
  18322.  If an option appears more than once (for example, on the command line and in
  18323.  the LINK variable), the effect is the same as if the option was given only
  18324.  once. If two options conflict, the most recently specified option takes
  18325.  effect. This means that a command-line option or one given in response to a
  18326.  prompt overrides one specified in the LINK environment variable. For
  18327.  example, the command-line option /SEG:512 cancels the effect of the
  18328.  environment-variable option /SEG:256.
  18329.  
  18330.  
  18331.  12.5.1.3  Numeric Arguments
  18332.  
  18333.  Some LINK options take numeric arguments. You can enter numbers either in
  18334.  decimal format or in standard C-language notation.
  18335.  
  18336.  
  18337.  12.5.2  The /ALIGN Option
  18338.  
  18339.  
  18340.  Option
  18341.  
  18342.    /A«LIGNMENT»:size
  18343.  
  18344.  The /ALIGN option aligns segments in a segmented executable file at the
  18345.  boundaries specified by size. The size argument must be an integer power of
  18346.  two. For example,
  18347.  
  18348.    /ALIGN:16
  18349.  
  18350.  indicates an alignment boundary of 16 bytes. The default alignment is 512
  18351.  bytes.
  18352.  
  18353.  This option reduces the size of the disk file by reducing the size of gaps
  18354.  between segments. It has no effect on the size of the file when loaded in
  18355.  memory.
  18356.  
  18357.  
  18358.  12.5.3  The /BATCH Option
  18359.  
  18360.  
  18361.  Option
  18362.  
  18363.    /B«ATCH»
  18364.  
  18365.  The /BATCH option suppresses prompting for libraries or object files that
  18366.  LINK cannot find. By default, the linker prompts for a new pathname whenever
  18367.  it cannot find a library that it has been directed to use. It also prompts
  18368.  you if it cannot find an object file that it expects to find on a floppy
  18369.  disk. When /BATCH is used, the linker generates an error or warning message
  18370.  (if appropriate). The /BATCH option also suppresses the LINK copyright
  18371.  message and echoed input from response files.
  18372.  
  18373.  Using this option can cause unresolved external references. It is intended
  18374.  primarily for users who use batch files or makefiles for linking many
  18375.  executable files with a single command and who wish to prevent linker
  18376.  operation from halting.
  18377.  
  18378.  ────────────────────────────────────────────────────────────────────────────
  18379.  NOTE
  18380.  
  18381.  This option does not suppress prompts for input fields. Use a semicolon (;)
  18382.  at the end of the LINK input to suppress input prompting.
  18383.  ────────────────────────────────────────────────────────────────────────────
  18384.  
  18385.  
  18386.  12.5.4  The /CO Option
  18387.  
  18388.  
  18389.  Option
  18390.  
  18391.    /CO«DEVIEW»
  18392.  
  18393.  The /CO option adds line numbers and symbolic data to the executable file
  18394.  for use with the Microsoft CodeView debugger. The /CO option has no effect
  18395.  if the object files do not contain CodeView debugging information.
  18396.  
  18397.  You can run the resulting executable file outside CodeView; the debugging
  18398.  data in the file is ignored. However, it increases file size and slows
  18399.  execution slightly. You should link a separate release version without the
  18400.  /CO option after the program has been debugged.
  18401.  
  18402.  When /CO is used with the /TINY option, debug information is put in a
  18403.  separate file with the same base name as the .COM file and with the .DBG
  18404.  extension.
  18405.  
  18406.  The /CO option is not compatible with the /EXEPACK option for DOS executable
  18407.  files.
  18408.  
  18409.  
  18410.  12.5.5  The /CPARM Option
  18411.  
  18412.  
  18413.  Option
  18414.  
  18415.    /CP«ARMAXALLOC»:number
  18416.  
  18417.  The /CPARM option sets the maximum number of 16-byte paragraphs needed by
  18418.  the program when it is loaded into memory. The operating system uses this
  18419.  value to allocate space for the program before loading it. This option is
  18420.  useful when you want to execute another program from within your program and
  18421.  you need to reserve memory for the program. The /CPARM option is valid only
  18422.  when linking DOS programs.
  18423.  
  18424.  LINK normally requests the operating system to set the maximum number of
  18425.  paragraphs to 65,535. Since this is more memory than DOS can supply, the
  18426.  operating system always denies the request and allocates the largest
  18427.  contiguous block of memory it can find. If the /CPARM option is used, the
  18428.  operating system allocates no more space than the option specified. Any
  18429.  memory in excess of that required for the program loaded is free for other
  18430.  programs.
  18431.  
  18432.  The number can be any integer value in the range 1 to 65,535. If number is
  18433.  less than the minimum number of paragraphs needed by the program, LINK
  18434.  ignores your request and sets the maximum value equal to whatever the
  18435.  minimum value happens to be. The minimum number of paragraphs needed by a
  18436.  program is never less than the number of paragraphs of code and data in the
  18437.  program. To free more memory for programs compiled in the medium and large
  18438.  models, link with /CPARM:1. This leaves no space for the near heap.
  18439.  
  18440.  ────────────────────────────────────────────────────────────────────────────
  18441.  NOTE
  18442.  
  18443.  You can change the maximum allocation after linking by using the EXEHDR
  18444.  utility, which modifies the executable-file header.
  18445.  ────────────────────────────────────────────────────────────────────────────
  18446.  
  18447.  
  18448.  12.5.6  The /DOSSEG Option
  18449.  
  18450.  
  18451.  Option
  18452.  
  18453.    /DO«SSEG»
  18454.  
  18455.  The /DOSSEG option forces segments to be ordered as follows:
  18456.  
  18457.  
  18458.    1.  All segments with a class name ending in CODE
  18459.  
  18460.    2.  All other segments outside DGROUP
  18461.  
  18462.    3.  DGROUP segments, in the following order:
  18463.  
  18464.        a.  Any segments of class BEGDATA. (This class name is reserved for
  18465.            Microsoft use.)
  18466.  
  18467.        b.  Any segments not of class BEGDATA, BSS, or STACK.
  18468.  
  18469.        c.  Segments of class BSS.
  18470.  
  18471.        d.  Segments of class STACK.
  18472.  
  18473.  
  18474.  
  18475.  In addition, /DOSSEG option defines the following two labels:
  18476.  
  18477.    _edata = DGROUP : BSS
  18478.    _end   = DGROUP : STACK
  18479.  
  18480.  The variables  _edata  and  _end  have special meanings for Microsoft
  18481.  compilers, so you should not define program variables with these names.
  18482.  Assembly-language programs can reference these variables but should not
  18483.  change them.
  18484.  
  18485.  The /DOSSEG option also inserts 16 null bytes at the beginning of the _TEXT
  18486.  segment (if this segment is defined). This behavior of the option is
  18487.  overridden by the /NONULLS option when both are used; use /NONULLS to
  18488.  override the DOSSEG comment record commonly found in standard Microsoft
  18489.  libraries.
  18490.  
  18491.  This option is principally for use with assembly-language programs. When you
  18492.  link high-level-language programs, a special object-module record in the
  18493.  Microsoft language libraries automatically enables the /DOSSEG option. This
  18494.  option is also enabled by assembly modules that use MASM directive .DOSSEG.
  18495.  
  18496.  
  18497.  
  18498.  12.5.7  The /DSALLOC Option
  18499.  
  18500.  
  18501.  Option
  18502.  
  18503.    /DS«ALLOCATE»
  18504.  
  18505.  The /DSALLOC option tells LINK to load all data starting at the high end of
  18506.  the data segment. At run time, the data segment (DS) register is set to the
  18507.  lowest data-segment address that contains program data.
  18508.  
  18509.  By default, LINK loads all data starting at the low end of the data segment.
  18510.  At run time, the DS register is set to the lowest possible address to allow
  18511.  the entire data segment to be used.
  18512.  
  18513.  The /DSALLOC option is most often used with the /HIGH option to take
  18514.  advantage of unused memory within the data segment. These options are valid
  18515.  only for assembly-language programs that create DOS .EXE files.
  18516.  
  18517.  
  18518.  12.5.8  The /EXEPACK Option
  18519.  
  18520.  
  18521.  Option
  18522.  
  18523.    /E«XEPACK»
  18524.  
  18525.  The /EXEPACK option directs LINK to remove sequences of repeated bytes
  18526.  (usually null characters) and to optimize the load-time relocation table
  18527.  before creating the executable file. (The load-time relocation table is a
  18528.  table of references relative to the start of the program, each of which
  18529.  changes when the executable image is loaded into memory and an actual
  18530.  address for the entry point is assigned.)
  18531.  
  18532.  The /EXEPACK option does not always produce a significant saving in disk
  18533.  space and may sometimes actually increase file size. Programs that have a
  18534.  large number of load-time relocations (about 500 or more) and long streams
  18535.  of repeated characters are usually shorter if packed. LINK notifies you if
  18536.  the packed file is larger than the unpacked file. The time required to
  18537.  expand a packed file may cause it to load more slowly than a file linked
  18538.  without this option.
  18539.  
  18540.  You cannot debug packed files with CodeView, because the /EXEPACK option
  18541.  removes symbolic information. A LINK warning message notifies you of this.
  18542.  
  18543.  The /EXEPACK option is not compatible with the /INCR option or with Windows
  18544.  programs.
  18545.  
  18546.  
  18547.  12.5.9  The /FARCALL Option
  18548.  
  18549.  
  18550.  Option
  18551.  
  18552.    /F«ARCALLTRANSLATION»
  18553.  
  18554.  The /FARCALL option directs the linker to optimize far calls to procedures
  18555.  that lie in the same segment as the caller. This can result in slightly
  18556.  faster code; the gain in speed is most apparent on 80286-based machines and
  18557.  later. The /PACKC option can be used with /FARCALL when linking for OS/2.
  18558.  /PACKC is not recommended when linking Windows applications with /FARCALL.
  18559.  
  18560.  The /FARCALL option is off by default. If an environment variable (such as
  18561.  LINK or FL) includes /FARCALL, you can use the /NOFARCALL option to override
  18562.  it.
  18563.  
  18564.  FARCALL optimizes by creating more efficient code.
  18565.  
  18566.  A program that has multiple code segments may make a far call to a procedure
  18567.  in the same segment. Since the segment address is the same (for both the
  18568.  code and the procedure it calls), only a near call is necessary. Far calls
  18569.  appear in the relocation table; a near call does not require a table entry.
  18570.  By converting far calls to near calls in the same segment, the /FARCALL
  18571.  option both reduces the size of the relocation table and increases execution
  18572.  speed, since only the offset needs to be loaded, not a new segment. The
  18573.  /FARCALL option has no effect on programs that make only near calls, since
  18574.  there are no far calls to convert.
  18575.  
  18576.  When /FARCALL is specified, the linker optimizes code by removing the
  18577.  instruction  call FAR label  and substituting the following sequence:
  18578.  
  18579.    nop
  18580.            push    cs
  18581.            call    NEAR label
  18582.  
  18583.  During execution, the called procedure still returns with a far-return
  18584.  instruction. However, because both the code segment and the near address are
  18585.  on the stack, the far return is executed correctly. The  nop  (no-op)
  18586.  instruction is added so that exactly five bytes replace the five-byte
  18587.  far-call instruction.
  18588.  
  18589.  In rare cases, /FARCALL should be used with caution.
  18590.  
  18591.  There is a small risk with the /FARCALL option. If LINK sees the far-call
  18592.  opcode (9A hexadecimal) followed by a far pointer to the current statement,
  18593.  and that segment has a class name ending in  CODE, it interprets that as a
  18594.  far call. This problem can occur when using  _based (segname  ("CODE")) in a
  18595.  C program. If a program linked with /FARCALL fails for no apparent reason,
  18596.  try using /NOFARCALL.
  18597.  
  18598.  Object modules produced by Microsoft high-level languages are safe from this
  18599.  problem because little immediate data is stored in code segments.
  18600.  Assemblylanguage programs are generally safe for use with the /FARCALL
  18601.  option if they do not involve advanced system-level code, such as might be
  18602.  found in operating systems or interrupt handlers.
  18603.  
  18604.  
  18605.  12.5.10  The /HELP Option
  18606.  
  18607.  
  18608.  Option
  18609.  
  18610.    /HE«LP»
  18611.  
  18612.  The /HELP option calls the QuickHelp utility. If LINK cannot find the help
  18613.  file or QuickHelp, it displays a brief summary of LINK command-line syntax
  18614.  and options. Do not give a filename when using the /HELP option.
  18615.  
  18616.  
  18617.  12.5.11  The /HIGH Option
  18618.  
  18619.  
  18620.  Option
  18621.  
  18622.    /HI«GH»
  18623.  
  18624.  At load time, the executable file can be placed either as low or as high in
  18625.  memory as possible. The /HIGH option causes DOS to place the executable file
  18626.  as high as possible in memory. Without the /HIGH option, DOS places the
  18627.  executable file as low as possible. This option is usually used with the
  18628.  /DSALLOC option. These options are valid only for assembly-language programs
  18629.  that create DOS .EXE files.
  18630.  
  18631.  
  18632.  12.5.12  The /INCR Option
  18633.  
  18634.  
  18635.  Option
  18636.  
  18637.    /INC«REMENTAL»
  18638.  
  18639.  The /INCR option must be used to prepare for subsequent linking with ILINK.
  18640.  This option produces a .SYM file and an .ILK file, each containing
  18641.  additional information needed by ILINK.
  18642.  
  18643.  When /INCR is specified, LINK creates the main output file as a segmented
  18644.  executable file. If the main output is a DOS application, LINK adds a stub
  18645.  loader so that the program can run under DOS. The file is slightly larger
  18646.  than it would be without /INCR.
  18647.  
  18648.  The /PADC and /PADD options are often used with the /INCR option to increase
  18649.  buffer size and thereby increase the likelihood that incremental linking
  18650.  will be successful. The /TINY and /EXEPACK options are not compatible with
  18651.  /INCR.
  18652.  
  18653.  You should not use /INCR or ILINK for the release version of a product.
  18654.  ILINK is intended to speed linking during development and debugging. In rare
  18655.  cases, linking with /INCR causes warning  L4001  to be generated. If this
  18656.  occurs, do not use this option or ILINK.
  18657.  
  18658.  
  18659.  12.5.13  The /INFO Option
  18660.  
  18661.  
  18662.  Option
  18663.  
  18664.    /INF«ORMATION»
  18665.  
  18666.  The /INFO option displays to the standard output information about the
  18667.  linking process, including the phase of linking and the names of the object
  18668.  files being linked. This option is a useful way to determine the locations
  18669.  of the object files being linked, the number of segments, and the order in
  18670.  which they are linked.
  18671.  
  18672.  
  18673.  12.5.14  The /LINE Option
  18674.  
  18675.  
  18676.  Option
  18677.  
  18678.    /LI«NENUMBERS»
  18679.  
  18680.  The /LINE option adds the line numbers and associated addresses from source
  18681.  files to the map file. The object file must contain line-number information
  18682.  for it to appear in the map file. If the object file has no line-number
  18683.  information, the /LINE option has no effect. (Use the /Zd or /Zi option with
  18684.  Microsoft compilers such as CL, FL, and ML to add line numbers to the object
  18685.  file.) If you also want to add public symbols to the map file, use the /MAP
  18686.  option.
  18687.  
  18688.  The /LINE option causes a map file to be created even if you did not
  18689.  explicitly tell the linker to do so. By default, the map file is given the
  18690.  same base name as the executable file with the extension .MAP. You can
  18691.  override the default name by specifying a new map filename in the mapfile
  18692.  field or in response to the  List File  prompt.
  18693.  
  18694.  
  18695.  12.5.15  The /MAP Option
  18696.  
  18697.  
  18698.  Option
  18699.  
  18700.    /M«AP»
  18701.  
  18702.  The /MAP option adds to the map file all public (global) symbols defined in
  18703.  object files. When /MAP is specified, the map file contains a list of all
  18704.  the symbols sorted by name and a list of all the symbols sorted by address.
  18705.  If you do not use this option, the map file contains only a list of
  18706.  segments. If you also want to add line numbers to the map file, use the
  18707.  /LINE option.
  18708.  
  18709.  The /MAP option causes a map file to be created even if you did not
  18710.  explicitly tell the linker to do so. By default, the map file is given the
  18711.  same base name as the executable file with the extension .MAP. You can
  18712.  override the default name by specifying a new map filename in the mapfile
  18713.  field or in response to the  List File  prompt.
  18714.  
  18715.  Under some circumstances, adding symbols slows the linking process. If this
  18716.  is a problem, do not use /MAP.
  18717.  
  18718.  
  18719.  12.5.16  The /NOD Option
  18720.  
  18721.  
  18722.  Option
  18723.  
  18724.    /NOD«EFAULTLIBRARYSEARCH»«:libraryname»
  18725.  
  18726.  The /NOD option tells LINK not to search default libraries named in object
  18727.  files. Specifying libraryname tells LINK to search all libraries named in
  18728.  the object files except libraryname. If you want LINK to ignore more than
  18729.  one library, specify /NOD once for each library. To tell LINK to ignore all
  18730.  default libraries, specify /NOD without a libraryname.
  18731.  
  18732.  High-level-language object files usually must be linked with a run-time
  18733.  library to produce an executable file. Therefore, if you use the /NOD
  18734.  option, you must also use the libraries field to specify an alternate
  18735.  library that resolves the external references in the object files.
  18736.  
  18737.  
  18738.  12.5.17  The /NOE Option
  18739.  
  18740.  
  18741.  Option
  18742.  
  18743.    /NOE«XTDICTIONARY»
  18744.  
  18745.  The /NOE option prevents the linker from searching extended dictionaries,
  18746.  which are lists of symbol locations in libraries created with LIB. The
  18747.  linker consults extended dictionaries to speed up library searches.
  18748.  
  18749.  Using /NOE slows the linker. Use this option when you are redefining a
  18750.  symbol or function defined in a library and you get the error
  18751.  
  18752.    L2044 symbol multiply defined, use /NOE
  18753.  
  18754.  
  18755.  12.5.18  The /NOFARCALL Option
  18756.  
  18757.  
  18758.  Option
  18759.  
  18760.    /NOF«ARCALLTRANSLATION»
  18761.  
  18762.  The /NOFARCALL option turns off far-call optimization (translation).
  18763.  Far-call optimization is off by default. However, if an environment variable
  18764.  (such as LINK or FL) includes the /FARCALL option, you can use /NOFARCALL to
  18765.  override /FARCALL.
  18766.  
  18767.  
  18768.  12.5.19  The /NOGROUP Option
  18769.  
  18770.  
  18771.  Option
  18772.  
  18773.    /NOG«ROUPASSOCIATION»
  18774.  
  18775.  The /NOGROUP option ignores group associations when assigning addresses to
  18776.  data and code items. It is provided primarily for compatibility with
  18777.  previous versions of the linker (2.02 and earlier) and early versions of
  18778.  Microsoft compilers. This option is valid only for assembly-language
  18779.  programs that create DOS .EXE files.>
  18780.  
  18781.  
  18782.  12.5.20  The /NOI Option
  18783.  
  18784.  
  18785.  Option
  18786.  
  18787.    /NOI«GNORECASE»
  18788.  
  18789.  This option preserves case in identifiers. By default, LINK treats uppercase
  18790.  and lowercase letters as equivalent. Thus  ABC,  Abc, and  abc  are
  18791.  considered the same name. When you use the /NOI option, the linker
  18792.  distinguishes between uppercase and lowercase, and considers these
  18793.  identifiers to be three different names.
  18794.  
  18795.  In most high-level languages, identifiers are not case sensitive, so this
  18796.  option has no effect. However, case is significant in C. It's a good idea to
  18797.  use this option with C programs to catch misnamed identifiers.
  18798.  
  18799.  
  18800.  12.5.21  The /NOLOGO Option
  18801.  
  18802.  
  18803.  Option
  18804.  
  18805.    /NOL«OGO»
  18806.  
  18807.  The /NOLOGO option suppresses the copyright message displayed when LINK
  18808.  starts. This option has no effect if not specified first on the command line
  18809.  or in the LINK environment variable.
  18810.  
  18811.  
  18812.  12.5.22  The /NONULLS Option
  18813.  
  18814.  
  18815.  Option
  18816.  
  18817.    /NON«ULLSDOSSEG»
  18818.  
  18819.  The /NONULLS option arranges segments in the same order they are arranged by
  18820.  the /DOSSEG option. The only difference is that the /DOSSEG option inserts
  18821.  16 null bytes at the beginning of the _TEXT segment (if it is defined), but
  18822.  /NONULLS does not insert the extra bytes.
  18823.  
  18824.  If both the /DOSSEG and /NONULLS options are given, the /NONULLS option
  18825.  takes precedence. You can therefore use /NONULLS to override the DOSSEG
  18826.  comment record found in run-time libraries. This option is for segmented
  18827.  executable files.
  18828.  
  18829.  
  18830.  12.5.23  The /NOPACKC Option
  18831.  
  18832.  
  18833.  Option
  18834.  
  18835.    /NOP«ACKCODE»
  18836.  
  18837.  This option turns off code-segment packing. Code-segment packing is normally
  18838.  off by default. However, if an environment variable (such as LINK or FL)
  18839.  includes the /PACKC option to turn on code-segment packing, you can use
  18840.  /NOPACKC to override /PACKC.
  18841.  
  18842.  
  18843.  12.5.24  The /OV Option
  18844.  
  18845.  
  18846.  Option
  18847.  
  18848.    /O«VERLAYINTERRUPT»:number
  18849.  
  18850.  This option sets an interrupt number for passing control to overlays. By
  18851.  default, the interrupt number used for passing control to overlays is 63 (3F
  18852.  hexadecimal). The /OV option allows you to select a different interrupt
  18853.  number. This option is valid only when linking DOS programs.
  18854.  
  18855.  The number can be any number from 0 to 255, specified in decimal format or
  18856.  in C-language notation. Numbers that conflict with DOS interrupts can be
  18857.  used; however, their use is not advised. You should use this option only
  18858.  when you want to use overlays with a program that already reserves interrupt
  18859.  63 for some other purpose.
  18860.  
  18861.  
  18862.  12.5.25  The /PACKC Option
  18863.  
  18864.  
  18865.  Option
  18866.  
  18867.    /PACKC«ODE»«:number»
  18868.  
  18869.  The /PACKC option turns on code-segment packing. The linker packs code
  18870.  segments by grouping neighboring code segments that have the same
  18871.  attributes. Segments in the same group are assigned the same segment
  18872.  address; offset addresses are adjusted accordingly. All items have the same
  18873.  physical address whether or not the /PACKC option is used. However, /PACKC
  18874.  changes the segment and offset addresses so that all items in a group share
  18875.  the same segment.
  18876.  
  18877.  The number specifies the maximum size of groups formed by /PACKC. The linker
  18878.  stops adding segments to a group when it cannot add another segment without
  18879.  exceeding number; then it starts a new group. The default segment size
  18880.  without /PACKC (or when /PACKC is specified without number) is 65,500 bytes
  18881.  (64K - 36 bytes).
  18882.  
  18883.  The /PACKC option produces slightly faster and more compact code. It affects
  18884.  only programs with multiple code segments. This option is off by default
  18885.  and, if specified in an environment variable, can be overridden with the
  18886.  /NOPACKC option.
  18887.  
  18888.  Code-segment packing provides more opportunities for far-call optimization
  18889.  (which is enabled with the /FARCALL option). The /FARCALL and /PACKC options
  18890.  together produce faster and more compact code. However, this combination is
  18891.  not recommended for Windows applications.
  18892.  
  18893.  Use caution when packing assembly-language programs.
  18894.  
  18895.  Object code created by Microsoft compilers can safely be linked with the
  18896.  /PACKC option. This option is unsafe only when used with assembly-language
  18897.  programs that make assumptions about the relative order of code segments.
  18898.  For example, the following assembly code attempts to calculate the distance
  18899.  between CSEG1  and  CSEG2. This code produces incorrect results when used
  18900.  with /PACKC, because /PACKC causes the two segments to share the same
  18901.  segment address. Therefore, the procedure would always return zero.
  18902.  
  18903.    CSEG1      SEGMENT PUBLIC 'CODE'
  18904.    .
  18905.    .
  18906.    .
  18907.    CSEG1      ENDS
  18908.  
  18909.    CSEG2      SEGMENT PARA PUBLIC 'CODE'
  18910.               ASSUME  cs:CSEG2
  18911.  
  18912.    ; Return the length of CSEG1 in AX
  18913.  
  18914.    codesize   PROC  NEAR
  18915.               mov   ax, CSEG2  ; Load para address of CSEG1
  18916.               sub   ax, CSEG1  ; Load para address of CSEG2
  18917.               mov   cx, 4      ; Load count
  18918.               shl   ax, cl     ; Convert distance from paragraphs
  18919.                                ;  to bytes
  18920.    codesize   ENDP
  18921.  
  18922.    CSEG2      ENDS
  18923.  
  18924.  
  18925.  12.5.26  The /PACKD Option
  18926.  
  18927.  
  18928.  Option
  18929.  
  18930.    /PACKD«ATA»«:number»
  18931.  
  18932.  The /PACKDoption turns on data-segment packing. The linker considers any
  18933.  segment definition with a class name that does not end in  CODE  as a data
  18934.  segment. Adjacent data-segment definitions are combined into the same
  18935.  physical segment. The linker stops adding segments to a group when it cannot
  18936.  add another segment without exceeding number bytes; then it starts a new
  18937.  group. The default segment size without /PACKD (or when /PACKD is specified
  18938.  without number) is 65,536 bytes (64K).
  18939.  
  18940.  The /PACKD option produces slightly faster and more compact code. It affects
  18941.  only programs with multiple data segments and is valid for OS/2 and Windows
  18942.  programs only. It might be necessary to use the /PACKD option to get around
  18943.  the limit of 255 physical data segments per executable file imposed by OS/2
  18944.  and Windows. Try using /PACKD if you get the following LINK error:
  18945.  
  18946.    L1073 file-segment limit exceeded
  18947.  
  18948.  This option may not be safe with other compilers that do not generate fixup
  18949.  records for all far data references.
  18950.  
  18951.  
  18952.  12.5.27  The /PADC Option
  18953.  
  18954.  
  18955.  Option
  18956.  
  18957.    /PADC«ODE»«:padsize»
  18958.  
  18959.  The /PADC option adds filler bytes to the end of each code segment for use
  18960.  when later linking with ILINK. If you use /PADC, you must also specify the
  18961.  /INCR option.
  18962.  
  18963.  The padsize is optional; the default is 0 bytes. If incremental linking
  18964.  fails, you can specify a padsize in decimal format or C-language notation.
  18965.  For example,  /PADC:256  adds an additional 256 bytes to each code segment.
  18966.  (You can also use  0400  or  0x100  to specify 256 bytes.)
  18967.  
  18968.  The linker recognizes code segments as segment definitions with class names
  18969.  that end in  CODE. Microsoft high-level languages automatically use this
  18970.  declaration for code segments. Code padding is not usually necessary for
  18971.  programs with multiple code segments but is recommended for mixed-model
  18972.  programs, programs with one code segment, and assembly-language programs in
  18973.  which code segments are grouped.
  18974.  
  18975.  
  18976.  12.5.28  The /PADD Option
  18977.  
  18978.  
  18979.  Option
  18980.  
  18981.    /PADD«ATA»«:padsize»
  18982.  
  18983.  The /PADD option adds filler bytes to the end of each data segment to permit
  18984.  subsequent linking with ILINK. If you use /PADD, you must also specify the
  18985.  /INCR option.
  18986.  
  18987.  The padsize is optional; the default is 16 bytes. The /INCR option itself
  18988.  adds 16 bytes. This default padding is usually sufficient for successful
  18989.  incremental linking. If incremental linking fails, you can specify a padsize
  18990.  in decimal format or C-language notation. (If you specify too large a
  18991.  padsize, you might exceed the 64K limitation on the size of the default data
  18992.  segment.) For example,  /PADD:32  adds an additional 32 bytes to each data
  18993.  segment. (You can also use  040  or  0x20  to specify 32 bytes.)
  18994.  
  18995.  
  18996.  12.5.29  The /PAUSE Option
  18997.  
  18998.  
  18999.  Option
  19000.  
  19001.    /PAU«SE»
  19002.  
  19003.  The /PAUSE option pauses the session before LINK writes the executable file
  19004.  or DLL to disk. This option is supplied for compatibility with machines that
  19005.  have two floppy drives but no hard disk. It allows you to swap floppy disks
  19006.  before LINK writes the executable file.
  19007.  
  19008.  If you specify the /PAUSE option, LINK displays the following message before
  19009.  it creates the main output:
  19010.  
  19011.    About to generate .EXE file
  19012.    Change diskette in drive letter and press <ENTER>
  19013.  
  19014.  The letter is the current drive. LINK resumes processing when you press
  19015.  ENTER.
  19016.  
  19017.  Do not remove a disk that contains either the map file or the temporary
  19018.  file. If LINK creates a temporary file on the disk you plan to remove,
  19019.  terminate the LINK session and rearrange your files so that the temporary
  19020.  file is on a disk that does not need to be removed. For more information on
  19021.  how LINK determines where to put the temporary file, see Section 12.9, "LINK
  19022.  Temporary Files."
  19023.  
  19024.  
  19025.  12.5.30  The /PM Option
  19026.  
  19027.  
  19028.  Option
  19029.  
  19030.    /PM«TYPE»:type
  19031.  
  19032.  This option specifies the type of Windows or OS/2 application being
  19033.  generated. The /PM option is equivalent to including a type specification in
  19034.  the NAME statement in a module-definition file.
  19035.  
  19036.  The type field can take one of the following values:
  19037.  
  19038.  Value                             Description
  19039.  ────────────────────────────────────────────────────────────────────────────
  19040.  PM                                Presentation Manager (PM) or Windows
  19041.                                    application. The application uses the
  19042.                                    API provided by PM or Windows and must
  19043.                                    be executed in the PM or Windows
  19044.                                    environment. This is equivalent to NAME
  19045.                                    WINDOWAPI.
  19046.  
  19047.  VIO                               Character-mode application to run in a
  19048.                                    text window in the
  19049.                                    PM or Windows session. This is
  19050.                                    equivalent to NAME
  19051.                                    WINDOWCOMPAT.
  19052.  
  19053.  NOVIO                             The default. Character-mode application
  19054.                                    that must run full screen and cannot run
  19055.                                    in a text window in PM or in Windows.
  19056.                                    This is equivalent to NAME
  19057.                                    NOTWINDOWCOMPAT.
  19058.  
  19059.  
  19060.  
  19061.  12.5.31  The /Q Option
  19062.  
  19063.  
  19064.  Option
  19065.  
  19066.    /Q«UICKLIBRARY»
  19067.  
  19068.  The /Q option directs the linker to produce a "Quick library" instead of an
  19069.  executable file. A Quick library is similar to a standard library in that
  19070.  both contain routines that can be called by a program. However, a standard
  19071.  library is linked with a program at link time; in contrast, a Quick library
  19072.  is linked with a program at run time.
  19073.  
  19074.  When /Q is specified, the exefile field refers to a Quick library instead of
  19075.  an application. The default extension for this field is then .QLB instead of
  19076.  .EXE.
  19077.  
  19078.  Quick libraries can be used only with programs created with Microsoft
  19079.  QuickBasic or early versions of Microsoft QuickC. These programs have the
  19080.  special code that loads a Quick library at run time.
  19081.  
  19082.  
  19083.  12.5.32  The /SEG Option
  19084.  
  19085.  
  19086.  Option
  19087.  
  19088.    /SE«GMENTS»«:number»
  19089.  
  19090.  The /SEG option sets the maximum number of program segments. The default
  19091.  without /SEG or number is 128. You can specify number as any value from 1 to
  19092.  16,384 in individual format or C-language notation. However, the number of
  19093.  segment definitions is constrained by available memory.
  19094.  
  19095.  LINK must allocate some memory to keep track of information for each
  19096.  segment; the larger the number you specify, the less free memory LINK has to
  19097.  run in. A relatively low segment limit (such as the 128 default) reduces the
  19098.  chance LINK will run out of memory. For programs with fewer than 128
  19099.  segments, you can minimize LINK's memory requirements by setting number to
  19100.  reflect the actual number of segments in the program. If a program has more
  19101.  than 128 segments, however, you must set a higher value.
  19102.  
  19103.  If the number of segments allocated is too high for the amount of memory
  19104.  available while linking, LINK displays the error message
  19105.  
  19106.    L1054 requested segment limit too high
  19107.  
  19108.  When this happens, try linking again after setting /SEG to a smaller number.
  19109.  
  19110.  
  19111.  
  19112.  12.5.33  The /STACK Option
  19113.  
  19114.  
  19115.  Option
  19116.  
  19117.    /ST«ACK»:number
  19118.  
  19119.  The /STACK option lets you change the stack size from its default value of
  19120.  2,048 bytes. The number is any positive value in decimal or C-language
  19121.  notation, up to 64K.
  19122.  
  19123.  Programs that pass large arrays or structures by value or with deeply nested
  19124.  subroutines may need additional stack space. In contrast, if your program
  19125.  uses the stack very little, you might be able to save space by decreasing
  19126.  the stack size. If a program fails with a stack-overflow message, try
  19127.  increasing the size of the stack.
  19128.  
  19129.  ────────────────────────────────────────────────────────────────────────────
  19130.  NOTE
  19131.  
  19132.  You can also use the EXEHDR utility to change the default stack size by
  19133.  modifying the executable-file header.
  19134.  ────────────────────────────────────────────────────────────────────────────
  19135.  
  19136.  
  19137.  12.5.34  The /TINY Option
  19138.  
  19139.  
  19140.  Option
  19141.  
  19142.    /T«INY»
  19143.  
  19144.  The /TINY option produces a .COM file instead of an .EXE file. The default
  19145.  extension of the output file is .COM. When the /CO option is used with
  19146.  /TINY, debug information is put in a separate file with the same base name
  19147.  as the .COM file and with the .DBG extension.
  19148.  
  19149.  Not every program can be linked in the .COM format. The following
  19150.  restrictions apply:
  19151.  
  19152.  
  19153.    ■   The program must consist of only one physical segment. You can declare
  19154.        more than one segment in assembly-language programs; however, the
  19155.        segments must be in the same group.
  19156.  
  19157.    ■   The code must not use far references.
  19158.  
  19159.    ■   Segment addresses cannot be used as immediate data for instructions.
  19160.        For example, you cannot use the following instruction:
  19161.  
  19162.        mov     ax, CODESEG
  19163.  
  19164.  
  19165.    ■   Windows and OS/2 programs cannot be converted to a .COM format.
  19166.  
  19167.  
  19168.  
  19169.  12.5.35  The /W Option
  19170.  
  19171.  
  19172.  Option
  19173.  
  19174.    /W«ARNFIXUP»
  19175.  
  19176.  The /W option issues the  L4000  warning when LINK uses a displacement from
  19177.  the beginning of a group in determining a fixup value. This option is
  19178.  provided because early versions of the Windows linker (LINK4) performed
  19179.  fixups without this displacement. This option is for linking segmented
  19180.  executable files.
  19181.  
  19182.  
  19183.  12.5.36  The /? Option
  19184.  
  19185.  
  19186.  Option
  19187.  
  19188.    /?
  19189.  
  19190.  The /? option displays a brief summary of LINK command-line syntax and
  19191.  options.
  19192.  
  19193.  
  19194.  12.6  Setting Options with the LINK Environment Variable
  19195.  
  19196.  You can use the LINK environment variable to set options that will be in
  19197.  effect each time you link. (Microsoft compilers such as CL, FL, and ML also
  19198.  use the options in the LINK environment variable.)
  19199.  
  19200.  
  19201.  12.6.1  Setting the LINK Environment Variable
  19202.  
  19203.  You set the LINK environment variable with the following operating-system
  19204.  command:
  19205.  
  19206.    SET LINK=options
  19207.  
  19208.  LINK expects to find options listed in the variable exactly as you would
  19209.  type them in fields on the command line, in response to a prompt, or in a
  19210.  response file. It does not accept input for other fields; filenames in the
  19211.  LINK variable cause an error.
  19212.  
  19213.  
  19214.  Example
  19215.  
  19216.    SET LINK=/NOI /SEG:256 /CO
  19217.    LINK TEST;
  19218.    LINK /NOD PROG;
  19219.  
  19220.  In the example above, the commands are specified at the system prompt. The
  19221.  file TEST.OBJ is linked using the options  /NOI,  /SEG:256, and  /CO. The
  19222.  file PROG.OBJ is then linked with the option  /NOD, in addition to  /NOI,
  19223.  /SEG:256, and  /CO.
  19224.  
  19225.  
  19226.  12.6.2  Behavior of the LINK Environment Variable
  19227.  
  19228.  You can specify options on the LINK command line or in a response file in
  19229.  addition to those in the LINK environment variable. If an option appears
  19230.  both in an input field and in the LINK variable, the input-field option
  19231.  overrides any environment-variable option it conflicts with. For example,
  19232.  the command-line option /SEG:512 overrides the environment-variable option
  19233.  /SEG:256.
  19234.  
  19235.  
  19236.  12.6.3  Clearing the LINK Environment Variable
  19237.  
  19238.  You must reset the LINK environment variable to prevent LINK from using its
  19239.  options. To clear the LINK variable, use the operating-system command
  19240.  
  19241.    SET LINK=
  19242.  
  19243.  To see the current setting of the LINK variable, type  SET  at the
  19244.  operatingsystem prompt.
  19245.  
  19246.  
  19247.  12.7  Using Overlays under DOS
  19248.  
  19249.  LINK can create DOS programs with "overlays." Overlays allow sections of a
  19250.  program to be loaded into memory only as needed. This permits running a
  19251.  program that would otherwise be too large to fit in available memory.
  19252.  Overlay programs execute more slowly, however, since the various program
  19253.  modules must be swapped into and out of memory.
  19254.  
  19255.  The CodeView debugger is compatible with overlaid modules. If you use
  19256.  CodeView to debug a program that has an overlay containing more than one
  19257.  code segment, you will see only the identifiers contained in the first
  19258.  segment of the overlay.
  19259.  
  19260.  
  19261.  12.7.1  Restrictions on Overlays
  19262.  
  19263.  Not all programs can use overlays. You will probably need to reorganize the
  19264.  code to accommodate the limitations explained in this section. Even after
  19265.  reorganization, some programs might not be convertible to overlay form or
  19266.  might not show a significant reduction in the amount of memory needed to
  19267.  execute them.
  19268.  
  19269.  Consider the following restrictions before trying to overlay a program:
  19270.  
  19271.  
  19272.    ■   You can use overlays only in programs with multiple code segments,
  19273.        because separate segment names are needed for overlays. Only code is
  19274.        overlaid, not data. The data becomes part of the "root" section of the
  19275.        program that is always in memory.
  19276.  
  19277.    ■   Only 255 overlays can be specified. The program can define only 255
  19278.        logical segments (segments with different names). This limits the
  19279.        total size of an overlaid program to 16 megabytes.
  19280.  
  19281.    ■   Only one overlay (in addition to the root) can be in memory at any one
  19282.        time. You must structure your program accordingly.
  19283.  
  19284.    ■   Duplicate names for different overlays are not supported; each module
  19285.        can appear only once in a program.
  19286.  
  19287.    ■   You must use far call/return instructions to transfer control between
  19288.        overlaid files. You cannot overlay files containing near routines if
  19289.        other overlays call those routines.
  19290.  
  19291.    ■   You cannot jump out of or into overlaid files using the longjmp
  19292.        C-library function. You can, however, use long jumps within an
  19293.        overlaid file.
  19294.  
  19295.    ■   You cannot use a function pointer to call a routine out of or into
  19296.        overlaid files. You can, however, use a function pointer to call a
  19297.        routine within an overlaid file.
  19298.  
  19299.    ■   You cannot use the same public name in different overlays.
  19300.  
  19301.    ■   The code required to manage overlays adds about 2K to 3K to the size
  19302.        of the root module.
  19303.  
  19304.  
  19305.  ────────────────────────────────────────────────────────────────────────────
  19306.  WARNING
  19307.  
  19308.  Never rename an executable program file containing overlays if it is to run
  19309.  under DOS 2.x and earlier. LINK records the .EXE filename in the program
  19310.  file. If you rename the file, the overlay manager may not be able to locate
  19311.  the proper file. You can rename an .EXE file that will run under DOS 3.x and
  19312.  later.
  19313.  ────────────────────────────────────────────────────────────────────────────
  19314.  
  19315.  
  19316.  12.7.2  Specifying Overlays
  19317.  
  19318.  Specify overlays by enclosing object-file (and possibly load-library) names
  19319.  in parentheses in the objfiles field. Each group of object files bracketed
  19320.  by parentheses represents one overlay. Overlays cannot be nested.
  19321.  
  19322.  The remaining modules (those not in parentheses), and any drawn from the
  19323.  run-time libraries, constitute the resident (or root) part of your program.
  19324.  The entry point to the program (for example,  main()  in a C program, or
  19325.  PROGRAM  in a FORTRAN program) must be in the root.
  19326.  
  19327.  
  19328.  Example
  19329.  
  19330.  The following list of files contains three overlays:
  19331.  
  19332.    a + (b+c) + (d+e) + f + (g)
  19333.  
  19334.  In this example, the groups  (b+c),  (d+e), and  (g)  are overlays. The
  19335.  remaining files  a  and  f  and any modules from libraries in the libraries
  19336.  field remain memory-resident throughout the execution of the program.
  19337.  
  19338.  It is important to remember that whichever object file first defines a
  19339.  segment gets all contributions to that segment. In the example above, if
  19340.  D.OBJ and F.OBJ both define the same segment, the contribution from F.OBJ to
  19341.  that segment goes into the  (d+e)  overlay rather than into the root.
  19342.  
  19343.  
  19344.  12.7.3  How Overlays Work
  19345.  
  19346.  Programs that use overlays require the overlay-manager code to handle module
  19347.  swapping. This code is included as part of the standard libraries for
  19348.  Microsoft high-level languages. If you specify overlays during linking, the
  19349.  code for the overlay manager is automatically linked with the rest of your
  19350.  program.
  19351.  
  19352.  LINK produces only one .EXE file. The overlay manager searches for this file
  19353.  whenever another overlay needs to be loaded. It first searches in the
  19354.  current directory. If the file is not there, the manager then searches the
  19355.  directories in the PATH environment variable. If the overlay manager still
  19356.  cannot find the file, it prompts for the pathname.
  19357.  
  19358.  
  19359.  Example
  19360.  
  19361.  Assume that an executable program called PAYROLL.EXE uses overlays and does
  19362.  not exist in either the current directory or the directories specified by
  19363.  PATH. If you run PAYROLL.EXE by entering a complete path specification, the
  19364.  overlay manager displays the following message when it attempts to load an
  19365.  overlay file:
  19366.  
  19367.    Cannot find PAYROLL.EXE
  19368.    Please enter new program spec:
  19369.  
  19370.  You can then enter the drive or directory, or both, where PAYROLL.EXE is
  19371.  located. For example, if the file is located in directory \EMPLOYEE\DATA\ on
  19372.  drive B, enter  B:\EMPLOYEE\DATA\; if the current drive is B, you can enter
  19373.  just  \EMPLOYEE\DATA\.
  19374.  
  19375.  If you later remove the disk in drive B and the overlay manager needs the
  19376.  overlay again, it does not find PAYROLL.EXE and displays the following
  19377.  message:
  19378.  
  19379.    Please insert diskette containing B:\EMPLOYEE\DATA\PAYROLL.EXE
  19380.    in drive B: and strike any key when ready.
  19381.  
  19382.  After the overlay file has been read from the disk, the overlay manager
  19383.  displays the following message:
  19384.  
  19385.    Please restore the original diskette.
  19386.    Strike any key when ready.
  19387.  
  19388.  
  19389.  12.7.4  Overlay Interrupts
  19390.  
  19391.  LINK replaces far calls to routines in overlays with interrupts (followed by
  19392.  the module identifier and offset). By default, the interrupt number is 63
  19393.  (3F hexadecimal). You can use the /OV option to change the interrupt number.
  19394.  
  19395.  
  19396.  
  19397.  12.8  Linker Operation under DOS
  19398.  
  19399.  LINK performs the following steps to produce a DOS executable file:
  19400.  
  19401.  
  19402.    1.  Reads the object modules submitted
  19403.  
  19404.    2.  Searches the given libraries, if necessary, to resolve external
  19405.        references
  19406.  
  19407.    3.  Assigns addresses to segments
  19408.  
  19409.    4.  Assigns addresses to public symbols
  19410.  
  19411.    5.  Reads code and data in the segments
  19412.  
  19413.    6.  Reads all relocation references in object modules
  19414.  
  19415.    7.  Performs fixups
  19416.  
  19417.    8.  Outputs an executable file (executable image and relocation
  19418.        information)
  19419.  
  19420.  
  19421.  Steps 5, 6, and 7 are performed iteratively─that is, LINK repeats these
  19422.  steps as many times as required before it progresses to step 8.
  19423.  
  19424.  The "executable image" contains the code and data that constitute the
  19425.  executable file. The "relocation information" is a list of references
  19426.  relative to the start of the program, each of which changes when the
  19427.  executable image is loaded into memory and an actual address for the entry
  19428.  point is assigned.
  19429.  
  19430.  The following sections explain the process LINK uses to concatenate segments
  19431.  and resolve references to items in memory.
  19432.  
  19433.  
  19434.  12.8.1  Segment Alignment
  19435.  
  19436.  LINK uses each segment's alignment type to set the starting address for the
  19437.  segment. The alignment types are BYTE, WORD, DWORD, PARA, and PAGE. These
  19438.  correspond to starting addresses at byte, word, doubleword, paragraph, and
  19439.  page boundaries, representing addresses that are multiples of 1, 2, 4, 16,
  19440.  and 256, respectively. The default alignment is PARA.
  19441.  
  19442.  When LINK encounters a segment, it checks the alignment type before copying
  19443.  the segment to the executable file. If the alignment is WORD, DWORD, PARA,
  19444.  or PAGE, LINK checks the executable image to see if the last byte copied
  19445.  ends at an appropriate boundary. If not, LINK pads the image with extra null
  19446.  bytes.
  19447.  
  19448.  
  19449.  12.8.2  Frame Number
  19450.  
  19451.  LINK computes a starting address for each segment in a program. The starting
  19452.  address is based on a segment's alignment and the sizes of the segments
  19453.  already copied to the executable file. The address consists of an offset and
  19454.  a "canonical frame number." The canonical frame number specifies the address
  19455.  of the first paragraph in memory containing one or more bytes of the
  19456.  segment. (A paragraph is 16 bytes of memory; therefore, to compute a
  19457.  physical location in memory, multiply the frame number by 16 and add the
  19458.  offset.) The offset is the number of bytes from the start of the paragraph
  19459.  to the first byte in the segment. For BYTE, WORD, and DWORD alignments, the
  19460.  offset may be nonzero. The offset is always zero for PARA and PAGE
  19461.  alignments. (An offset of zero means that the physical location is an exact
  19462.  multiple of 16.)
  19463.  
  19464.  The frame number of a segment can be obtained from the map file created by
  19465.  LINK. The first four digits of the start address give the frame number in
  19466.  hexadecimal. For example, a start address of  0C0A6  gives a frame number of
  19467.   0C0A.
  19468.  
  19469.  
  19470.  12.8.3  Segment Order
  19471.  
  19472.  LINK copies segments to the executable file in the same order that it
  19473.  encounters them in the object files. This order is maintained throughout the
  19474.  program unless LINK encounters two or more segments having the same class
  19475.  name. Segments having identical class names belong to the same class type
  19476.  and are copied as a contiguous block to the executable file.
  19477.  
  19478.  The /DOSSEG option might change the way in which segments are ordered.
  19479.  
  19480.  
  19481.  12.8.4  Combined Segments
  19482.  
  19483.  LINK uses combine types to determine whether two or more segments sharing
  19484.  the same segment name should be combined into one large segment. The valid
  19485.  combine types are PUBLIC, STACK, COMMON, and PRIVATE.
  19486.  
  19487.  If a segment has combine type PUBLIC, LINK automatically combines it with
  19488.  any other segments having the same name and belonging to the same class.
  19489.  When LINK combines segments, it ensures that the segments are contiguous and
  19490.  that all addresses in the segments can be accessed using an offset from the
  19491.  same frame address. The result is the same as if the segment were defined as
  19492.  a whole in one source file.
  19493.  
  19494.  LINK preserves each individual segment's alignment type. This means that
  19495.  even though the segments belong to a single large segment, the code and data
  19496.  in the segments do not lose their original alignment. If the combined
  19497.  segments exceed 64K, LINK displays an error message.
  19498.  
  19499.  If a segment has combine type STACK, LINK carries out the same combine
  19500.  operation as for PUBLIC segments. The only exception is that STACK segments
  19501.  cause LINK to copy an initial stack-pointer value to the executable file.
  19502.  This stack-pointer value is the offset to the end of the first stack segment
  19503.  (or combined stack segment) encountered.
  19504.  
  19505.  If a segment has combine type COMMON, LINK automatically combines it with
  19506.  any other segments having the same name and belonging to the same class.
  19507.  When LINK combines COMMON segments, however, it places the start of each
  19508.  segment at the same address, creating a series of overlapping segments. The
  19509.  result is a single segment no larger than the largest segment combined.
  19510.  
  19511.  A segment has combine type PRIVATE only if no explicit combine type is
  19512.  defined for it in the source file. LINK does not combine private segments.
  19513.  
  19514.  
  19515.  12.8.5  Groups
  19516.  
  19517.  Groups allow segments to be addressed relative to the same frame address.
  19518.  When LINK encounters a group, it adjusts all memory references to items in
  19519.  the group so that they are relative to the same frame address.
  19520.  
  19521.  Segments in a group do not have to be contiguous, belong to the same class,
  19522.  or have the same combine type. The only requirement is that all segments in
  19523.  the group fit within 64K.
  19524.  
  19525.  Groups do not affect the order in which the segments are loaded. Unless you
  19526.  use class names and enter object files in the right order, there is no
  19527.  guarantee the segments will be contiguous. In fact, LINK may place segments
  19528.  that do not belong to the group in the same 64K of memory. LINK does not
  19529.  explicitly check that all segments in a group fit within 64K of memory;
  19530.  however, LINK is likely to encounter a fixup-overflow error if this
  19531.  requirement is not met.
  19532.  
  19533.  
  19534.  12.8.6  Fixups
  19535.  
  19536.  Once the starting address of each segment in a program is known and all
  19537.  segment combinations and groups have been established, LINK can "fix up" any
  19538.  unresolved references to labels and variables. To fix up unresolved
  19539.  references, LINK computes an appropriate offset and segment address and
  19540.  replaces the temporary values generated by the assembler with the new
  19541.  values.
  19542.  
  19543.  LINK carries out fixups for the types of references shown in Table 12.1.
  19544.  
  19545.  The size of the value to be computed depends on the type of reference. If
  19546.  LINK discovers an error in the anticipated size of a reference, it displays
  19547.  a fixupoverflow message. This can happen, for example, if a program attempts
  19548.  to use a 16-bit offset to reach an instruction which is more than 64K away.
  19549.  It can also occur if all segments in a group do not fit within a single 64K
  19550.  block of memory.
  19551.  
  19552.  Table 12.1  LINK Fixups
  19553.  
  19554.  Type              Location of Reference    LINK Action
  19555.  ────────────────────────────────────────────────────────────────────────────
  19556.  Short             In JMP instructions      Computes a signed, eight-bit
  19557.                    that attempt to pass     number for the reference and
  19558.                    control to labeled       displays an error message if
  19559.                    instructions in the      the target instruction belongs
  19560.                    same segment or group.   to a different segment or group
  19561.                    The target instruction   (has a different frame address),
  19562.                    must be no more than     or if the target is more than
  19563.                    128 bytes from the       128 bytes away in either
  19564.                    point of reference.      direction.
  19565.  
  19566.  Near              In instructions that     Computes a 16-bit offset for
  19567.  self-relative     access data relative to  the reference and displays an
  19568.                    the same segment or      error if the data are not in
  19569.                    group.                   the same segment or group.
  19570.  
  19571.  Near              In instructions that     Computes a 16-bit offset for
  19572.  segment-relative  attempt to access data   the reference and displays an
  19573.                    in a specified segment   error message if the offset of
  19574.                    or group, or relative    the target within the specified
  19575.                    to a specified segment   frame is greater than 64K or
  19576.                                             less than 0, or if the
  19577.                    register.                beginning of the canonical
  19578.                                             frame of the target is not
  19579.                                             addressable.
  19580.  
  19581.  Long              In CALL instructions     Computes a 16-bit frame address
  19582.                    that attempt to access   and 16-bit offset for this
  19583.                    an instruction in        reference, and displays an
  19584.                    another segment or       error message if the computed
  19585.                    group.                   offset is greater than 64K or
  19586.                                             less than 0, or if the
  19587.                                             beginning of the canonical
  19588.                                             frame of the target is not
  19589.                                             addressable.
  19590.  
  19591.  ────────────────────────────────────────────────────────────────────────────
  19592.  
  19593.  
  19594.  
  19595.  12.9  LINK Temporary Files
  19596.  
  19597.  LINK uses available memory during the linking session. If LINK runs out of
  19598.  memory, it creates a disk file to hold intermediate files. LINK deletes this
  19599.  file when it finishes.
  19600.  
  19601.  When the linker creates a temporary disk file, you see the message
  19602.  
  19603.    Temporary file tempfile has been created.
  19604.    Do not change diskette in drive, letter.
  19605.  
  19606.  In the message displayed above, tempfile is the name of the temporary file
  19607.  and letter is the drive containing the temporary file. (The second line
  19608.  appears only for a floppy drive.)
  19609.  
  19610.  After this message appears, do not remove the disk from the drive specified
  19611.  by letter until the link session ends. If the disk is removed, the operation
  19612.  of LINK is unpredictable, and you might see the following message:
  19613.  
  19614.    Unexpected end-of-file on scratch file
  19615.  
  19616.  If this happens, run LINK again.
  19617.  
  19618.  
  19619.  Location of the Temporary File
  19620.  
  19621.  If the TMP environment variable defines a temporary directory, LINK creates
  19622.  temporary files there. If the TMP environment variable is undefined or the
  19623.  temporary directory doesn't exist, LINK creates temporary files in the
  19624.  current directory.
  19625.  
  19626.  
  19627.  Name of the Temporary File
  19628.  
  19629.  When running under OS/2 or DOS version 3.0 or later, LINK asks the operating
  19630.  system to create a temporary file with a unique name in the temporary-file
  19631.  directory.
  19632.  
  19633.  Under DOS versions earlier than 3.0, LINK creates a temporary file named
  19634.  VM.TMP. Do not use this name for your files. LINK generates an error message
  19635.  if it encounters an existing file with this name.
  19636.  
  19637.  
  19638.  12.10  LINK Exit Codes
  19639.  
  19640.  LINK returns an exit code (also called return code or error code) that you
  19641.  can use to control the operation of batch files or makefiles.
  19642.  
  19643. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  19644.  Code                              Meaning
  19645.  ────────────────────────────────────────────────────────────────────────────
  19646.  0                                 No error.
  19647.  
  19648.  2                                 Program error. Commands or files given
  19649.                                    as input to the linker produced the
  19650.                                    error.
  19651.  
  19652.  4                                 System error. The linker
  19653.  
  19654.                                    Ran out of space on output files
  19655.  
  19656.                                    Was unable to reopen the temporary file
  19657.  
  19658.  Code                              Meaning
  19659.  ────────────────────────────────────────────────────────────────────────────
  19660. 
  19661.                                    Experienced an internal error
  19662.  
  19663.                                    Was interrupted by the user
  19664.  
  19665.  
  19666.  
  19667.  
  19668.  12.11  Related Topics in Online Help
  19669.  
  19670.  In addition to information covered in this chapter, information on the
  19671.  following topics can be found in online help.
  19672.  
  19673.  Topic                                 Access
  19674.  ────────────────────────────────────────────────────────────────────────────
  19675.  Syntax and procedural information on  Choose these topics from the
  19676.  LINK, BIND, and LIB                   "Microsoft Advisor Contents" screen
  19677.  
  19678.  Syntax and procedural information on  Choose "Miscellaneous" from the list
  19679.  EXEHDR                                of utilities on the "Microsoft
  19680.                                        Advisor Contents" screen
  19681.  
  19682.  
  19683.  
  19684.  
  19685.  
  19686.  
  19687.  
  19688.  Chapter 13  Module-Definition Files
  19689.  ────────────────────────────────────────────────────────────────────────────
  19690.  
  19691.  This chapter describes the contents of a module-definition file. It begins
  19692.  with a brief overview of the purpose of module-definition files. The rest of
  19693.  the chapter discusses each statement in a module-definition file and
  19694.  describes syntax rules, argument fields, attributes, and keywords for each
  19695.  statement.
  19696.  
  19697.  
  19698.  13.1  Overview
  19699.  
  19700.  A module-definition file is a text file that describes the name, attributes,
  19701.  exports, imports, system requirements, and other characteristics of an
  19702.  application or dynamic-link library (DLL) for OS/2 or Microsoft Windows.
  19703.  This file is required for DLLs and is optional (but desirable) for OS/2 and
  19704.  Windows applications.
  19705.  
  19706.  You use module-definition files in two situations:
  19707.  
  19708.  
  19709.    ■   You can specify a module-definition file in LINK's deffile field. The
  19710.        module-definition file gives LINK the information it needs to
  19711.        determine how to set up the application or DLL it creates.
  19712.  
  19713.    ■   You can provide LINK with the needed information when creating an
  19714.        application by using the Microsoft Import Library Manager utility
  19715.        (IMPLIB) to create an import library from a module-definition file (or
  19716.        from the DLL created by a module-definition file). You then specify
  19717.        the import library in LINK's libraries field.
  19718.  
  19719.  
  19720.  For more information about IMPLIB, see online help.
  19721.  
  19722.  
  19723.  13.2  Module Statements
  19724.  
  19725.  A module-definition file contains one or more "module statements." Each
  19726.  module statement defines an attribute of the executable file, such as its
  19727.  name, the attributes of program segments, and the number and names of
  19728.  exported and imported functions and data. Table 13.1 summarizes the purpose
  19729.  of the module statements and shows the order in which they are discussed in
  19730.  this chapter.
  19731.  
  19732.  Table 13.1  Module Statements
  19733.  
  19734. ╓┌─────────────┌─────────────────────────────────────────────────────────────╖
  19735.  Statement     Purpose
  19736.  ────────────────────────────────────────────────────────────────────────────
  19737.  NAME          Names the application (no library created)
  19738.  LIBRARY       Names the DLL (no application created)
  19739.  DESCRIPTION   Embeds text in the application or DLL
  19740.  STUB          Adds a DOS executable file to the beginning of the file
  19741.  EXETYPE       Identifies the target operating system
  19742.  Statement     Purpose
  19743.  ────────────────────────────────────────────────────────────────────────────
  19744. EXETYPE       Identifies the target operating system
  19745.  PROTMODE      Specifies a protected-mode application or DLL
  19746.  REALMODE      Supported for compatibility
  19747.  STACKSIZE     Sets stack size in bytes
  19748.  HEAPSIZE      Sets local heap size in bytes
  19749.  CODE          Sets default attributes for all code segments
  19750.  DATA          Sets default attributes for all data segments
  19751.  SEGMENTS      Sets attributes for specific segments
  19752.  OLD           Preserves ordinals from a previous DLL
  19753.  EXPORTS       Defines exported functions
  19754.  IMPORTS       Defines imported functions
  19755.  ────────────────────────────────────────────────────────────────────────────
  19756.  
  19757.  
  19758.  
  19759.  13.2.1  Syntax Rules
  19760.  
  19761.  The syntax rules in this section apply to all statements in a
  19762.  module-definition file. Other rules specific to each statement are described
  19763.  in the sections that follow.
  19764.  
  19765.  
  19766.    ■   Statement and attribute keywords are not case sensitive. A statement
  19767.        keyword can be preceded by spaces and tabs.
  19768.  
  19769.    ■   A NAME or LIBRARY statement, if used, must precede all other
  19770.        statements.
  19771.  
  19772.    ■   Most statements appear at most once in a file and accept one
  19773.        specification of parameters and attributes. The specification follows
  19774.        the statement keyword on the same or subsequent line(s). If repeated
  19775.        with a different specification later in the file, the later statement
  19776.        overrides the earlier one.
  19777.  
  19778.    ■   The SEGMENTS, EXPORTS, and IMPORTS statements can appear more than
  19779.        once in the file and take multiple specifications, each on its own
  19780.        line. The statement keyword must appear once before the first
  19781.        specification and can be repeated before each additional
  19782.        specification.
  19783.  
  19784.    ■   Comments in the file are designated by a semicolon (;) at the
  19785.        beginning of each comment line. A comment cannot share a line with
  19786.        part or all of a statement but can appear between lines of a multiline
  19787.        statement.
  19788.  
  19789.    ■   Numeric arguments can be specified in decimal or in C-language
  19790.        notation.
  19791.  
  19792.    ■   Name arguments cannot match a reserved word.
  19793.  
  19794.  
  19795.  
  19796.  Example
  19797.  
  19798.  The sample module-definition file below gives a description for a DLL. This
  19799.  sample file includes one comment and five statements.
  19800.  
  19801.    ; Sample module-definition file
  19802.  
  19803.    LIBRARY
  19804.  
  19805.    DESCRIPTION 'Sample dynamic-link library'
  19806.  
  19807.    CODE       PRELOAD
  19808.  
  19809.    STACKSIZE  1024
  19810.  
  19811.    EXPORTS
  19812.        Init   @1
  19813.        Begin  @2
  19814.        Finish @3
  19815.        Load   @4
  19816.        Print  @5
  19817.  
  19818.  
  19819.  13.2.2  Reserved Words
  19820.  
  19821.  The following words are reserved by the linker for use in module-definition
  19822.  files. These names cannot be used as arguments in module-definition
  19823.  statements.
  19824.  
  19825.  (This figure may be found in the printed book.)
  19826.  
  19827.  * DOS4 and HUGE are obsolete but are still reserved by the linker.
  19828.  
  19829.  In addition to the words listed above, the following words are reserved for
  19830.  use by future or other versions of the linker and should be avoided.
  19831.  
  19832.  (This figure may be found in the printed book.)
  19833.  
  19834.  
  19835.  13.3  The NAME Statement
  19836.  
  19837.  The NAME statement identifies the executable file as an application (rather
  19838.  than a DLL). It can also specify the name and application type. The NAME or
  19839.  LIBRARY statement must precede all other statements. If NAME is specified,
  19840.  the LIBRARY statement cannot be used. If neither is used, the default is
  19841.  NAME and LINK creates an application.
  19842.  
  19843.  
  19844.  Syntax
  19845.  
  19846.    NAME «appname» «apptype» «NEWFILES»
  19847.  
  19848.  
  19849.  Remarks
  19850.  
  19851.  The fields can appear in any order.
  19852.  
  19853.  If appname is specified, it becomes the name of the application as it is
  19854.  known by OS/2 or Windows. This name can be any valid filename. If appname
  19855.  contains a space, begins with a nonalphabetic character, or is a reserved
  19856.  word, surround appname with double quotation marks. The name cannot exceed
  19857.  255 characters (not including surrounding quotation marks). If appname is
  19858.  not specified, the base name of the executable file becomes the name of the
  19859.  application.
  19860.  
  19861.  If apptype is specified, it defines the type of application. This
  19862.  information is kept in the executable-file header. The apptype field can
  19863.  take one of the following values:
  19864.  
  19865.  Value                             Description
  19866.  ────────────────────────────────────────────────────────────────────────────
  19867.  WINDOWAPI                         Presentation Manager (PM) or Windows
  19868.                                    application. The application uses the
  19869.                                    API provided by PM or Windows and must
  19870.                                    be executed in the PM or Windows
  19871.                                    environment. This is equivalent to the
  19872.                                    LINK option /PM:PM.
  19873.  
  19874.  WINDOWCOMPAT                      Character-mode application to run in a
  19875.                                    text window in the PM or Windows session.
  19876.                                    This is equivalent to the LINK option
  19877.                                    /PM:VIO.
  19878.  
  19879.  NOTWINDOWCOMPAT                   The default. Character-mode application
  19880.                                    that must run full screen and cannot run
  19881.                                    in a text window in PM or Windows. This
  19882.                                    is equivalent to the LINK option
  19883.                                    /PM:NOVIO.
  19884.  
  19885.  
  19886.  Specify NEWFILES to tell the operating system that the application supports
  19887.  long filenames and extended file attributes (available under OS/2 version
  19888.  1.2 and later). The synonym LONGNAMES is supported for compatibility.
  19889.  
  19890.  
  19891.  Example
  19892.  
  19893.  The example below assigns the name  calendar  to an application that can run
  19894.  in a text window in PM or Windows:
  19895.  
  19896.    NAME calendar WINDOWCOMPAT
  19897.  
  19898.  
  19899.  13.4  The LIBRARY Statement
  19900.  
  19901.  The LIBRARY statement identifies the executable file as a DLL. It can also
  19902.  specify the name of the library and the type of library-module
  19903.  initialization required. The NAME or LIBRARY statement must precede all
  19904.  other statements. If LIBRARY is specified, the NAME statement cannot be
  19905.  used. If neither is used, the default is NAME.
  19906.  
  19907.  
  19908.  Syntax
  19909.  
  19910.    LIBRARY «libraryname» «initialization»
  19911.    «PRIVATELIB»
  19912.  
  19913.  
  19914.  Remarks
  19915.  
  19916.  The fields can appear in any order.
  19917.  
  19918.  If libraryname is specified, it becomes the name of the library as it is
  19919.  known by OS/2 or Windows. This name can be any valid filename. If
  19920.  libraryname contains a space, begins with a nonalphabetic character, or is a
  19921.  reserved word, surround the name with double quotation marks. The name
  19922.  cannot exceed 255 characters. If libraryname is not given, the base name of
  19923.  the DLL file becomes the name of the library.
  19924.  
  19925.  If initialization is specified, it determines the type of initialization
  19926.  required. The initialization field can take one of the following values:
  19927.  
  19928.  Value                             Description
  19929.  ────────────────────────────────────────────────────────────────────────────
  19930.  INITGLOBAL                        The default. The library-initialization
  19931.                                    routine is called only when the library
  19932.                                    is initially loaded into memory.
  19933.  
  19934.  INITINSTANCE                      The library-initialization routine is
  19935.                                    called each time a new process gains
  19936.                                    access to the DLL. This keyword applies
  19937.                                    only to OS/2.
  19938.  
  19939.  
  19940.  If PRIVATELIB is specified, it tells Windows that only one application may
  19941.  use the DLL.
  19942.  
  19943.  
  19944.  Example
  19945.  
  19946.  The following example assigns the name  calendar  to the DLL being defined
  19947.  and specifies that library initialization is performed each time a new
  19948.  process gains access to  calendar:
  19949.  
  19950.    LIBRARY calendar INITINSTANCE
  19951.  
  19952.  
  19953.  13.5  The DESCRIPTION Statement
  19954.  
  19955.  The DESCRIPTION statement inserts specified text into the application or
  19956.  DLL. This statement is useful for embedding source-control or copyright
  19957.  information into a file.
  19958.  
  19959.  
  19960.  Syntax
  19961.  
  19962.    DESCRIPTION 'text'
  19963.  
  19964.  
  19965.  Remarks
  19966.  
  19967.  The text is a string of up to 255 characters enclosed in single or double
  19968.  quotation marks (' or "). To include a literal quotation mark in the text,
  19969.  either specify two consecutive quotation marks of the same type or enclose
  19970.  the text with the other type of quotation mark. If a DESCRIPTION statement
  19971.  is not specified, the default text is the name of the main output file as
  19972.  specified in LINK's exefile field. You can view this string by using the
  19973.  Microsoft EXE File Header Utility (EXEHDR).
  19974.  
  19975.  The DESCRIPTION statement is different from a comment. A comment is a line
  19976.  that begins with a semicolon (;). Comments are not placed in the application
  19977.  or library.
  19978.  
  19979.  
  19980.  Example
  19981.  
  19982.  The following example inserts the text  Tester's Version, Test "A",
  19983.  including a literal single quotation mark and a pair of literal double
  19984.  quotation marks, into the application or DLL being defined:
  19985.  
  19986.    DESCRIPTION "Tester's Version, Test ""A"""
  19987.  
  19988.  
  19989.  13.6  The STUB Statement
  19990.  
  19991.  The STUB statement adds a DOS executable file to the beginning of an OS/2 or
  19992.  Windows application or DLL. The stub is invoked whenever the file is
  19993.  executed under DOS. Usually, the stub displays a message and terminates
  19994.  execution. By default, LINK adds a standard stub for this purpose. Use the
  19995.  STUB statement when creating a dual-mode program.
  19996.  
  19997.  
  19998.  Syntax
  19999.  
  20000.    STUB {'filename' | NONE}
  20001.  
  20002.  
  20003.  Remarks
  20004.  
  20005.  The filename specifies the DOS executable file to be added. LINK searches
  20006.  for filename first in the current directory and then in directories
  20007.  specified with the PATH environment variable. The filename must be
  20008.  surrounded by single or double quotation marks (' or ").
  20009.  
  20010.  The alternate specification NONE prevents LINK from adding a default stub.
  20011.  This saves space in the application or DLL, but the resulting file will hang
  20012.  the system if loaded in DOS.
  20013.  
  20014.  
  20015.  Example
  20016.  
  20017.  The following example inserts the DOS executable file STOPIT.EXE at the
  20018.  beginning of the application or DLL:
  20019.  
  20020.    STUB 'STOPIT.EXE'
  20021.  
  20022.  The file STOPIT.EXE is executed when you attempt to run the application or
  20023.  DLL under DOS.
  20024.  
  20025.  
  20026.  13.7  The EXETYPE Statement
  20027.  
  20028.  The EXETYPE statement specifies under which operating system the application
  20029.  or DLL is to run. This statement is optional and provides an additional
  20030.  degree of protection against the program being run under an incorrect
  20031.  operating system.
  20032.  
  20033.  
  20034.  Syntax
  20035.  
  20036.    EXETYPE «OS2 | WINDOWS« version» |
  20037.    UNKNOWN»
  20038.  
  20039.  
  20040.  Remarks
  20041.  
  20042.  The EXETYPE keyword is followed by a descriptor of the operating system,
  20043.  either OS2 (for OS/2 applications and DLLs), WINDOWS (for WINDOWS
  20044.  applications and DLLs), or UNKNOWN (for other applications). The default
  20045.  without a descriptor or an EXETYPE statement is OS2.
  20046.  
  20047.  EXETYPE sets bits in the header which identify the operating system.
  20048.  Operating-system loaders can check these bits.
  20049.  
  20050.  
  20051.  Windows Programming
  20052.  
  20053.  The WINDOWS descriptor takes an optional version number. Windows reads this
  20054.  number to determine the minimum version of Windows needed to load the
  20055.  application or DLL. For example, if 3.0 is specified, the resulting
  20056.  application or DLL
  20057.  
  20058.  can run under Windows versions 3.0 and higher. If version is not specified,
  20059.  the default is 3.0. The syntax for version is
  20060.  
  20061.  number«.«number» »
  20062.  
  20063.  where each number is a decimal integer.
  20064.  
  20065.  In Windows programming, use the EXETYPE statement with a PROTMODE statement
  20066.  to specify an application or DLL that runs only under protected-mode
  20067.  Windows.
  20068.  
  20069.  
  20070.  13.8  The PROTMODE Statement
  20071.  
  20072.  The PROTMODE statement specifies that the application or DLL runs only under
  20073.  OS/2 or under Windows 3.0 standard mode and 386 enhanced mode. PROTMODE lets
  20074.  LINK optimize to reduce both the size of the file on disk and its loading
  20075.  time. However, an OS/2 program created with PROTMODE cannot be bound using
  20076.  BIND. Use PROTMODE in combination with an EXETYPE WINDOWS statement to
  20077.  define an application or DLL that runs only under protected-mode Windows.
  20078.  
  20079.  
  20080.  Syntax
  20081.  
  20082.    PROTMODE
  20083.  
  20084.  
  20085.  Example
  20086.  
  20087.  The following statement combination defines an application that runs only
  20088.  under protected-mode (standard or 386 enhanced) Windows version 3.0:
  20089.  
  20090.    EXETYPE WINDOWS 3.0
  20091.    PROTMODE
  20092.  
  20093.  
  20094.  
  20095.  
  20096.  
  20097.  13.9  The REALMODE Statement
  20098.  
  20099.  The REALMODE statement specifies that the application runs only in real
  20100.  mode. This statement is supported for compatibility with existing
  20101.  module-definition files. Use EXETYPE instead.
  20102.  
  20103.  
  20104.  Syntax
  20105.  
  20106.    REALMODE
  20107.  
  20108.  
  20109.  13.10  The STACKSIZE Statement
  20110.  
  20111.  The STACKSIZE statement specifies the size of the stack in bytes. It
  20112.  performs the same function as LINK's /STACK option. If both are specified,
  20113.  the STACKSIZE statement overrides the /STACK option.
  20114.  
  20115.  
  20116.  Syntax
  20117.  
  20118.    STACKSIZE number
  20119.  
  20120.  
  20121.  Remarks
  20122.  
  20123.  The number must be a positive integer, in decimal or C-language notation, up
  20124.  to 64K.
  20125.  
  20126.  
  20127.  Example
  20128.  
  20129.  The following example allocates 4,096 bytes of stack space:
  20130.  
  20131.    STACKSIZE 4096
  20132.  
  20133.  
  20134.  13.11  The HEAPSIZE Statement
  20135.  
  20136.  The HEAPSIZE statement defines the size of the application or DLL's local
  20137.  heap in bytes. This value affects the size of the default data segment
  20138.  (DGROUP). The default without HEAPSIZE is no local heap.
  20139.  
  20140.  
  20141.  Syntax
  20142.  
  20143.    HEAPSIZE {bytes | MAXVAL}
  20144.  
  20145.  
  20146.  Remarks
  20147.  
  20148.  The bytes field accepts a positive integer in decimal or C-language
  20149.  notation. The limit is MAXVAL; if bytes exceeds MAXVAL, the excess is not
  20150.  allocated.
  20151.  
  20152.  MAXVAL is a keyword that sets the heap size to 64K minus the size of DGROUP.
  20153.  This is useful in bound applications when you want to force a 64K
  20154.  requirement for DGROUP for the program in DOS. The bound program fails to
  20155.  load if 64K of memory is not available.
  20156.  
  20157.  
  20158.  Example
  20159.  
  20160.  The following example sets the local heap to 4,000 bytes:
  20161.  
  20162.    HEAPSIZE 4000
  20163.  
  20164.  
  20165.  13.12  The CODE Statement
  20166.  
  20167.  The CODE statement defines the default attributes for all code segments
  20168.  within the application or DLL. The SEGMENTS statement can override this
  20169.  default for one or more specific segments.
  20170.  
  20171.  
  20172.  Syntax
  20173.  
  20174.    CODE «attribute...»
  20175.  
  20176.  
  20177.  Remarks
  20178.  
  20179.  This statement accepts several optional attribute fields: conforming,
  20180.  discard, executeonly, iopl, load, movable, and shared. Each can appear once,
  20181.  in any order. These fields are described in Section 13.15, "CODE, DATA, and
  20182.  SEGMENTS Attributes."
  20183.  
  20184.  
  20185.  Example
  20186.  
  20187.  The following example sets defaults for the program's code segments. No code
  20188.  segments in the program are loaded until accessed, and all require I/O
  20189.  hardware privilege.
  20190.  
  20191.    CODE LOADONCALL IOPL
  20192.  
  20193.  
  20194.  13.13  The DATA Statement
  20195.  
  20196.  The DATA statement defines the default attributes for all data segments
  20197.  within the application or DLL. The SEGMENTS statement can override this
  20198.  default for one or more specific segments.
  20199.  
  20200.  
  20201.  Syntax
  20202.  
  20203.    DATA «attribute...»
  20204.  
  20205.  
  20206.  Remarks
  20207.  
  20208.  This statement accepts several optional attribute fields: instance, iopl,
  20209.  load, movable, readonly, and shared. Each can appear once, in any order.
  20210.  These fields are described in Section 13.15, "CODE, DATA, and SEGMENTS
  20211.  Attributes."
  20212.  
  20213.  
  20214.  Example
  20215.  
  20216.  The example below defines the application's data segment so that it cannot
  20217.  be shared by multiple copies of the program and cannot be written to. By
  20218.  default, the data segment can be read and written to and a new DGROUP is
  20219.  created for each instance of the application.
  20220.  
  20221.    DATA NONSHARED READONLY
  20222.  
  20223.  
  20224.  13.14  The SEGMENTS Statement
  20225.  
  20226.  The SEGMENTS statement defines the attributes of one or more individual
  20227.  segments in the application or DLL. The attributes specified for a specific
  20228.  segment override the defaults set in the CODE and DATA statements (except as
  20229.  noted below). The total number of segment definitions cannot exceed the
  20230.  number set using LINK's /SEG option. (The default without /SEG is 128.)
  20231.  
  20232.  The SEGMENTS keyword marks the beginning of the segment definitions, where
  20233.  each definition is on its own line. The SEGMENTS statement must appear once
  20234.  before the first specification (on the same or preceding line) and can be
  20235.  repeated before each additional specification. SEGMENTS statements can
  20236.  appear more than once in the file.
  20237.  
  20238.  
  20239.  Syntax
  20240.  
  20241.    SEGMENTS
  20242.              «'»segmentname«'» «CLASS 'classname'»
  20243.    «attribute...»
  20244.  
  20245.  
  20246.  Remarks
  20247.  
  20248.  Each segment definition begins with segmentname, optionally enclosed in
  20249.  single or double quotation marks (' or "). The quotation marks are required
  20250.  if segmentname is a reserved word.
  20251.  
  20252.  The CLASS keyword optionally specifies the class of the segment. Single or
  20253.  double quotation marks (' or ") are required around classname. If you do not
  20254.  use the CLASS argument, the linker assumes that the class is CODE.
  20255.  
  20256.  This statement accepts several optional attribute fields: conforming,
  20257.  discard, executeonly, iopl, load, movable, readonly, and shared. Each can
  20258.  appear once, in any order. These fields are described in the next section,
  20259.  "CODE, DATA, and SEGMENTS Attributes."
  20260.  
  20261.  
  20262.  Example
  20263.  
  20264.  The following example specifies segments named  cseg1,  cseg2, and  dseg.
  20265.  The first segment is assigned the class  mycode  and the second is assigned
  20266.  CODE by default. Each segment is given different attributes.
  20267.  
  20268.    SEGMENTS
  20269.        cseg1 CLASS 'mycode' IOPL
  20270.        cseg2    EXECUTEONLY PRELOAD CONFORMING
  20271.        dseg  CLASS 'data'   LOADONCALL READONLY
  20272.  
  20273.  
  20274.  13.15  CODE, DATA, and SEGMENTS Attributes
  20275.  
  20276.  The following attribute fields apply to the CODE, DATA, and SEGMENTS
  20277.  statements previously described. Refer to "Remarks" in each of the previous
  20278.  sections for the attribute fields that are used by each statement. Most
  20279.  fields are used by all three statements; others are used as noted. Each
  20280.  field can appear once, in any order.
  20281.  
  20282.  Listed with each attribute field below are keywords that are legal values
  20283.  for the field, along with descriptions of the field and values. The defaults
  20284.  are noted. If two segments with different attributes are combined into the
  20285.  same group, LINK makes decisions to resolve any conflicts and assumes a set
  20286.  of attributes.
  20287.  
  20288. ╓┌───────────────────┌───────────────────────────────────────────────────────╖
  20289.  Attribute           Description
  20290.  ────────────────────────────────────────────────────────────────────────────
  20291.  conforming          {CONFORMING | NONCONFORMING}
  20292.  
  20293.                      For CODE and SEGMENTS statements only. Determines
  20294.                      whether a code segment is an 80286 "conforming"
  20295.                      segment for device drivers and system-level code. The
  20296.                      conforming attribute is for OS/2 only.
  20297.  
  20298.                      CONFORMING specifies that the segment executes at the
  20299.                      caller's privilege level. When IOPL=YES is specified
  20300.                      in CONFIG.SYS, no call gates are generated for calls
  20301.                      or jumps.
  20302.  
  20303.                      NONCONFORMING (the default) specifies that the segment
  20304.                      can be accessed from Ring 2. When IOPL=YES is
  20305.                      specified in CONFIG.SYS, call gates are generated.
  20306.  
  20307.                      For more information, refer to Intel documentation for
  20308.                      the 80286 processor and later.
  20309.  Attribute           Description
  20310.  ────────────────────────────────────────────────────────────────────────────
  20311.                     the 80286 processor and later.
  20312.  
  20313.  discard             {DISCARDABLE | NONDISCARDABLE}
  20314.  
  20315.                      For CODE and SEGMENTS statements only. Determines
  20316.                      whether a code segment can be discarded from memory
  20317.                      to fill a different memory request. If the discarded
  20318.                      segment is accessed later, it is reloaded from disk.
  20319.                      NONDISCARDABLE is the default. The discard attribute
  20320.                      is for Windows only.
  20321.  
  20322.  
  20323.  
  20324.  
  20325.  executeonly         {EXECUTEONLY | EXECUTEREAD}
  20326.  
  20327.                      For CODE and SEGMENTS statements only. Determines
  20328.                      whether a code segment can be read as well as executed.
  20329.  
  20330.  Attribute           Description
  20331.  ────────────────────────────────────────────────────────────────────────────
  20332. 
  20333.                      EXECUTEONLY specifies that the segment can only be
  20334.                      executed. The keyword EXECUTE-ONLY is an alternate
  20335.                      spelling.
  20336.  
  20337.                      EXECUTEREAD (the default) specifies that the segment
  20338.                      is both executable and readable. This attribute is
  20339.                      necessary for a program to run under the Microsoft
  20340.                      CodeView debugger.
  20341.  
  20342.  instance            {NONE | SINGLE | MULTIPLE}
  20343.  
  20344.                      For the DATA statement only. Affects the sharing
  20345.                      attributes of the default data segment (DGROUP). This
  20346.                      attribute interacts with the shared attribute.
  20347.  
  20348.                      NONE tells the loader not to allocate DGROUP. Use NONE
  20349.                      when a DLL has no data and uses an application's
  20350.                      DGROUP.
  20351.  Attribute           Description
  20352.  ────────────────────────────────────────────────────────────────────────────
  20353.                     DGROUP.
  20354.  
  20355.                      SINGLE (the default for DLLs) specifies that one
  20356.                      DGROUP is shared by all instances of the DLL or
  20357.                      application.
  20358.  
  20359.                      MULTIPLE (the default for applications) specifies that
  20360.                      DGROUP is copied for each instance of the DLL or
  20361.                      application.
  20362.  
  20363.  iopl                {IOPL | NOIOPL}
  20364.  
  20365.                      Determines whether a segment has I/O privilege. OS/2
  20366.                      only.
  20367.  
  20368.                      IOPL specifies that a code segment has I/O privilege
  20369.                      and that a data segment can be accessed only from an
  20370.                      IOPL code segment.
  20371.  
  20372.  Attribute           Description
  20373.  ────────────────────────────────────────────────────────────────────────────
  20374. 
  20375.                      NOIOPL (the default) specifies that there is no I/O
  20376.                      privilege for code and no protection for data.
  20377.  
  20378.  load                {PRELOAD | LOADONCALL}
  20379.  
  20380.                      Determines when a segment is loaded.
  20381.  
  20382.  
  20383.  
  20384.  (load,              PRELOAD specifies that the segment is loaded when the
  20385.  continued)          program starts.
  20386.  
  20387.                      LOADONCALL (the default) specifies that the segment is
  20388.                      not loaded until accessed and only if not already
  20389.                      loaded.
  20390.  
  20391.  movable             {MOVABLE | FIXED}
  20392.  
  20393.  Attribute           Description
  20394.  ────────────────────────────────────────────────────────────────────────────
  20395. 
  20396.                      Determines whether a segment can be moved in memory.
  20397.                      Windows only. FIXED is the default. An alternative
  20398.                      spelling for MOVABLE is MOVEABLE.
  20399.  
  20400.  readonly            {READONLY | READWRITE}
  20401.  
  20402.                      For DATA and SEGMENTS statements only. Determines
  20403.                      access rights to a data segment.
  20404.  
  20405.                      READONLY specifies that the segment can only be read.
  20406.  
  20407.                      READWRITE (the default) specifies that the segment is
  20408.                      both readable and writeable.
  20409.  
  20410.  shared              {SHARED | NONSHARED}
  20411.  
  20412.                      For real-mode Windows and for READWRITE data segments
  20413.                      under OS/2 only. Determines whether all instances of
  20414.  Attribute           Description
  20415.  ────────────────────────────────────────────────────────────────────────────
  20416.                     under OS/2 only. Determines whether all instances of
  20417.                      the program can share EXECUTEREAD and READWRITE
  20418.                      segments. (Under OS/2, all code segments and READONLY
  20419.                      data segments are shared.)
  20420.  
  20421.                      SHARED (the default for DLLs) specifies that one copy
  20422.                      of the segment is loaded and shared among all
  20423.                      processes accessing the application or DLL. This
  20424.                      attribute saves memory and can be used for code that
  20425.                      is not self-modifying. An alternate keyword is PURE.
  20426.  
  20427.                      NONSHARED (the default for applications) specifies
  20428.                      that the segment must be loaded separately for each
  20429.                      process. An alternate keyword is IMPURE.
  20430.  
  20431.                      This attribute and the instance attribute interact for
  20432.                      data segments. The instance attribute has the keywords
  20433.                      NONE, SINGLE, and MULTIPLE. If  DATA SINGLE  is
  20434.                      specified, LINK assumes SHARED; if  DATA MULTIPLE  is
  20435.  Attribute           Description
  20436.  ────────────────────────────────────────────────────────────────────────────
  20437.                     specified, LINK assumes SHARED; if  DATA MULTIPLE  is
  20438.                      specified, LINK assumes NONSHARED. Similarly,  DATA
  20439.                      SHARED  forces SINGLE, and  DATA NONSHARED  forces
  20440.                      MULTIPLE.
  20441.  
  20442.  
  20443.  
  20444.  
  20445.  13.16  The OLD Statement
  20446.  
  20447.  The OLD statement directs the linker to search another DLL for export
  20448.  ordinals. This statement preserves ordinal values used from older versions
  20449.  of a DLL. For more information on ordinals, see the sections below on the
  20450.  EXPORTS and IMPORTS statements.
  20451.  
  20452.  Exported names in the current DLL that match exported names in the old DLL
  20453.  are assigned ordinal values from the earlier DLL unless
  20454.  
  20455.  
  20456.    ■   The name in the old module has no ordinal value assigned, or
  20457.  
  20458.    ■   An ordinal value is explicitly assigned in the current DLL.
  20459.  
  20460.  
  20461.  Only one DLL can be specified; ordinals can be preserved from only one DLL.
  20462.  The OLD statement has no effect on applications.
  20463.  
  20464.  
  20465.  Syntax
  20466.  
  20467.    OLD 'filename'
  20468.  
  20469.  
  20470.  Remarks
  20471.  
  20472.  The filename specifies the DLL to be searched. It must be enclosed in single
  20473.  or double quotation marks (' or ").
  20474.  
  20475.  
  20476.  13.17  The EXPORTS Statement
  20477.  
  20478.  The EXPORTS statement defines the names and attributes of the functions and
  20479.  data made available to other applications and DLLs, and of the functions
  20480.  that run with I/O privilege. By default, functions and data are hidden from
  20481.  other programs at run time. A definition is required for each function or
  20482.  data item being exported.
  20483.  
  20484.  The EXPORTS keyword marks the beginning of the export definitions, each on
  20485.  its own line. The EXPORTS keyword must appear once before the first
  20486.  definition (on the same or preceding line) and can be repeated before each
  20487.  additional definition. EXPORTS statements can appear more than once in the
  20488.  file.
  20489.  
  20490.  Some languages offer a way to export without using an EXPORTS statement. For
  20491.  example, in C the _exports keyword makes a function available from a DLL.
  20492.  
  20493.  
  20494.  Syntax
  20495.  
  20496.    EXPORTS
  20497.    entryname«=internalname» «@ord«
  20498.    RESIDENTNAME» » «NODATA» «pwords»
  20499.  
  20500.  
  20501.  Remarks
  20502.  
  20503.  The entryname defines the function or data-item name as it is known to other
  20504.  programs. The optional internalname defines the actual name of the exported
  20505.  function or data item as it appears within the exporting program; by
  20506.  default, this name is the same as entryname.
  20507.  
  20508.  The optional ord field defines a function's ordinal position within the
  20509.  moduledefinition table as an integer from 1 to 65,535. If ord is specified,
  20510.  the function can be called by either entryname or ord. Use of ord is faster
  20511.  and can save space.
  20512.  
  20513.  The optional keyword RESIDENTNAME specifies that entryname be kept resident
  20514.  in memory at all times. This keyword is applicable only if ord is used. (If
  20515.  ord is not used, the name entryname is always kept in memory.)
  20516.  
  20517.  The optional keyword NODATA specifies that there is no static data in the
  20518.  function.
  20519.  
  20520.  The pwords field specifies the total size of the function's parameters in
  20521.  words. This field is required only if the function executes with I/O
  20522.  privilege. When a function with I/O privilege is called, OS/2 consults
  20523.  pwords to determine how many words to copy from the caller's stack to the
  20524.  I/O-privileged function's stack.
  20525.  
  20526.  
  20527.  Example
  20528.  
  20529.  The following EXPORTS statement defines the three exported functions
  20530.  SampleRead,  StringIn, and  CharTest. The first two functions can be called
  20531.  either by their exported names or by an ordinal number. In the application
  20532.  or DLL where they are defined, these functions are named  read2bin  and
  20533.  str1, respectively. The first and last functions run with I/O privilege and
  20534.  therefore are given with the total size of the parameters.
  20535.  
  20536.    EXPORTS
  20537.           SampleRead = read2bin @8              24
  20538.           StringIn   = str1     @4 RESIDENTNAME
  20539.           CharTest                              6
  20540.  
  20541.  
  20542.  13.18  The IMPORTS Statement
  20543.  
  20544.  The IMPORTS statement defines the names and locations of functions and data
  20545.  items to be imported (usually from a DLL) for use in the application or DLL.
  20546.  A definition is required for each function or data item being imported. This
  20547.  statement is an alternative to resolving references through an import
  20548.  library created by the IMPLIB utility; functions and data items listed in an
  20549.  import library do not require an IMPORTS definition.
  20550.  
  20551.  The IMPORTS keyword marks the beginning of the import definitions, each on
  20552.  its own line. The IMPORTS keyword must appear once before the first
  20553.  definition on the same or preceding line and can be repeated before each
  20554.  additional definition. IMPORTS statements can appear more than once in the
  20555.  file.
  20556.  
  20557.  
  20558.  Syntax
  20559.  
  20560.    IMPORTS
  20561.              «internalname=»modulename.entry
  20562.  
  20563.  
  20564.  Remarks
  20565.  
  20566.  The internalname specifies the function or data-item name as it is used in
  20567.  the importing application or DLL. Thus, internalname appears in the source
  20568.  code of the importing program, while the function may have a different name
  20569.  in the program where it is defined. By default, internalname is the same as
  20570.  the entry name. An internalname is required if entry is an ordinal value.
  20571.  
  20572.  The modulename is the filename of the exporting application or DLL that
  20573.  contains the function or data item.
  20574.  
  20575.  The entry field specifies the name or ordinal value of the function or data
  20576.  item as defined in the modulename application or DLL. If entry is an ordinal
  20577.  value, internalname must be specified. (Ordinal values are set in an EXPORTS
  20578.  statement.)
  20579.  
  20580.  ────────────────────────────────────────────────────────────────────────────
  20581.  NOTE
  20582.  
  20583.  A given symbol (function or data item) has a name for each of three
  20584.  different contexts. The symbol has a name used by the exporting program
  20585.  (application or DLL) where it is defined, a name used as an entry point
  20586.  between programs, and a name used by the importing program where the symbol
  20587.  is used. If neither program uses the optional internalname field, the symbol
  20588.  has the same name in all three contexts. If either of the programs uses the
  20589.  internalname field, the symbol may have more than one distinct name.
  20590.  ────────────────────────────────────────────────────────────────────────────
  20591.  
  20592.  
  20593.  Example
  20594.  
  20595.  The following IMPORTS statement defines three functions to be imported:
  20596.  SampleRead,  SampleWrite, and a function that has been assigned an ordinal
  20597.  value of 1. The functions are found in the  Sample,  SampleA, and  Read
  20598.  applications or DLLs, respectively. The function from  Read  is referred to
  20599.  as  ReadChar  in the importing application or DLL. The original name of the
  20600.  function, as it is defined in  Read, may or may not be known and is not
  20601.  included in the IMPORTS statement.
  20602.  
  20603.    IMPORTS
  20604.                   Sample.SampleRead
  20605.                   SampleA.SampleWrite
  20606.        ReadChar = Read.1
  20607.  
  20608.  
  20609.  13.19  Related Topics in Online Help
  20610.  
  20611.  In addition to information covered in this chapter, information on the
  20612.  following topics can be found in online help.
  20613.  
  20614.  Topic                                 Access
  20615.  ────────────────────────────────────────────────────────────────────────────
  20616.  Syntax and procedural information on  Choose "LIB" from the list of
  20617.  LIB                                   utilities on the "Microsoft Advisor
  20618.                                        Contents" screen
  20619.  
  20620.  Module-definition files and IMPLIB    Choose "LINK" from the list of
  20621.                                        utilities on the "Microsoft Advisor
  20622.                                        Contents" screen
  20623.  
  20624.  
  20625.  
  20626.  
  20627.  
  20628.  
  20629.  
  20630.  
  20631.  
  20632.  Chapter 14  Customizing the Microsoft Programmer's WorkBench
  20633.  ────────────────────────────────────────────────────────────────────────────
  20634.  
  20635.  The Microsoft Programmer's WorkBench (PWB) is not just a text editor, but
  20636.  also a full-featured platform for program development. It is both flexible
  20637.  (you can customize it to match your working habits) and extensible (you can
  20638.  add your own functions and features).
  20639.  
  20640.  This chapter explains three ways to customize the Programmer's WorkBench:
  20641.  
  20642.  
  20643.    ■   Setting switches
  20644.  
  20645.    ■   Assigning keystrokes
  20646.  
  20647.    ■   Writing macros
  20648.  
  20649.  
  20650.  While this chapter explains customizing techniques, it does not document
  20651.  every customizable feature. Please consult online help for detailed
  20652.  information about these and other PWB features.
  20653.  
  20654.  This chapter assumes you are familiar with basic PWB operation and
  20655.  terminology. If not, please read "Using the Programmer's WorkBench" in
  20656.  Installing and Using the Microsoft Macro Assembler Professional Development
  20657.  System. The Programmer's WorkBench is supplied with both the Macro Assembler
  20658.  and Microsoft C so that you can customize one copy of PWB to work with these
  20659.  and other languages.
  20660.  
  20661.  
  20662.  14.1  Setting Switches
  20663.  
  20664.  The Programmer's WorkBench has a number of "switches," or user-configurable
  20665.  options, that control features such as how many lines the screen scrolls or
  20666.  whether you are prompted to save a file when you exit. Each switch has a
  20667.  name and can be assigned a value.
  20668.  
  20669.  There are two ways to set PWB switches. The easiest way is to choose Editor
  20670.  Settings from the Options menu. Saving the changes made to Editor Settings
  20671.  updates your TOOLS.INI initialization file. You can also directly edit
  20672.  TOOLS.INI. Either method can be used for more elaborate customizations, such
  20673.  as writing macros.
  20674.  
  20675.  
  20676.  14.1.1  Changing Current Assignments and Switch Settings
  20677.  
  20678.  You can change the current editor switches and key assignments. Choose
  20679.  Editor Settings or Key Assignments from the Options menu. PWB displays these
  20680.  settings in a new window labeled Current Assignments and Switch Settings.
  20681.  
  20682.  The <ASSIGN> pseudofile is associated with the Current Assignments and
  20683.  Switch Settings window. A pseudofile exists only in memory; it has no
  20684.  counterpart on disk until you explicitly save it. Saving the <ASSIGN>
  20685.  pseudofile automatically saves any changes you make in the Current
  20686.  Assignments and Switch Settings window.
  20687.  
  20688.  To change a switch, edit the line on which it appears. For instance, the
  20689.  vscroll switch controls how many lines PWB scrolls vertically; its default
  20690.  setting is 1. To change it, move to the corresponding line:
  20691.  
  20692.    vscroll:1
  20693.  
  20694.  Change the 1 to 3 and move the cursor to another line. PWB highlights the
  20695.  line to indicate that the change has been executed. (If you make an illegal
  20696.  change, PWB signals an error.) The change takes effect immediately: PWB now
  20697.  scrolls text three lines at a time.
  20698.  
  20699.  When you save <ASSIGN>, PWB updates your TOOLS.INI file.
  20700.  
  20701.  PWB discards all changes at the end of a session unless you explicitly save
  20702.  them. You save changes by saving <ASSIGN> as you would any other file.
  20703.  Select Save from the File menu, or press SHIFT+F2.
  20704.  
  20705.  You can also use this method for more elaborate customizations, such as
  20706.  writing macros (see Section 14.3, "Writing Macros"). Simply insert a few
  20707.  blank lines in the Current Assignments and Switch Settings window and enter
  20708.  the new information in them.
  20709.  
  20710.  If you add or modify a line of the Current Assignments and Switch Settings
  20711.  window, PWB immediately alters its behavior accordingly; the new or changed
  20712.  lines are saved in TOOLS.INI when you save the <ASSIGN> file. However,
  20713.  deleting a line has no effect, either on PWB's behavior or the contents of
  20714.  TOOLS.INI; you must edit TOOLS.INI to remove an assignment.
  20715.  
  20716.  
  20717.  14.1.2  Editing the TOOLS.INI Initialization File
  20718.  
  20719.  Another way to customize PWB is by editing TOOLS.INI, the initialization
  20720.  file used by PWB and other Microsoft language utilities. This is the most
  20721.  convenient way to perform extensive customizing.
  20722.  
  20723.  While the Current Assignments and Switch Settings window displays every
  20724.  customizable PWB item, the TOOLS.INI file contains lines only for items you
  20725.  have customized. PWB sets any items you omit from TOOLS.INI to a default
  20726.  value.
  20727.  
  20728.  TOOLS.INI is made up of sections that start with tags.
  20729.  
  20730.  Since TOOLS.INI can initialize a number of Microsoft tools, the file is
  20731.  divided into sections, one for each tool. Each section begins with a tag
  20732.  consisting of the tool's base name enclosed in square brackets:  [PWB]  for
  20733.  PWB.EXE,  [NMAKE]  for NMAKE.EXE, and so on.
  20734.  
  20735.  For example, assume you set the vscroll switch to 3 and saved the change,
  20736.  but you have not customized PWB in any other way. Your TOOLS.INI file will
  20737.  contain this section:
  20738.  
  20739.    [PWB]
  20740.    vscroll:3
  20741.  
  20742.  PWB reads TOOLS.INI at start-up and loads the settings from the  [PWB]
  20743.  section.
  20744.  
  20745.  You can also create sections of TOOLS.INI that configure PWB for specific
  20746.  programming languages or operating systems. For instance, your TOOLS.INI
  20747.  file could contain a section beginning with the tag
  20748.  
  20749.    [PWB-.C]
  20750.  
  20751.  for C source files, and
  20752.  
  20753.    [PWB-.ASM]
  20754.  
  20755.  TOOLS.INI sections contain customization information.
  20756.  
  20757.  for assembly-language (.ASM) source files. Each time you load a file with
  20758.  the designated extension, PWB reads the appropriate section of TOOLS.INI.
  20759.  You can have a different set of macros and other customizations for each
  20760.  file type.
  20761.  
  20762.  TOOLS.INI can also contain sections specific to an operating system. The
  20763.  following tag introduces a section specific to DOS version 3.31, for
  20764.  instance:
  20765.  
  20766.    [PWB-3.31]
  20767.  
  20768.  You can combine tags as needed. For example, the tag
  20769.  
  20770.    [PWB-3.0 PWB-10.10R]
  20771.  
  20772.  applies to DOS version 3.0 and OS/2 version 1.1 real mode.
  20773.  
  20774.  
  20775.  14.2  Assigning Functions to Keystrokes
  20776.  
  20777.  You can assign any PWB function to almost any keystroke. Keystroke
  20778.  assignments, like switches, are displayed in the Current Assignments and
  20779.  Switch Settings window (choose Key Assignments from the Options menu) and
  20780.  can be
  20781.  
  20782.  changed there. Suppose you want to assign the home cursor function to
  20783.  SHIFT+HOME. The default keystroke assignment for home is
  20784.  
  20785.    home:Goto
  20786.  
  20787.  If you change the assignment to
  20788.  
  20789.    home:Shift+Home
  20790.  
  20791.  SHIFT+HOME moves the cursor to the home (upper left) window position.
  20792.  
  20793.  You can assign the same function to more than one keystroke. For example,
  20794.  many keystrokes invoke the select function, which selects a text region. The
  20795.  preceding example adds a new keystroke (SHIFT+HOME) for the home function,
  20796.  but it does not remove the previous assignment (GOTO, the 5 key on the
  20797.  keypad).
  20798.  
  20799.  If you aren't sure whether a keystroke is already assigned, select the
  20800.  Current Assignments and Switch Settings window and press PGDN until you
  20801.  reach the Available Keys table. All unassigned keystrokes are displayed;
  20802.  once a keystroke is assigned, it no longer appears in this table.
  20803.  
  20804.  There are two limitations on keystroke assignments:
  20805.  
  20806.  
  20807.    ■   You should not reassign a keystroke that PWB assigns to a menu. For
  20808.        instance, ALT+F displays the File menu; PWB ignores any attempt to
  20809.        reassign ALT+F.
  20810.  
  20811.    ■   You should not reassign the ALT plus number keys 1- 6 (ALT+1, ALT+2,
  20812.        and so on). These keystrokes are reserved for the file history menu
  20813.        items.
  20814.  
  20815.  
  20816.  PWB uses the most recent duplicate key assignment.
  20817.  
  20818.  A keystroke can invoke only one function. If you accidentally assign a
  20819.  keystroke to more than one function, PWB uses the most recent assignment.
  20820.  For example,
  20821.  
  20822.    home:Ctrl+A
  20823.    setfile:Ctrl+A
  20824.  
  20825.  assigns the CTRL+A keystroke to two different functions, home and setfile.
  20826.  The second assignment overrides the first, assigning CTRL+A to setfile.
  20827.  
  20828.  You might occasionally want to "unassign," or disable, a keystroke. This is
  20829.  done by assigning the unassigned function to the keystroke. For example,
  20830.  
  20831.    unassigned:Ctrl+A
  20832.  
  20833.  disables CTRL+A. PWB signals an error when you press any unassigned key.
  20834.  
  20835.  As the list of assigned keystrokes shows, you can use SHIFT+CTRL as a
  20836.  prefix. For PWB to recognize this key combination, SHIFT must come first.
  20837.  For example, to use SHIFT+CTRL with M, you must type SHIFT+CTRL+M, not
  20838.  CTRL+SHIFT+M.
  20839.  
  20840.  
  20841.  14.3  Writing Macros
  20842.  
  20843.  If you need a feature or function that is not a part of PWB, the quickest
  20844.  way to create it is by writing a macro in the TOOLS.INI file. A macro can do
  20845.  something as simple as inserting a line of text, or it can perform complex
  20846.  operations by invoking PWB functions and other macros.
  20847.  
  20848.  
  20849.  14.3.1  Macro Syntax
  20850.  
  20851.  A macro can consist of any combination of PWB functions, literal text, and
  20852.  calls to previously defined macros. You can define up to 1,024 macros at one
  20853.  time.
  20854.  
  20855.  Anything inside quotation marks is literal text. Within literal text,
  20856.  quotation marks are represented by a backslash followed by quotation marks
  20857.  (\ ") and a backslash is represented by two consecutive backslashes (\ \).
  20858.  Only literal text is case sensitive; PWB ignores the case of everything
  20859.  else.
  20860.  
  20861.  The following macro "comments out" a line of MASM source code:
  20862.  
  20863.    comment:=begline "; "
  20864.    comment:alt+c
  20865.  
  20866.  The first line names the macro (comment); the macro commands follow the
  20867.  assignment operator ( := ). The begline editor function moves the cursor to
  20868.  the beginning of the current line. The text inside quotation marks (the MASM
  20869.  comment delimiter) is then inserted. The second line assigns a keystroke
  20870.  (ALT+C) to the macro.
  20871.  
  20872.  Macros can extend over one line.
  20873.  
  20874.  If a macro definition takes up more space than you have on one line (about
  20875.  250 characters in PWB), you can use the backslash ( \ ) to continue the
  20876.  definition on the next line. Consider, for instance, the following macro,
  20877.  which comments out a line of C source code:
  20878.  
  20879.    comment:=begline "/* " endline " */"
  20880.  
  20881.  It could be written as
  20882.  
  20883.    comment:=begline  \
  20884.    "/* " endline  \
  20885.    " */"
  20886.  
  20887.  Notice the extra space before each backslash. If you want a space between
  20888.  the end of one line and the beginning of the next, you must precede the
  20889.  backslash with two spaces.
  20890.  
  20891.  You can pass arguments to PWB macros.
  20892.  
  20893.  You can use the arg function to pass arguments to functions. For example,
  20894.  the following macro passes the argument  15  to the plines function (which
  20895.  scrolls text down):
  20896.  
  20897.    movedown:=arg "15" plines
  20898.  
  20899.  Because arg precedes the literal text, the text isn't written to the screen.
  20900.  Instead, it is passed as an argument to the next function, plines. The macro
  20901.  scrolls the current text down 15 lines.
  20902.  
  20903.  Arguments can also use regular-expression syntax (regular expressions are
  20904.  documented in online help):
  20905.  
  20906.    endword:=arg arg "([ .,;:()[\\»!$)" psearch cancel
  20907.  
  20908.  The arg arg sequence directs the psearch function to treat the text argument
  20909.  as a regular-expression search pattern. This search pattern tells PWB to
  20910.  search for the next space, period, comma, semicolon, colon, parentheses, and
  20911.  square brackets. (Note that a backslash must precede any character that has
  20912.  a special meaning in regular expressions─in this case, the right bracket.)
  20913.  
  20914.  A macro can invoke other macros:
  20915.  
  20916.    lcomment:= "/* "
  20917.    rcomment:= " */"
  20918.    commentout:=begline lcomment endline rcomment
  20919.    commentout:ctrl+o
  20920.  
  20921.  The  commentout  macro invokes the previously defined macros  lcomment  and
  20922.  rcomment.
  20923.  
  20924.  In addition to standard PWB functions, PWB macros can invoke user-defined
  20925.  macro functions. See Section 9.6, "Returning Values with Macro Functions."
  20926.  
  20927.  
  20928.  14.3.2  Macro Responses
  20929.  
  20930.  Some PWB functions ask you for confirmation. For example, the meta exit
  20931.  (quit without saving) function normally asks if you really want to exit.
  20932.  Such questions always take the answer "yes" (Y) or "no" (N).
  20933.  
  20934.  When you invoke such a function in a macro, the function assumes an answer
  20935.  of yes and does not ask for confirmation. For example, the macro definition
  20936.  
  20937.  
  20938.    quit:=meta exit
  20939.    quit:alt+x
  20940.  
  20941.  The meta prefix modifies the action of a function.
  20942.  
  20943.  invokes meta exit when you press ALT+X. Because the meta exit function is
  20944.  invoked from a macro, PWB exits without asking for confirmation.
  20945.  
  20946.  The following operators allow you to restore normal prompting or change the
  20947.  default responses:
  20948.  
  20949.  Operator                          Description
  20950.  ────────────────────────────────────────────────────────────────────────────
  20951.  <                                 Asks for confirmation; if not followed
  20952.                                    by another
  20953.                                    < operator, prompts for all further
  20954.                                    questions
  20955.  
  20956.  <y                                Assumes a response of "yes"
  20957.  
  20958.  <n                                Assumes a response of "no"
  20959.  
  20960.  
  20961.  A response operator applies to the function immediately preceding it. For
  20962.  example, you can add the < operator to the  quit  macro definition to
  20963.  restore the usual prompt:
  20964.  ────────────────────────────────────────────────────────────────────────────
  20965.    quit:=meta exit <
  20966.    quit:alt+x
  20967.  
  20968.  Now the macro prompts for a response before it exits.
  20969.  
  20970.  
  20971.  14.3.3  Macro Arguments
  20972.  
  20973.  If you enter an argument in PWB and then invoke a macro, the argument is
  20974.  passed to the first function in the macro that takes an argument:
  20975.  
  20976.    tripleit:=copy paste paste
  20977.  
  20978.  The  tripleit  macro invokes the copy and paste editing functions. When you
  20979.  highlight a text area and then invoke the macro, your highlighted argument
  20980.  is passed to the copy function, which copies the argument to the clipboard.
  20981.  The macro then invokes paste twice. The effect is to insert two copies of
  20982.  the highlighted text.
  20983.  
  20984.  You cannot pass more than one argument from PWB to a macro.
  20985.  
  20986.  You cannot pass more than one argument from PWB to a macro, even if the
  20987.  macro invokes more than one function that can accept an argument. The
  20988.  argument always goes to the first function in the macro that takes an
  20989.  argument.
  20990.  
  20991.  You can also prompt for input inside a macro and pass the input as an
  20992.  argument using the prompt function as shown below:
  20993.  
  20994.    newfile:=arg "Next file: " prompt setfile <
  20995.    newfile:alt+n
  20996.  
  20997.  The  newfile  macro prompts for a file name and then switches to the
  20998.  specified file. The sequence  arg "Next file: "  passes the text argument
  20999.  Next file:  to prompt, which prints it in the text-argument dialog box and
  21000.  waits for the user to respond. The response is passed as a text argument to
  21001.  the setfile function, which switches to that file.
  21002.  
  21003.  
  21004.  14.3.4  Macro Conditionals
  21005.  
  21006.  Macros can take different actions depending on certain conditions. Such
  21007.  macros take advantage of the fact that PWB editing functions return values─
  21008.  a TRUE (nonzero) value if successful or FALSE (zero) if unsuccessful.
  21009.  
  21010.  Macros can use four conditional operators:
  21011.  
  21012.  Operator    Description
  21013.  ────────────────────────────────────────────────────────────────────────────
  21014.  :>label     Defines a label that can be targeted by other operators
  21015.  =>label     Jumps to label
  21016.  +>label     Jumps to label if the previous function returns TRUE
  21017.  ->label     Jumps to label if the previous function returns FALSE
  21018.  
  21019.  For example, the  leftmarg  macro moves the cursor to the left margin of
  21020.  the editing window:
  21021.  ────────────────────────────────────────────────────────────────────────────
  21022.    leftmarg:=:>leftmore left +>leftmore
  21023.  
  21024.  The macro above invokes the left function repeatedly (jumping to the label
  21025.  leftmore) until it returns FALSE, indicating the cursor has reached the left
  21026.  margin.
  21027.  
  21028.  Macro execution depends on the status of conditionals.
  21029.  
  21030.  The label must appear immediately after the conditional operator, with no
  21031.  intervening spaces. A conditional operator without a label exits the macro
  21032.  immediately if the condition is satisfied. If the condition is not
  21033.  satisfied, the macro continues execution. The following example demonstrates
  21034.  this:
  21035.  
  21036.    turnon:=insertmode +> insertmode
  21037.  
  21038.  This macro turns on insert mode regardless of whether insert mode is
  21039.  currently on or off. If insert mode is off, the first invocation of
  21040.  insertmode toggles the mode on and returns TRUE, causing the +> operator to
  21041.  terminate the macro. If insert mode is currently on, the first invocation of
  21042.  insertmode turns insert mode off and returns FALSE. The macro then invokes
  21043.  insertmode a second time, turning insert mode back on.
  21044.  
  21045.  
  21046.  14.3.5  Recording Macros
  21047.  
  21048.  You can also create a macro by recording a procedure as you perform it. The
  21049.  keystroke sequence is saved and can be replayed, like any other macro. To
  21050.  record a macro:
  21051.  
  21052.  
  21053.    1.  Choose Set Record from the Edit menu. The Set Macro Record dialog box
  21054.        appears.
  21055.  
  21056.    2.  Type the name you want the macro to have in the Name text box.
  21057.  
  21058.    3.  Tab to the Key Assignment text box and press the key to which you are
  21059.        assigning the macro. (For example, press ALT+T to assign the macro to
  21060.        ALT+T. The name of the keystroke appears in the text box.) If the
  21061.        keystroke (such as ENTER, TAB, or ESC) would normally exit the dialog
  21062.        box or move to the next field, type in the keystroke's name.
  21063.  
  21064.    4.  Click the OK button.
  21065.  
  21066.    5.  Choose Record On from the Edit menu to start the recording.
  21067.  
  21068.    6.  Type the text or perform the actions you want to record. (You can
  21069.        select text or fields with the mouse as well as the keyboard. Mouse
  21070.        selections are automatically converted into equivalent keystrokes.)
  21071.  
  21072.    7.  Choose Record On again to end the recording.
  21073.  
  21074.  
  21075.  You have now created a named macro available through the assigned keystroke.
  21076.  Pressing this key replays the actions you recorded.
  21077.  
  21078.  ────────────────────────────────────────────────────────────────────────────
  21079.  WARNING
  21080.  
  21081.  If you do not select a name for your macro, it is assigned the default name
  21082.  recordvalue. Unless you plan to discard the macro when exiting, do not let a
  21083.  recorded macro's name default to recordvalue. Any subsequent macro recorded
  21084.  with the  recordvalue default name will overwrite the first recordvalue
  21085.  macro.
  21086.  ────────────────────────────────────────────────────────────────────────────
  21087.  
  21088.  A recorded macro is temporary; PWB discards it when you exit. To save a
  21089.  recorded macro:
  21090.  
  21091.  
  21092.    1.  Choose Edit Macro from the Edit menu. This opens the <RECORD>
  21093.        pseudofile and displays the macros you recorded.
  21094.  
  21095.    2.  Make any changes required. For example, you might want to change the
  21096.        macro's name or modify the keystroke sequence.
  21097.  
  21098.    3.  Save the macro using the Save command from the File menu.
  21099.  
  21100.  
  21101.  The macros defined in the <RECORD> pseudofile are added to your TOOLS.INI
  21102.  file when you save the <RECORD> file. PWB automatically reloads them at the
  21103.  next session.
  21104.  
  21105.  You can append functions to an existing macro without having to record the
  21106.  original steps again:
  21107.  
  21108.  
  21109.    1.  Choose Set Record from the Edit menu. The Set Macro Record dialog box
  21110.        appears.
  21111.  
  21112.    2.  Type the macro's name in the Name text box.
  21113.  
  21114.    3.  Tab to the Clear First check box and cancel selection. This causes any
  21115.        new actions to be appended to the original macro, rather than
  21116.        replacing (clearing) it.
  21117.  
  21118.    4.  Click the OK button.
  21119.  
  21120.    5.  Choose Record On from the Edit menu to start the recording.
  21121.  
  21122.    6.  Perform the actions you want added to the macro.
  21123.  
  21124.    7.  Choose Record On again to end the recording.
  21125.  
  21126.  
  21127.  Remember to save the modified macro before exiting, or the new version will
  21128.  be discarded.
  21129.  
  21130.  You can record a series of actions without executing them.
  21131.  
  21132.  You can make a "silent" recording, which records a series of actions without
  21133.  executing them. This allows you to create a macro without altering or
  21134.  damaging the file. Start the recording with a meta record command (press F9,
  21135.  SHIFT+CTRL+R). When the macro is complete, terminate recording with record
  21136.  (press SHIFT+CTRL+R).
  21137.  
  21138.  PWB gives no visual feedback during silent recording. If you need to see the
  21139.  macro being created, open the <RECORD> pseudofile in a second window as
  21140.  described above. This is an excellent way to get a better understanding of
  21141.  macros and editor functions.
  21142.  
  21143.  
  21144.  14.3.6  Temporary Macros
  21145.  
  21146.  You can use the assign function to create a macro that lasts only until the
  21147.  end of the current session. For example, the following steps create the
  21148.  comment  macro described above:
  21149.  
  21150.  
  21151.    ■   Press ALT+A
  21152.  
  21153.    ■   Type  comment:=begline "; "
  21154.  
  21155.    ■   Press ALT+=
  21156.  
  21157.  
  21158.  This key sequence tells PWB to open dialog boxes where the macro and key
  21159.  assignments are to be typed. To assign ALT+C to the macro,
  21160.  
  21161.  
  21162.    ■   Press ALT+A
  21163.  
  21164.    ■   Type  comment:alt+c
  21165.  
  21166.    ■   Press ALT+=
  21167.  
  21168.  
  21169.  The macro is available immediately and is discarded when you exit PWB.
  21170.  
  21171.  
  21172.  14.4  Related Topics in Online Help
  21173.  
  21174.  Information on the following related topics can be found in online help. All
  21175.  the topics listed below are found by choosing "Programmer's WorkBench" from
  21176.  the "Microsoft Advisor's Help System Contents" screen.
  21177.  
  21178.  Topic                             Access
  21179.  ────────────────────────────────────────────────────────────────────────────
  21180.  Writing macros                    Choose "Writing and Using Macros"
  21181.  
  21182.  TOOLS.INI                         Choose "Using TOOLS.INI"
  21183.  
  21184.  Regular expressions               Choose "Writing and Using Macros;" then
  21185.                                    choose "Regular Expressions" from under
  21186.                                    the "Building Macros" subhead
  21187.  
  21188.  The prompt and meta functions     Choose "Using PWB Functions," and from
  21189.                                    the next screen, choose "Alphabetical
  21190.                                    List"
  21191.  
  21192.  Assigning keystrokes              Choose "Setting PWB Switches" and then
  21193.                                    "Assign Function"
  21194.  
  21195.  
  21196.  
  21197.  
  21198.  
  21199.  
  21200.  Chapter 15  Debugging Assembly-Language Programs with CodeView
  21201.  ────────────────────────────────────────────────────────────────────────────
  21202.  
  21203.  You can diagnose software problems and locate programming errors quickly
  21204.  with the CodeView debugger. This chapter explains how to
  21205.  
  21206.  
  21207.    ■   Display and modify variables and memory
  21208.  
  21209.    ■   Control the flow of execution
  21210.  
  21211.    ■   Use advanced CodeView debugging techniques
  21212.  
  21213.    ■   Modify CodeView's behavior with command-line switches and the
  21214.        TOOLS.INI file
  21215.  
  21216.  
  21217.  CodeView supports the Microsoft mouse (or any fully compatible pointing
  21218.  device). This chapter first describes CodeView operations with the mouse,
  21219.  then with function keys. Command-window commands are not generally
  21220.  discussed, except when there is no comparable mouse or function-key command.
  21221.  Unless a specific mouse button is named, "clicking" means pressing and
  21222.  quickly releasing the left mouse button.
  21223.  
  21224.  
  21225.  15.1  Understanding Windows in CodeView
  21226.  
  21227.  CodeView divides the screen into logically separate sections called windows.
  21228.  Windows permit a large amount of information to be displayed in an organized
  21229.  and easy-to-read fashion.
  21230.  
  21231.  Each window displays a different type of data.
  21232.  
  21233.  Each CodeView window has a distinct function and operates independently of
  21234.  the others. The name of each window described below appears in the top of
  21235.  the window's frame:
  21236.  
  21237.  
  21238.    ■   The Source window displays the source code. You can open a second
  21239.        source window to view an include file, another source file, or the
  21240.        same source file at a different location. Any ASCII text file can be
  21241.        viewed in the Source window.
  21242.  
  21243.    ■   The Command window accepts debugging commands from the keyboard.
  21244.  
  21245.    ■   The Watch window displays the current values of selected variables.
  21246.  
  21247.    ■   The Local window lists the values of all variables local to the
  21248.        current procedure.
  21249.  
  21250.    ■   The Memory window shows the contents of memory. You can open a second
  21251.        Memory window to view a different section of memory.
  21252.  
  21253.    ■   The Register window displays the contents of the microprocessor's
  21254.        registers, as well as the processor flags.
  21255.  
  21256.    ■   The 8087 window displays the registers of the coprocessor or its
  21257.        software emulator.
  21258.  
  21259.  
  21260.  Figure 15.1 shows all CodeView windows.
  21261.  
  21262.  (This figure may be found in the printed book.)
  21263.  
  21264.  The first time you run CodeView, it displays three windows. The Local window
  21265.  is at the top, the Source window fills the middle of the screen, and the
  21266.  Command window is at the bottom. CodeView records which windows were open
  21267.  and how they were positioned at the time you exit. These settings become the
  21268.  default the next time you run CodeView.
  21269.  
  21270.  There are two ways to open windows. You can choose the desired window from
  21271.  the View menu or press its shortcut key. In addition, some operations (such
  21272.  as selecting a Watch variable) automatically open the appropriate window if
  21273.  it isn't already open.
  21274.  
  21275.  All displays are updated automatically.
  21276.  
  21277.  CodeView continually and automatically updates the contents of all windows.
  21278.  However, if you want to interact with a particular window (such as entering
  21279.  a command, setting a breakpoint, or modifying a variable), you must first
  21280.  select that window.
  21281.  
  21282.  The selected window is called the "active" window. The active window is
  21283.  marked in three ways:
  21284.  
  21285.  
  21286.    ■   The window's name is highlighted.
  21287.  
  21288.    ■   The text cursor appears in the window.
  21289.  
  21290.    ■   The vertical and horizontal scroll bars move into the window.
  21291.  
  21292.  
  21293.  Figure 15.2 shows the Source window as the active window.
  21294.  
  21295.  (This figure may be found in the printed book.)
  21296.  
  21297.  To select a new active window, click that window (position the mouse pointer
  21298.  in the window and press the left mouse button). You can also press F6 or
  21299.  SHIFT+F6 to move from one window to the next.
  21300.  
  21301.  Windows often contain more information than can be displayed in the area
  21302.  allotted to the window. There are several ways to view these additional
  21303.  contents.
  21304.  
  21305.  To view additional contents with the mouse:
  21306.  
  21307.  
  21308.    ■   Drag the scroll box on the horizontal or vertical scroll bars.
  21309.        (Position the mouse pointer on the scroll box and, while holding down
  21310.        the left mouse button, move the mouse in the appropriate direction.)
  21311.  
  21312.    ■   Click the arrows at the top and bottom of the scroll bars.
  21313.  
  21314.    ■   Click the gray area to either side of the scroll box in a scroll bar.
  21315.  
  21316.  
  21317.  To view additional contents with the keyboard:
  21318.  
  21319.  
  21320.    ■   Press the direction keys (LEFT, RIGHT, UP, DOWN) to move the cursor.
  21321.  
  21322.    ■   Press PGUP, PGDN, CTRL+PGUP (page left), and CTRL+PGDN (page right) to
  21323.        move the cursor to a different page of the window's contents.
  21324.  
  21325.    ■   Press CTRL+HOME to move the cursor to the beginning of the window's
  21326.        contents.
  21327.  
  21328.    ■   Press CTRL+END to move the cursor to the end of the window's contents.
  21329.  
  21330.  
  21331.  Typing commands when the Source window is active causes CodeView to
  21332.  temporarily shift its focus to the Command window. Whatever you type is
  21333.  appended to the last line in the Command window. If the Command window is
  21334.  closed, CodeView beeps in response to your entry and ignores the input.
  21335.  
  21336.  
  21337.  Adjusting the Windows
  21338.  
  21339.  Although you can't reposition the windows, you can change their size or
  21340.  close them. The Maximize, Size, and Close commands from the View menu
  21341.  perform these functions, or you can press CTRL+F10, CTRL+F8, and CTRL+F4,
  21342.  respectively. Window manipulation is especially easy with a mouse:
  21343.  
  21344.  
  21345.    ■   To maximize a window (enlarge it so it fills the screen), click the up
  21346.        arrow at the right end of the window's top border, or double-click the
  21347.        window's title. (Position the mouse pointer anywhere on the title and
  21348.        press the left mouse button twice, rapidly.) To restore the window to
  21349.        its original size, click the double arrow at the right end of the top
  21350.        border or press CTRL+F10.
  21351.  
  21352.    ■   To change the size of a window, position the mouse pointer anywhere
  21353.        along the line at the top of the window. Press and hold down the left
  21354.        mouse button, then drag the mouse to enlarge or reduce the window. The
  21355.        same action on a vertical border widens or narrows the window.
  21356.  
  21357.    ■   To close a window, click the dot at the left end of the top border.
  21358.        The adjacent windows automatically expand to recover the unused space.
  21359.        You can also close any window whose View menu name has a dot next to
  21360.        it: choose that window from the menu or press the window's shortcut
  21361.        key.
  21362.  
  21363.  
  21364.  CodeView remembers the last debugging session.
  21365.  
  21366.  CodeView stores session information in a file called CURRENT.STS, which is
  21367.  created in the directory pointed to by the INIT environment variable (or in
  21368.  the current directory, if there is no INIT variable). The session
  21369.  information includes such items as the name of the program being debugged,
  21370.  the CodeView windows that were open, breakpoint locations, and other status.
  21371.  This information becomes the default status the next time you run CodeView.
  21372.  
  21373.  
  21374.  
  21375.  15.2  Overview of Debugging Techniques
  21376.  
  21377.  There is no single best approach to debugging. CodeView offers a variety of
  21378.  debugging tools that let you select a method appropriate for the program or
  21379.  for your work habits. This section describes some approaches to solving
  21380.  debugging problems.
  21381.  
  21382.  Broadly speaking, two things can go wrong in a program:
  21383.  
  21384.  
  21385.    ■   The program doesn't manipulate the data the way you expected it to.
  21386.  
  21387.    ■   The flow of execution is incorrect.
  21388.  
  21389.  
  21390.  These problems usually overlap. Incorrect execution can corrupt the data,
  21391.  and bad data can cause execution to take an unexpected turn. Because
  21392.  CodeView allows you to trace program execution while simultaneously
  21393.  displaying whatever combination of variables you want, you don't have to
  21394.  know ahead of time whether the problem is bad data manipulation, a bad
  21395.  execution path, or some combination of both.
  21396.  
  21397.  CodeView has specific features that deal with the problems of bad data and
  21398.  incorrect execution:
  21399.  
  21400.  
  21401.    ■   You can view and modify any program variable, any section of memory,
  21402.        or any processor register. These features are explained in Section
  21403.        15.3, "Viewing and Modifying Program Data."
  21404.  
  21405.    ■   You can monitor the path of execution and precisely control where
  21406.        execution pauses. These features are explained in Section 15.4,
  21407.        "Controlling Execution."
  21408.  
  21409.  
  21410.  
  21411.  15.3  Viewing and Modifying Program Data
  21412.  
  21413.  CodeView offers a variety of ways to display the values of program
  21414.  variables, processor registers, and memory. You can also modify the values
  21415.  of all these items as the program executes. This section shows how to
  21416.  display and modify variables, registers, and memory.
  21417.  
  21418.  
  21419.  15.3.1  Displaying Variables in the Watch Window
  21420.  
  21421.  To add a variable to the Watch window, position the cursor on the variable's
  21422.  name, using the mouse or the direction keys (LEFT, RIGHT, UP, DOWN). Then
  21423.  choose the Add Watch command from the Watch menu, or press CTRL+W.
  21424.  
  21425.  A dialog box appears with the selected variable's name displayed in the
  21426.  Expression field. If you don't want to watch the variable shown, type in the
  21427.  name of another variable. Click the OK button or press ENTER to add this
  21428.  variable to the Watch window.
  21429.  
  21430.  The Watch window appears at the top of the screen. Selecting a Watch
  21431.  variable automatically opens the Watch window if the window isn't already
  21432.  open.
  21433.  
  21434.  A newly added variable may be followed by the message:
  21435.  
  21436.    <Watch Expression Not in Context>
  21437.  
  21438.  This message appears when execution has not yet reached the procedure where
  21439.  a local variable is defined. Global variables (those declared outside
  21440.  procedures) never cause CodeView to display this message; they can be
  21441.  watched from anywhere in the program.
  21442.  
  21443.  To remove a variable from the Watch window, choose the Delete Watch command
  21444.  from the Watch menu or press CTRL+U. Then select the variable to be removed
  21445.  from the list in the dialog box. You can also position the cursor on any
  21446.  line in the Watch window and press CTRL+Y to delete that line.
  21447.  
  21448.  You can watch an unlimited number of variables.
  21449.  
  21450.  You can place as many variables as you like in the Watch window; the
  21451.  quantity is limited only by available memory. You can scroll the Watch
  21452.  window to position it at those variables you want to view. CodeView
  21453.  automatically updates all Watch window variables as the program runs,
  21454.  including those not currently visible within the Watch window frame.
  21455.  
  21456.  A variable can be specified by its address as well as its name. You can give
  21457.  its address in segment:offset form, where either component can be a register
  21458.  name or a number. You can extract a variable's address by prefixing the &
  21459.  operator to its name. Prefixing a variable's address (or any address) with
  21460.  the BY, WO, or DW operator displays the byte, word, or doubleword value
  21461.  starting at that address.
  21462.  
  21463.  There are several ways to display a variable's value.
  21464.  
  21465.  By default, CodeView displays variables as decimal values. You can select
  21466.  the radix by typing  n8,  n10, or  n16  in the Command window for an octal,
  21467.  decimal, or hexadecimal display. CodeView remembers the current radix when
  21468.  you exit; it becomes the default radix the next time you run CodeView.
  21469.  
  21470.  
  21471.  15.3.2  Displaying Expressions in the Watch Window
  21472.  
  21473.  The Watch window is not limited to variables. You can enter an expression
  21474.  (that is, any valid combination of variables, constants, and operators) for
  21475.  CodeView to evaluate and display. You can also select the format in which
  21476.  CodeView displays the expression.
  21477.  
  21478.  MASM expressions are evaluated using C rules.
  21479.  
  21480.  CodeView does not include an expression evaluator specifically for MASM. It
  21481.  uses the C expression evaluator instead. This means you must enter MASM
  21482.  variables or expressions in a form the C evaluator recognizes, which is not
  21483.  always the way they appear in a MASM program. (Online help describes the
  21484.  operators and precedence order for C expressions. The last part of this
  21485.  section also gives examples of some of the more commonly used expression
  21486.  forms.)
  21487.  
  21488.  The Language command from the Options menu offers a choice of Auto, C,
  21489.  Basic, or FORTRAN expression evaluators. However, the Basic and FORTRAN
  21490.  expression evaluators do not support address evaluation, pointer
  21491.  conversions, type casting, or other operations needed when debugging
  21492.  assembly-language code.
  21493.  
  21494.  Besides arithmetic and memory-reference expressions, CodeView can also
  21495.  display Boolean expressions. For example, if a variable is never supposed to
  21496.  be larger than 100 or less than 25, the expression
  21497.  
  21498.    (var < 25 || var > 100)
  21499.  
  21500.  evaluates to one (TRUE) if  var  goes out of bounds.
  21501.  
  21502.  
  21503.  Changing Display Format
  21504.  
  21505.  By default, CodeView displays expression values in decimal form. You can
  21506.  change the display radix to octal or hexadecimal with the Radix (N) command
  21507.  described at the end of the previous section.
  21508.  
  21509.  Another way to change the display format is to append a comma and a
  21510.  single-digit format specifier to any watched variable, expression, or
  21511.  address. For example, to display  varname  in octal form, type  varname,o
  21512.  in the Watch expression box. (If  varname  is already in the Watch window,
  21513.  simply append a comma and the octal specifier  ,o  and then move the cursor
  21514.  off the line.) The following list describes the use of each specifier:
  21515.  
  21516. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  21517.  Specifier                         Form Displayed
  21518.  ────────────────────────────────────────────────────────────────────────────
  21519.  c                                 Least-significant byte of the variable
  21520.                                    displayed as a single character
  21521.  
  21522.  d                                 Decimal value
  21523.  
  21524.  e or E                            Eight bytes displayed as a
  21525.                                    double-precision exponential
  21526.                                    number
  21527.  Specifier                         Form Displayed
  21528.  ────────────────────────────────────────────────────────────────────────────
  21529.                                   number
  21530.  
  21531.  f                                 Four bytes displayed as a
  21532.                                    single-precision floating-point
  21533.                                    number
  21534.  
  21535.  g or G                            Eight bytes displayed as a
  21536.                                    double-precision exponential
  21537.                                    number
  21538.  
  21539.  i                                 Signed integer value
  21540.  
  21541.  o                                 Unsigned octal value
  21542.  
  21543.  s                                 String; all following bytes displayed as
  21544.                                    ASCII characters, up to next null
  21545.                                    character (ASCII 0)
  21546.  
  21547.  u                                 Unsigned decimal value
  21548.  Specifier                         Form Displayed
  21549.  ────────────────────────────────────────────────────────────────────────────
  21550. u                                 Unsigned decimal value
  21551.  
  21552.  x or X                            Hexadecimal value, without leading  0x
  21553.  
  21554.  
  21555.  
  21556.  
  21557.  Displaying MASM Expressions
  21558.  
  21559.  Expressions using registers or indexes are more complex. The following
  21560.  sections show how to substitute CodeView expressions using the C expression
  21561.  evaluator for MASM expressions.
  21562.  
  21563.  Register Indirection - The C expression evaluator does not recognize
  21564.  brackets to indicate the memory location pointed to by a register. Instead,
  21565.  use the BY, WO, or DW operator to reference the corresponding byte, word, or
  21566.  doubleword value.
  21567.  
  21568.  MASM Expression              CodeView Equivalent
  21569.  ────────────────────────────────────────────────────────────────────────────
  21570.  BYTE PTR [bx]                BY bx
  21571.  WORD PTR [bp]                WO bp
  21572.  DWORD PTR [bp]               DW bp
  21573.  
  21574.  Register Indirection with Displacement - To perform based, indexed, or
  21575.  based-indexed indirection with a displacement, use the BY, WO, or DW
  21576.  operator combined with addition.
  21577.  
  21578.  MASM Expression                 CodeView Equivalent
  21579.  ────────────────────────────────────────────────────────────────────────────
  21580.  BYTE PTR [di+6]                 BY di+6
  21581.  BYTE PTR Test [bx]              BY &Test+bx
  21582.  WORD PTR [si] [bp+6]            WO si+bp+6
  21583.  DWORD PTR [bx] [si]             DW bx+si
  21584.  
  21585.  Address of a Variable - Use the address operator (&) instead of the OFFSET
  21586.  operator.
  21587.  
  21588.  MASM Expression              CodeView Equivalent
  21589.  ────────────────────────────────────────────────────────────────────────────
  21590.  OFFSET Var                   &Var
  21591.  
  21592.  PTR Operator - Use C type casts, or the BY, WO, and DW operators in
  21593.  conjunction with the address operator (&), to replace the PTR operator.
  21594.  
  21595.  MASM Expression                   CodeView Equivalents
  21596.  ────────────────────────────────────────────────────────────────────────────
  21597.  BYTE PTR Var                      BY &Var
  21598.                                    *(unsigned char*)&Var
  21599.  
  21600.  WORD PTR Var                      WO &Var
  21601.                                    *(unsigned *)&Var
  21602.  
  21603.  DWORD PTR Var                     DW &Var
  21604.                                    *(unsigned long*)&Var
  21605.  
  21606.  
  21607.  Strings - Add a comma and the string specifier  ,s  after the variable name.
  21608.  
  21609.  MASM Expression              CodeView Equivalent
  21610.  ────────────────────────────────────────────────────────────────────────────
  21611.  Stringvar                    Stringvar,s
  21612.  
  21613.  Because CodeView uses the C expression evaluator and C strings end with an
  21614.  ASCII null (zero), CodeView displays all characters up to the next null in
  21615.  memory when you request a string display. If you intend to debug a MASM
  21616.  program, you should terminate string variables with a null.
  21617.  
  21618.  Array and Structure Elements - The C expression evaluator equates an array
  21619.  name with the address of its first element. Therefore, you should prefix an
  21620.  array name with the address operator (&), then add the desired offset. The
  21621.  offset can be added directly, or it can appear within parentheses. It can be
  21622.  a number, a register name, or a variable.
  21623.  
  21624.  The following examples (using byte, word, and doubleword arrays) show how
  21625.  this is done:
  21626.  
  21627.  MASM Expression                   CodeView Equivalents
  21628.  ────────────────────────────────────────────────────────────────────────────
  21629.  String[12]                        BY &String+12
  21630.                                    *(&String+12)
  21631.  
  21632.  aWords[bx+di]                     WO &aWords+bx+di
  21633.                                    *(unsigned*)(&aWords+bx+di)
  21634.  
  21635.  aDWords[bx+4]                     DW &aDWords+bx+4
  21636.                                    *(unsigned long*)(&aDWords+bx+4)
  21637.  
  21638.  
  21639.  Pointers - MASM 6.0 lets you define pointer-type variables. Since these are
  21640.  the same as C pointers, the C expression evaluator works as it does with C
  21641.  programs.
  21642.  
  21643.  You dereference a pointer simply by typing its name in the Watch window. The
  21644.  pointer's address is displayed, followed by all the elements of the variable
  21645.  to which the pointer refers. Multiple levels of indirection (that is,
  21646.  pointers referencing other pointers) can be displayed simultaneously.
  21647.  
  21648.  
  21649.  15.3.3  Displaying Local Variables
  21650.  
  21651.  When your program is executing within the scope of a procedure, the Local
  21652.  window automatically displays the variables local to that procedure (stack
  21653.  variables). This includes arguments declared in PROC directives and
  21654.  variables explicitly declared as LOCAL within the procedure.
  21655.  
  21656.  Note that variables you create on the stack are not displayed in the Local
  21657.  window, since CodeView is aware only of the assembler-created stack. You can
  21658.  display user-defined stack variables in the Watch window by specifying their
  21659.  address in segment:offset form.
  21660.  
  21661.  
  21662.  15.3.4  Using Pointers to Display Arrays and Strings
  21663.  
  21664.  Unlike high-level-language compilers, MASM does not provide symbolic
  21665.  information for arrays. Consequently, CodeView cannot distinguish between a
  21666.  simple variable and an array, and therefore cannot directly display an
  21667.  assemblylanguage array in expanded form. (See Section 15.3.2, "Displaying
  21668.  Expressions in the Watch Window," to display individual array elements.)
  21669.  
  21670.  A user-defined pointer lets you view an expanded array.
  21671.  
  21672.  For debugging purposes, you can overcome MASM's lack of array information by
  21673.  using the TYPEDEF directive to define a pointer type, and from that a
  21674.  pointer variable for the array. (Place the directive and pointer definition
  21675.  within a conditional-assembly block, so the pointer won't be added to your
  21676.  release code.) You can then view the array from CodeView by placing the
  21677.  pointer in the Watch window. For example:
  21678.  
  21679.    array   BYTE    20 DUP (0)      ; array of 20 bytes
  21680.  
  21681.    IF debug
  21682.       PBYTE   TYPEDEF PTR BYTE     ; PBYTE type is pointer to bytes
  21683.       parray PBYTE array           ; parray points to array
  21684.    ENDIF
  21685.  
  21686.  If you declare multiple levels of pointers (pointers to pointers to
  21687.  pointers, and so on), multiple levels of indirection can be displayed
  21688.  simultaneously by expanding each subpointer.
  21689.  
  21690.  If it is inconvenient to view a character array in hexadecimal form, cast
  21691.  the variable's name to a character pointer by placing (char *) in front of
  21692.  the name. The character array is then displayed as a string delimited by
  21693.  apostrophes. You can also append the string-format specifier  ,s  to the
  21694.  expression.
  21695.  
  21696.  Note that the C expression evaluator expects a string to terminate with the
  21697.  ASCII null character (0). If you do not include a terminating null in the
  21698.  string's definition, the evaluator continues displaying memory as characters
  21699.  until it encounters a null. The Memory window is an effective way to view
  21700.  nonterminated strings.
  21701.  
  21702.  
  21703.  15.3.5  Displaying Structures
  21704.  
  21705.  MASM adds structure and union information to the debugging table. You can
  21706.  display MASM structures in expanded form, just as you would in C, Basic,
  21707.  Pascal, or FORTRAN.
  21708.  
  21709.  Structures contain multiple data values, often of different data types,
  21710.  arranged in one or more layers. Therefore, they are often referred to as
  21711.  "aggregate" data items. CodeView lets you control how much of a structure is
  21712.  shown; that is, whether all, part, or none of its components are displayed.
  21713.  
  21714.  
  21715.  The following example defines a structure and pointer types to implement a
  21716.  simple linked list:
  21717.  
  21718.    PTRLINKEDLIST TYPEDEF PTR LINKEDLIST
  21719.    PTRDATAWORD   TYPEDEF PTR WORD
  21720.  
  21721.    LINKEDLIST STRUCT
  21722.       ptrNext PTRLINKEDLIST 0
  21723.       ptrData PTRDATAWORD   0
  21724.    LINKEDLIST ENDS
  21725.  
  21726.    rootNode linkedList < >
  21727.  
  21728.  Once  rootNode  has been defined, the program calls the MALLOC function
  21729.  (which is available from the libraries of Microsoft high-level languages) to
  21730.  allocate memory for a structure pointer and a data pointer. The addresses of
  21731.  each are assigned to the corresponding pointers in  rootNode, readying the
  21732.  list for its first entry.
  21733.  
  21734.  The program stores a list item at the memory location specified by the
  21735.  preceding pointer, then calls MALLOC to allocate memory for the next list
  21736.  item. This process is repeated for each new list item, creating a linked
  21737.  list of data structures.
  21738.  
  21739.  To display the linked list of structures, add  rootNode  to the Watch
  21740.  window. It initially appears in the form:
  21741.  
  21742.    +rootnode = {...}
  21743.  
  21744.  The brackets indicate that this is an aggregate variable (since it's a
  21745.  structure). The plus sign (+) indicates that the structure has not yet been
  21746.  expanded to display its components.
  21747.  
  21748.  To expand  rootnode, double-click its display line. (Position the mouse
  21749.  pointer anywhere on the line and press the left mouse button twice,
  21750.  rapidly.) You can also move the cursor to the line and press ENTER. The
  21751.  Watch window display changes to
  21752.  
  21753.    -rootnode
  21754.       +ptrnext  = 0F00:1111
  21755.       ptrdata  = 0x0032  "2"
  21756.  
  21757.  The address and data values shown here are arbitrary. They depend on the
  21758.  data values stored and on the memory location from where MALLOC obtained
  21759.  free space. The minus sign (-) indicates that  rootnode  has been fully
  21760.  expanded; no further expansion is possible. The plus sign (+) indicates that
  21761.   ptrnext  points to another structure that has not been expanded.
  21762.  
  21763.  Any structure element can be independently expanded or contracted. To expand
  21764.  the next structure, double-click  ptrnext, or press ENTER when the cursor is
  21765.  on that line. The Watch window display changes to
  21766.  
  21767.    -rootnode
  21768.       -ptrnext  = 0F00:1111
  21769.          +ptrnext  = 0F00:2222
  21770.          ptrdata  = 0x0034  "4"
  21771.       ptrdata  = 0x0032  "2"
  21772.  
  21773.  Note that both the data value and its ASCII equivalent are displayed. To
  21774.  contract the structure, double-click its line a second time or position the
  21775.  cursor on the line and press ENTER.
  21776.  
  21777.  The process of expanding structures pointed to by  ptrnext  may be repeated
  21778.  indefinitely until you reach the last structure in the list. Its identifier
  21779.  will be prefixed with a minus sign, indicating that no more space for
  21780.  structures has been allocated.
  21781.  
  21782.  You can view individual elements instead of the entire structure.
  21783.  
  21784.  If you want to view only one or two elements of a large structure, indicate
  21785.  the specific structure elements in the Expression field of the Add Watch
  21786.  dialog box. Structure elements are separated by a dot (.), so you would type
  21787.  
  21788.  
  21789.    rootnode.ptrnext.ptrnext
  21790.  
  21791.  to view the pointer from the third structure in the list.
  21792.  
  21793.  
  21794.  15.3.6  Using Quick Watch
  21795.  
  21796.  Choose the Quick Watch command from the Watch menu (or press SHIFT+F9) to
  21797.  display the Quick Watch dialog box. If the cursor is in the Source, Local,
  21798.  or Watch window, the variable at the current cursor position appears in the
  21799.  dialog box. If it isn't the item you want to display, type in the desired
  21800.  expression or variable; then press ENTER. The Quick Watch window immediately
  21801.  displays the specified item.
  21802.  
  21803.  The Quick Watch display automatically expands structures and pointers to
  21804.  their first level. You can expand or contract an element just as you would
  21805.  in the Watch window: position the cursor on the appropriate line and press
  21806.  ENTER. If the array needs more lines than the Quick Watch window can
  21807.  display, drag the scroll box with the mouse, or press DOWN or PGDN to view
  21808.  the rest of the array.
  21809.  
  21810.  You can add Quick Watch variables to the Watch window.
  21811.  
  21812.  Choose the Add Watch button to add a Quick Watch item to the Watch window.
  21813.  Structures and pointers appear in the Watch window expanded as they were
  21814.  displayed in the Quick Watch dialog box.
  21815.  
  21816.  Quick Watch is a convenient way to take a quick look at a variable or
  21817.  expression. Since only one Quick Watch variable can be viewed at a time, you
  21818.  would not use Quick Watch for most of the variables you want to view.
  21819.  
  21820.  
  21821.  15.3.7  Displaying Memory
  21822.  
  21823.  Choosing the Memory command from the View menu opens a Memory window. Two
  21824.  Memory windows can be open at one time.
  21825.  
  21826.  By default, memory is displayed as hexadecimal byte values, with 16 bytes
  21827.  per line. At the end of each line is a second display of the same memory in
  21828.  ASCII form. Values that correspond to printable ASCII characters (decimal 32
  21829.  to 127) are displayed in that form. Values outside this range are shown as
  21830.  dots (.).
  21831.  
  21832.  You can display memory values in any form.
  21833.  
  21834.  Byte values are not always the most convenient way to view memory. If the
  21835.  area of memory you're examining contains character strings or floating-point
  21836.  values, you might prefer to view them in a directly readable form. Choosing
  21837.  the Memory Window command from the Options menu displays a dialog box with a
  21838.  variety of display options:
  21839.  
  21840.  
  21841.    ■   ASCII characters
  21842.  
  21843.    ■   Byte, word, or doubleword binary values
  21844.  
  21845.    ■   Signed or unsigned integer decimal values
  21846.  
  21847.    ■   Short (32-bit), long (64-bit), or ten-byte (80-bit) floating-point
  21848.        values
  21849.  
  21850.  
  21851.  Figures 15.3 and 15.4 show two of these different displays.
  21852.  
  21853.  (This figure may be found in the printed book.)
  21854.  
  21855.  (This figure may be found in the printed book.)
  21856.  
  21857.  Another way to choose a display format is to cycle through the formats by
  21858.  repeatedly pressing SHIFT+F3.
  21859.  
  21860.  Not every four-byte or eight-byte sequence represents a valid floating-point
  21861.  number. If a section of memory cannot be displayed in the floating-point
  21862.  format you select, the number displayed includes the characters NAN─"not a
  21863.  number."
  21864.  
  21865.  You can change the contents of the memory by simply overtyping new values in
  21866.  the Memory window. See Section 15.3.9 for more information on modifying
  21867.  values.
  21868.  
  21869.  
  21870.  Displaying Variables with a Live Expression
  21871.  
  21872.  Section 15.3.4 explained how to display a specific array element by adding
  21873.  the appropriate expression to the Watch window. You can also watch a
  21874.  particular array element or structure element in the Memory window. This
  21875.  CodeView display feature is called a "live expression." The term "live"
  21876.  means that CodeView dynamically displays memory starting at the current
  21877.  value of the address expression you specify.
  21878.  
  21879.  To create a live expression, choose the Memory Window command from the
  21880.  Options menu; then select the Live Expression check box. Type the element
  21881.  you want to view in the Address Expression field. For example, if  array  is
  21882.  a variable whose current value is being indexed by the value in the BI
  21883.  register and you wish to view it, type  array [bi]. Then choose the OK
  21884.  button or press ENTER.
  21885.  
  21886.  If no memory windows are open, a new Memory window opens. The first memory
  21887.  location in the window is the first memory location of the live expression.
  21888.  The section of memory displayed changes to the section the live expression
  21889.  currently references.
  21890.  
  21891.  You can use the Memory Window command from the Options menu to display the
  21892.  memory in a directly readable form. This is especially convenient when the
  21893.  live expression represents strings or floating-point values, which are
  21894.  difficult to interpret in hexadecimal form.
  21895.  
  21896.  It is usually more convenient to view an item in the Watch window than as a
  21897.  live expression. However, some items are more easily viewed as live
  21898.  expressions. For example, you can examine what is currently on top of the
  21899.  stack by entering SS:SP as the live expression. In fact, any legal
  21900.  combination of register values (such as ES:DI or DS:SI) can be entered in
  21901.  segment:offset form.
  21902.  
  21903.  
  21904.  15.3.8  Displaying the Processor Registers
  21905.  
  21906.  Choosing the Register command from the View menu (or pressing F2) opens a
  21907.  window on the right side of the screen. The microprocessor's current
  21908.  register values appear in this window. At the bottom of the window is a
  21909.  group of mnemonics representing the processor flags. Pressing F2 a second
  21910.  time closes the window.
  21911.  
  21912.  Video intensity shows changed values.
  21913.  
  21914.  When you first open the Register window, all register and flag values are
  21915.  shown in normal text. When you change a register or flag, the changed value
  21916.  is highlighted. For example, suppose the overflow flag is not set when the
  21917.  Register window is first opened. The corresponding mnemonic is NV and
  21918.  appears in light gray. If the overflow flag is subsequently set, the
  21919.  mnemonic changes to OV and appears in bright white. If your computer uses an
  21920.  80386/486 processor and you are running the real-mode version of CodeView
  21921.  choosing the 386 Instructions command from the Options menu displays the
  21922.  registers as 32-bit values. Choosing this command a second time returns to
  21923.  the 16-bit display.
  21924.  
  21925.  You can also display the registers of an 8087-80387 coprocessor (or the
  21926.  built-in coprocessor of the 80486) in a separate window by choosing the 8087
  21927.  command from the View menu. If your program uses the coprocessor emulator,
  21928.  the emulated registers are displayed instead.
  21929.  
  21930.  The Register values reveal program status.
  21931.  
  21932.  The Register window is a valuable debugging tool. Almost every assembly
  21933.  instruction alters a register or flag. As each line of code is executed, the
  21934.  register values and flags that change are highlighted, so you can see
  21935.  whether each instruction does what you intended it to.
  21936.  
  21937.  Also, when you execute an instruction whose operand has a memory location
  21938.  (such as a variable), the effective address of the operand, as well as the
  21939.  value stored at that address, is displayed at the bottom of the Register
  21940.  window.
  21941.  
  21942.  
  21943.  15.3.9  Modifying the Values of Variables, Memory, and Registers
  21944.  
  21945.  You can easily change the values of variables, memory locations, or
  21946.  registers displayed in the Watch, Local, Memory, Register, or 8087 windows.
  21947.  Simply position the cursor at the value you want to change and edit it to
  21948.  the appropriate value. In the Watch and Local windows, the change is
  21949.  accepted by CodeView when you move the cursor off the line. If you change
  21950.  your mind, press ALT+BKSP to undo the last change you made.
  21951.  
  21952.  You can also alter expressions in the Watch window by adding an operator or
  21953.  changing the variable displayed. When you have altered the expression and
  21954.  moved the cursor off the line, CodeView will immediately show the new value
  21955.  of the modified expression.
  21956.  
  21957.  The starting address of each line of memory displayed is shown at the left
  21958.  of the Memory window in segment:offset form. Altering the address
  21959.  automatically shifts the display to the corresponding section of memory.
  21960.  Under OS/2, if your program does not own that section of memory, memory
  21961.  values are displayed as double question marks (??).
  21962.  
  21963.  It's easy to change memory values...
  21964.  
  21965.  You can also change the values of memory locations by modifying the right
  21966.  side of the memory display (where memory values are shown in ASCII form).
  21967.  For example, to change a byte from decimal 75 to decimal 85, place the
  21968.  cursor over the letter K, which corresponds to the position where the memory
  21969.  value is 75 (K is ASCII 75), and type in U (ASCII 85).
  21970.  
  21971.  ...or flags.
  21972.  
  21973.  To toggle a processor flag, double-click its mnemonic. You can also position
  21974.  the cursor on a mnemonic, then press any key (except ENTER, TAB, or SPACE).
  21975.  Press ALT+BKSP (undo) to restore the flag to its previous setting.
  21976.  
  21977.  Be cautious when modifying memory or a register.
  21978.  
  21979.  The effect of changing a register, flag, or memory location can vary from no
  21980.  effect at all to crashing the operating system. Be cautious when altering
  21981.  these values.
  21982.  
  21983.  
  21984.  15.4  Controlling Execution
  21985.  
  21986.  There are two forms of program execution under CodeView:
  21987.  
  21988.  
  21989.    ■   Continuous; the program executes until either a previously specified
  21990.        breakpoint has been reached or the program terminates.
  21991.  
  21992.    ■   Single-step; the program pauses after each line of code has been
  21993.        executed.
  21994.  
  21995.  
  21996.  Sections 15.4.1 and 15.4.2 explain how each form of execution works and the
  21997.  most effective way to use each.
  21998.  
  21999.  As you are debugging, you can display the program in source-code form or
  22000.  assembly form. Section 15.4.3 explains the advantages of each.
  22001.  
  22002.  
  22003.  15.4.1  Continuous Execution
  22004.  
  22005.  Continuous execution lets you quickly execute the bug-free sections of code
  22006.  which would otherwise take a long time to execute one instruction at a time.
  22007.  
  22008.  
  22009.  The simplest form of continuous execution is to click the line of code you
  22010.  want to debug or examine in more detail with the right mouse button. The
  22011.  program executes up to the start of this line, then pauses. An alternative
  22012.  method is to position the cursor on this line, then press F7.
  22013.  
  22014.  You can also pause execution at a specific line of code with a "breakpoint."
  22015.  There are several types of breakpoints. Breakpoints are explained in the
  22016.  following section.
  22017.  
  22018.  
  22019.  Selecting Breakpoint Lines
  22020.  
  22021.  Breakpoints can be tied to lines of code.
  22022.  
  22023.  You can skip over those parts of the program that you don't want to examine
  22024.  by specifying one or more lines as breakpoints. The program executes up to
  22025.  the first breakpoint, then pauses. Pressing F5 continues program execution
  22026.  up to the next breakpoint, and so on. (You can halt execution at any time by
  22027.  pressing CTRL+C.)
  22028.  
  22029.  There is no limit to the number of breakpoints.
  22030.  
  22031.  You can set as many breakpoints as you like (limited only by available
  22032.  memory). There are several ways to set breakpoints:
  22033.  
  22034.  
  22035.    ■   Double-click anywhere on the desired breakpoint line. The selected
  22036.        line is highlighted to show that it is a breakpoint. To remove the
  22037.        breakpoint, double-click the line a second time.
  22038.  
  22039.    ■   Position the cursor anywhere on the line at which you want execution
  22040.        to pause. Press F9 to select the line as a breakpoint and highlight
  22041.        it. Press F9 a second time to remove the breakpoint and highlighting.
  22042.  
  22043.    ■   Display the Set Breakpoint dialog box by choosing Set Breakpoint from
  22044.        the Watch menu. Select one of the breakpoint options that permits a
  22045.        line ("location") to be specified. The line at the cursor is the
  22046.        default breakpoint line in the Location field. If this line is not the
  22047.        desired location, enter the line number desired. (You must place a
  22048.        period in front of the line number, or CodeView will interpret the
  22049.        number as an absolute address.) To remove the breakpoint, use F9 or
  22050.        choose Edit Breakpoints from the Watch menu to display the Edit
  22051.        Breakpoints dialog box.
  22052.  
  22053.  
  22054.  Not every line can be a breakpoint.
  22055.  
  22056.  A breakpoint line must be a program line that represents executable code.
  22057.  You cannot select a blank line, a comment, or a declaration (such as a
  22058.  variable declaration or a segment specifier) as a breakpoint.
  22059.  
  22060.  A breakpoint can also be set at an address. Type the address in
  22061.  segment:offset form in the Set Breakpoint dialog box. (Address breakpoints,
  22062.  unlike line breakpoints, are not saved in CodeView's status file, and
  22063.  therefore are not restored when you restart a debugging session.)
  22064.  
  22065.  A breakpoint can be set to the name of a procedure if the procedure was
  22066.  declared with the PROC directive. If not, the procedure must contain a
  22067.  labeled line. Type the procedure's name or the line's label in the Set
  22068.  Breakpoint dialog box.
  22069.  
  22070.  Once execution has paused, you can continue execution by clicking the F5=Go
  22071.  button in the display or by pressing F5. Execution continues to the next
  22072.  breakpoint. If there are no more breakpoints, execution continues to the end
  22073.  of the program, or until a fatal error occurs.
  22074.  
  22075.  ────────────────────────────────────────────────────────────────────────────
  22076.  NOTE
  22077.  
  22078.  The Set Breakpoint dialog box contains a Commands text box. You can type
  22079.  Command-window commands in this box, separated by semicolons. These commands
  22080.  are executed when the breakpoint is reached. See the Command Window section
  22081.  of CodeView online help for a full description of Command-window commands.
  22082.  ────────────────────────────────────────────────────────────────────────────
  22083.  
  22084.  
  22085.  Conditional Breakpoints
  22086.  
  22087.  Breakpoints are not limited to specific lines of code. CodeView can also
  22088.  pause when a variable reaches a particular value or just changes value. This
  22089.  is a "conditional breakpoint." In previous versions of CodeView, conditional
  22090.  breakpoints are called "watchpoints" and "tracepoints."
  22091.  
  22092.  You can associate a conditional breakpoint with a specific line of code, so
  22093.  that execution pauses at that line only if the variable has simultaneously
  22094.  reached a particular value or changed value. The check boxes in the Set
  22095.  Breakpoint dialog box select these other breakpoint types.
  22096.  
  22097.  To pause execution when a variable reaches a particular value, type an
  22098.  expression that is usually false in the Expression field of the Set
  22099.  Breakpoint dialog box. For example, if you want to pause when the variable
  22100.  looptest  equals 17, type  looptest == 17.
  22101.  
  22102.  To pause execution when a variable changes value, you need to type only the
  22103.  name of the variable in the Expression field. For large variables (such as
  22104.  arrays or character strings), you can specify the number of bytes you want
  22105.  checked (up to 32K) in the Length field. Execution pauses when any one of
  22106.  these values changes.
  22107.  
  22108.  ────────────────────────────────────────────────────────────────────────────
  22109.  NOTE
  22110.  
  22111.  CodeView checks every conditional breakpoint after executing each line of
  22112.  source code. Unless you have enabled the use of the debug registers with the
  22113.  CodeView /R command-line option, this computational overhead greatly slows
  22114.  execution. (Execution is even slower if you are executing in Mixed mode or
  22115.  Assembly mode, because conditional breakpoints are checked after each
  22116.  machine instruction.)
  22117.  
  22118.  For maximum speed when debugging, either associate conditional breakpoints
  22119.  with specific lines, or set conditional breakpoints only after you have
  22120.  reached the section of code that needs to be debugged. You can also use the
  22121.  Disable button in the Edit Breakpoints dialog box to temporarily suspend
  22122.  evaluation of a previously set conditional breakpoint.
  22123.  ────────────────────────────────────────────────────────────────────────────
  22124.  
  22125.  
  22126.  Using Breakpoints
  22127.  
  22128.  One of the most common bugs is a loop that executes too many or too few
  22129.  times. If you set a breakpoint on the statement that controls the loop
  22130.  statements, the program pauses after each iteration. With the loop variable
  22131.  or critical program variables in the Watch or Local windows, it should be
  22132.  easy to see what's going wrong in the loop.
  22133.  
  22134.  You can specify how many times a breakpoint is reached before stopping.
  22135.  
  22136.  You do not have to pause at a breakpoint the first time execution reaches
  22137.  it. CodeView lets you specify the number of times you want to ignore the
  22138.  breakpoint condition before pausing. Type the number in the Pass Count field
  22139.  of the Set Breakpoint dialog box. This feature can eliminate a lot of
  22140.  tedious singlestepping.
  22141.  
  22142.  Another programming error is erroneously assigning a value to a variable
  22143.  that should not change. Type the variable in the Expression field of the Set
  22144.  Breakpoint dialog box. Execution breaks whenever this variable changes─even
  22145.  unintentionally.
  22146.  
  22147.  You can assign new values to variables while execution is paused.
  22148.  
  22149.  Breakpoints are a convenient way to pause the program so you can assign new
  22150.  values to variables. For example, if a limit value is set by a variable, you
  22151.  can change the value to see whether program execution is affected.
  22152.  
  22153.  
  22154.  15.4.2  Single-Stepping
  22155.  
  22156.  In single-stepping, CodeView pauses after each line of code is executed. The
  22157.  next line to be executed is highlighted.
  22158.  
  22159.  There are two ways to single-step.
  22160.  
  22161.  You can single-step through a program with the Step and Trace commands. Step
  22162.  (executed by pressing F10) steps over procedure calls. All the code in the
  22163.  procedure is executed, but it appears to you as if the procedure executed in
  22164.  a single step. Trace (executed by pressing F8) traces through every step of
  22165.  all procedures. Each line of the procedure is executed as a separate step.
  22166.  
  22167.  You can alternate between Trace and Step as you like. The method you use
  22168.  depends only on whether you want to see what happens within a particular
  22169.  procedure. (Note that interrupt calls are always stepped over; you do not
  22170.  see individual steps of the execution.)
  22171.  
  22172.  If CodeView cannot locate the source code for a procedure in the current
  22173.  directory, it pauses and asks for the name of the file that contains the
  22174.  source. If you cannot supply a source file, CodeView disassembles the
  22175.  executable code and displays that instead. (If you are executing in Source
  22176.  mode, and the source code for a procedure is not available, CodeView steps
  22177.  over the procedure, even if you use the Trace command.)
  22178.  
  22179.  Note that breakpoints are active during both step and trace mode. If the
  22180.  procedure you step over contains a breakpoint, execution stops at the
  22181.  breakpoint.
  22182.  
  22183.  You can trace through the program continuously (without having to press F8
  22184.  at each step), using the Animate command from the Run menu. The speed of
  22185.  execution is controlled by the Trace Speed command from the Options menu.
  22186.  You can halt animated execution at any time by pressing any key.
  22187.  
  22188.  
  22189.  15.4.3  Changing the Program Display Mode
  22190.  
  22191.  The F3 function switches the display between Source mode, Mixed mode, and
  22192.  Assembly mode. You can also switch display modes by choosing the Source
  22193.  Window command from the Options menu and then selecting a display mode in
  22194.  the Source Window Options dialog box. (If the source-code text file cannot
  22195.  be located, CodeView automatically disassembles the executable file and
  22196.  displays it in assembly-language form.)
  22197.  
  22198.  The Source mode shows the program as you wrote it. The Mixed mode and
  22199.  Assembly mode each expand macros and code-generating directives (such as
  22200.  .STARTUP) into assembly-language instructions. You can execute these
  22201.  instructions one at a time (rather than as a single item), and verify that
  22202.  the assembler has created the correct instructions from the macro or the
  22203.  directive.
  22204.  
  22205.  Figures 15.5 and 15.6 show Mixed mode and Assembly mode, respectively, for
  22206.  the same code.
  22207.  
  22208.  (This figure may be found in the printed book.)
  22209.  
  22210.  (This figure may be found in the printed book.)
  22211.  
  22212.  
  22213.  15.5  Replaying a Debug Session
  22214.  
  22215.  CodeView can automatically create a "tape" (a disk file) with the debugging
  22216.  instructions and input data you entered when testing a program. The tape can
  22217.  then be "replayed" to repeat the debugging process. You initiate recording
  22218.  by choosing the History On command from the Run menu. Choosing History On a
  22219.  second time terminates recording. The recording is saved in the .CVH file in
  22220.  the current directory.
  22221.  
  22222.  Dynamic replay has several uses. The most obvious is repeating a debug
  22223.  session for the corrected version of a program. Dynamic replay usually works
  22224.  with slightly modified programs. However, the more you change the program,
  22225.  the less likely the new version will replay reliably.
  22226.  
  22227.  You can also use the recording as a bookmark. You can quit after a long
  22228.  debugging session, then pick up the session later in the same place.
  22229.  
  22230.  Dynamic replay makes it easy to correct a mistake.
  22231.  
  22232.  Most importantly, dynamic replay allows you to back up when you make an
  22233.  error or overshoot the section of code with the bug. This feature is
  22234.  important because not all bugs appear on the first path of execution you
  22235.  try.
  22236.  
  22237.  For example, you might have to manually execute a procedure many times
  22238.  before its bug appears. If you then enter a command that alters the
  22239.  machine's or program's status, thereby losing the information you need to
  22240.  find the cause of the bug, you would have to restart the program and
  22241.  manually repeat every debugging step to return to that point. Even worse, if
  22242.  you don't remember the exact sequence of events that exposed the bug, it
  22243.  could take hours to reproduce them.
  22244.  
  22245.  Dynamic replay of a recorded tape eliminates this problem. Choose the Undo
  22246.  command from the Run menu to automatically restart the program and
  22247.  continuously execute every command up to (but not including) the last one
  22248.  you entered. You can repeat this process as many times as you like until you
  22249.  return to the desired point in execution.
  22250.  
  22251.  You can add additional steps to an existing tape. Choose History On, then
  22252.  choose Replay. When replay has completed, perform whatever new debugging
  22253.  steps you want, then choose History On a second time to terminate recording.
  22254.  The new tape contains both the original and the added commands.
  22255.  
  22256.  ────────────────────────────────────────────────────────────────────────────
  22257.  NOTE
  22258.  
  22259.  CodeView records only those mouse commands that apply to CodeView. Mouse
  22260.  commands recognized by the application being debugged are not recorded.
  22261.  ────────────────────────────────────────────────────────────────────────────
  22262.  
  22263.  
  22264.  Replay Limitations under OS/2
  22265.  
  22266.  There are some limitations to dynamic replay when debugging under OS/2:
  22267.  
  22268.  
  22269.    ■   The program must not respond to asynchronous events. Replay under
  22270.        Presentation Manager is not currently supported because of this
  22271.        restriction.
  22272.  
  22273.    ■   Breakpoints must be specified at specific source lines or for specific
  22274.        symbols (rather than by absolute addresses), or replay may fail.
  22275.  
  22276.    ■   Single-thread programs behave normally during replay. However, one of
  22277.        the threads in a multithread program may cause an asynchronous event,
  22278.        violating the first restriction in this list. Multithread programs are
  22279.        therefore more likely to fail during replay.
  22280.  
  22281.    ■   Multiprocess replay will fail. Each new process invokes a new CodeView
  22282.        session. The existence of multiple sessions makes it impractical to
  22283.        record the sequence of events if you execute commands in a session
  22284.        other than the original session.
  22285.  
  22286.  
  22287.  
  22288.  15.6  Advanced CodeView Techniques
  22289.  
  22290.  Once you are comfortable displaying and changing variables, stepping through
  22291.  the program, and using dynamic replay, you might want to experiment with the
  22292.  advanced techniques explained below.
  22293.  
  22294.  
  22295.  Debugging OS/2 Programs
  22296.  
  22297.  You can debug protected-mode and bound programs under CodeView. See the
  22298.  Debug Multiple Processes and Debug Multiple Threads sections of CodeView
  22299.  online help for information about executing threads and multiple processes.
  22300.  
  22301.  
  22302.  
  22303.  Setting Command-Line Arguments
  22304.  
  22305.  If your program retrieves command-line arguments, you can specify them with
  22306.  the Set Runtime Arguments command from the Run menu. Type the arguments in
  22307.  the Command Line field before you begin execution. (Arguments entered after
  22308.  execution begins cause an automatic restart.)
  22309.  
  22310.  
  22311.  Opening Multiple Source Windows
  22312.  
  22313.  You can open two Source windows at the same time. The windows can display
  22314.  two different sections of the same program, or one window can show the
  22315.  calling program and the other a procedure file. You can move freely between
  22316.  the windows, executing lines of code as you like.
  22317.  
  22318.  
  22319.  Calling Procedures
  22320.  
  22321.  Any procedure in your program (whether user-written or from a library) can
  22322.  be called from the Command window or the Watch window. In the Command
  22323.  window, use the Display Expression command as follows:
  22324.  
  22325.    ?procname (arglist)
  22326.  
  22327.  The procedure procname is evaluated with the arglist arguments and the
  22328.  returned value is displayed in the Command window. (Note that CodeView
  22329.  cannot evaluate a function that returns an aggregate type.) In the Watch
  22330.  window, simply enter the procedure call. If the procedure does not return a
  22331.  value, the value displayed is the value of the AX register upon return from
  22332.  the procedure.
  22333.  
  22334.  You can evaluate any procedure, not just those called by your program. All
  22335.  object code specified to the linker is linked into the program. Any public
  22336.  functions in this code can be evaluated from the Command window.
  22337.  
  22338.  You can use this feature to call functions from within CodeView that you
  22339.  would not normally include in the final version of your program. For
  22340.  example, you could include the OS/2 API functions that control semaphores,
  22341.  then execute them from the Command window to manipulate the run-time
  22342.  environment at any point in the debugging process. (Remember that altering
  22343.  the environment during program execution may have unexpected side effects.)
  22344.  
  22345.  
  22346.  
  22347.  Executing Faster when Using Breakpoints
  22348.  
  22349.  Breakpoints can slow execution. You can increase CodeView's speed with the
  22350.  /R command-line option if you have an 80386/486-based computer and are
  22351.  running CodeView under DOS. This option enables the four debug registers,
  22352.  which support breakpoint-checking in hardware rather than in software. (The
  22353.  CodeView options are described in Section 15.7.)
  22354.  
  22355.  
  22356.  Printing Selected Items
  22357.  
  22358.  You can print all or part of the contents of any window with the Print
  22359.  command from the File menu. In the Print dialog box, a check box lets you
  22360.  print selected text from the window, the material currently displayed in the
  22361.  window, or the complete contents of the window. Select text by dragging the
  22362.  mouse across it, or by holding down the SHIFT key and pressing the direction
  22363.  keys (LEFT, RIGHT, UP, DOWN).
  22364.  
  22365.  By default, print output is to the file CODEVIEW.LST in the current
  22366.  directory. You can choose whether the new material is appended to an
  22367.  existing file or overwrites it, using the Append/Overwrite check box. If you
  22368.  want print output to go to a different file, type its name in the To File
  22369.  Name field. If you want the output to go to a printer, enter the appropriate
  22370.  device name such as LPT1 or COM2.
  22371.  
  22372.  
  22373.  Redirecting CodeView Input and Output
  22374.  
  22375.  The Command window accepts DOS-like commands that redirect input and output.
  22376.  These commands can also be included on the command line that invokes
  22377.  CodeView. Whatever items follow the /C option on the command line are
  22378.  treated as CodeView commands to be immediately executed at start-up.
  22379.  
  22380.    CV /c "<infile; t>outfile" myprog
  22381.  
  22382.  In the example above, input is redirected from  infile, which can contain
  22383.  start-up commands for CodeView. When CodeView exhausts all commands in the
  22384.  input file, focus automatically shifts to the Command window. Output is sent
  22385.  to  outfile  and echoed to the Command window. The  t  must precede the  >
  22386.  command for output to be sent to the Command window.
  22387.  
  22388.  Redirection is a useful way to automate CodeView start-up. It also lets you
  22389.  keep a viewable record of command-line input and output, a feature not
  22390.  available with dynamic replay. No record is kept of mouse operations. Some
  22391.  applications (particularly interactive ones) may need modification to allow
  22392.  for redirection of input to the application itself.
  22393.  
  22394.  
  22395.  Executing Faster with Additional Memory
  22396.  
  22397.  If you are running DOS and your computer uses expanded or extended memory,
  22398.  you can increase CodeView's execution speed by selecting the /X or /E
  22399.  option. CodeView moves as much as it can of itself and the symbolic CodeView
  22400.  information to higher memory (above the first megabyte).
  22401.  
  22402.  The /X option uses extended memory and gives the greatest speed increase.
  22403.  This option requires the HIMEM.SYS driver, which is included on your
  22404.  distribution disks. Add  DEVICE = HIMEM.SYS  to your CONFIG.SYS file to load
  22405.  HIMEM.SYS at boot time.
  22406.  
  22407.  The /E option uses expanded memory. The speed increase is not as great as
  22408.  that supplied by the /X option. The expanded memory manager (EMM) must be
  22409.  LIM 4.0, and no single module's debug information can exceed 48K. If the
  22410.  symbol table exceeds this limit, try reducing file-name information by not
  22411.  specifying full path names at compile time and by specifying CodeView
  22412.  information (/Zi) only with those program modules that need debugging.
  22413.  
  22414.  If you do not specify either /X or /E (or the /D disk-overlay option),
  22415.  CodeView automatically searches for the HIMEM.SYS driver and extended memory
  22416.  so it can implement the /X option. If it fails, CodeView searches for
  22417.  expanded memory to implement the /E option. If that search fails, CodeView
  22418.  uses a default disk overlay of 64K. (See the description of the /D option in
  22419.  the next section.)
  22420.  
  22421.  
  22422.  15.7  CodeView Command-Line Options
  22423.  
  22424.  The following options can be added to the command line that invokes
  22425.  CodeView. The Starting Up CodeView section of CodeView online help contains
  22426.  more information about these options.
  22427.  
  22428. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  22429.  Option                            Description
  22430.  Option                            Description
  22431.  ────────────────────────────────────────────────────────────────────────────
  22432.  /2                                Two-monitor debugging. The display
  22433.                                    adapters must be configured for
  22434.                                    different addresses, such as Hercules (R)
  22435.                                    and VGA. The application is displayed on
  22436.                                    the primary monitor (the monitor the
  22437.                                    operating system normally directs output
  22438.                                    to), while CodeView's output appears on
  22439.                                    the secondary monitor.
  22440.  
  22441.  /25                               Display in 25-line mode.
  22442.  
  22443.  /43                               Display in 43-line mode.
  22444.  
  22445.  /50                               Display in 50-line mode.
  22446.  
  22447.  /B                                Display in black and white. This assures
  22448.                                    that the display is readable when a
  22449.                                    color display is not used. You should
  22450.                                    also specify this option along with the
  22451.  Option                            Description
  22452.  ────────────────────────────────────────────────────────────────────────────
  22453.                                   also specify this option along with the
  22454.                                    /2 option when the secondary monitor is
  22455.                                    black and white.
  22456.  
  22457.  /Ccommands                        Execute commands immediately on start-up.
  22458.                                    The commands must be separated with a
  22459.                                    semicolon. If any commands require a
  22460.                                    space, enclose the entire list in double
  22461.                                    quotation marks.
  22462.  
  22463.  /D«buffersize»                    Use disk overlays to increase the size
  22464.                                    of the program that can be debugged,
  22465.                                    where buffersize is the decimal size of
  22466.                                    the overlay buffer, in kilobytes.
  22467.                                    Smaller buffers leave more room for the
  22468.                                    program being debugged, while larger
  22469.                                    buffers increase the speed of execution.
  22470.                                    The acceptable range is 16K to 128K. The
  22471.                                    default size is 64K. (DOS only.)
  22472.  Option                            Description
  22473.  ────────────────────────────────────────────────────────────────────────────
  22474.                                   default size is 64K. (DOS only.)
  22475.  
  22476.  
  22477.  /E                                Use expanded memory for symbolic
  22478.                                    information and CodeView overlays. (DOS
  22479.                                    only.)
  22480.  
  22481.  /F                                Flip screen video pages (rather than
  22482.                                    swap). When your application does not
  22483.                                    use graphics, eight video screen pages
  22484.                                    are available. Switching from CodeView
  22485.                                    to the output screen is accomplished by
  22486.                                    directly selecting the appropriate video
  22487.                                    page. Cannot be used with /S. (DOS only.)
  22488.  
  22489.  /G                                Suppress "snow" on a CGA display. (DOS
  22490.                                    only.)
  22491.  
  22492.  /I«0 | 1»                         Control trapping of nonmaskable
  22493.  Option                            Description
  22494.  ────────────────────────────────────────────────────────────────────────────
  22495. /I«0 | 1»                         Control trapping of nonmaskable
  22496.                                    interrupts and 8259 interrupts. A value
  22497.                                    of 0 forces interrupt trapping on
  22498.                                    machines CodeView doesn't recognize as
  22499.                                    IBM-
  22500.                                    compatible. A value of 1 (the default)
  22501.                                    disables interrupt trapping. (DOS only.)
  22502.  
  22503.  /K                                Disable keyboard monitors (under OS/2)
  22504.                                    and keyboard interrupts (under DOS).
  22505.                                    This allows you to regain control of the
  22506.                                    computer under deadlock conditions, but
  22507.                                    prevents CodeView from recording
  22508.                                    keyboard entries when recording a debug
  22509.                                    session.
  22510.  
  22511.  /Ldll                             Load symbolic information for the
  22512.                                    specified dynamic-link libraries (DLL).
  22513.                                    (OS/2 only.) This option is required
  22514.  Option                            Description
  22515.  ────────────────────────────────────────────────────────────────────────────
  22516.                                   (OS/2 only.) This option is required
  22517.                                    only for DLLs loaded with DOSLOADMODULE.
  22518.                                    CodeView automatically loads debug
  22519.                                    information for statically linked DLLs.
  22520.  
  22521.  /M                                Disable CodeView's use of the mouse.
  22522.                                    This simplifies debugging programs that
  22523.                                    accept mouse commands.
  22524.  
  22525.  /N«0 | 1»                         Identical to /I, but applies only to
  22526.                                    nonmaskable interrupts. (DOS only.)
  22527.  
  22528.  /O                                Debug child processes ("offspring").
  22529.                                    (OS/2 only.)
  22530.  
  22531.  /R                                Use 80386/486 hardware debug registers
  22532.                                    to speed execution. (DOS only.)
  22533.  
  22534.  
  22535.  Option                            Description
  22536.  ────────────────────────────────────────────────────────────────────────────
  22537. 
  22538.  /S                                Swap screen in buffers (rather than
  22539.                                    flip). When your program uses graphics,
  22540.                                    all eight video pages must be used.
  22541.                                    Switching from CodeView to the output
  22542.                                    screen is accomplished by saving the
  22543.                                    previous screen in a buffer. Cannot be
  22544.                                    used with /F. (DOS only.)
  22545.  
  22546.  /TSF                              Toggle (invert) the sense of the
  22547.                                    Statefileread switch in TOOLS.INI. If
  22548.                                    Statefileread is set to no (do not read
  22549.                                    the status file), the status file is
  22550.                                    read, and vice-versa.
  22551.  
  22552.  /X                                Use extended memory for CodeView and
  22553.                                    symbolic information. (DOS only.)
  22554.  
  22555.  
  22556.  
  22557.  
  22558.  15.8  Customizing CodeView with the TOOLS.INI File
  22559.  
  22560.  The TOOLS.INI file customizes the behavior and user interface of several
  22561.  Microsoft products. The TOOLS.INI file is a plain ASCII text file. You
  22562.  should place it in a directory pointed to the INIT environment variable. (If
  22563.  you do not use the INIT environment variable, CodeView looks for TOOLS.INI
  22564.  only in the CodeView source directory.)
  22565.  
  22566.  The CodeView section of TOOLS.INI is preceded by the following line:
  22567.  
  22568.    [cv]
  22569.  
  22570.  If you run the protected-mode version of CodeView, use [cvp] instead. If you
  22571.  run both versions, include both: [cv cvp]. You can have separate sections
  22572.  for  cv  and  cvp  if you want different customizations.
  22573.  
  22574.  Most of the TOOLS.INI customizations for CodeView control screen colors, but
  22575.  you can also specify such things as start-up commands or the default name of
  22576.  the file that receives CodeView output. See the Configure CodeView section
  22577.  of CodeView online help for full information about all TOOLS.INI switches
  22578.  that control CodeView.
  22579.  
  22580.  
  22581.  15.9  Related Topics in Online Help
  22582.  
  22583.  In addition to information covered in this chapter, information on the
  22584.  following topics can be found in online help.
  22585.  
  22586.  Topic                             Access
  22587.  ────────────────────────────────────────────────────────────────────────────
  22588.  CodeView information              Choose "CodeView Debuggers" from the
  22589.                                    "Microsoft Advisor Contents" screen
  22590.  
  22591.  ML command-line options           Choose "Macro Assembler" from the
  22592.                                    "Command Line" section of the "Microsoft
  22593.                                    Advisor Contents" screen
  22594.  
  22595.  
  22596.  
  22597.  
  22598.  
  22599.  
  22600.  
  22601.  
  22602.  
  22603.  Chapter 16  Converting C Header Files to MASM Include Files
  22604.  ────────────────────────────────────────────────────────────────────────────
  22605.  
  22606.  The H2INC utility translates C header files into MASM-compatible include
  22607.  files. C header files normally have the extension .H; MASM include files
  22608.  normally have the extension .INC. This is the origin of the program's name:
  22609.  "H to INC."
  22610.  
  22611.  H2INC simplifies porting data structures from your C programs to MASM
  22612.  programs. This is especially useful when you have
  22613.  
  22614.  
  22615.    ■   A program that mixes C code and MASM code with globally accessible
  22616.        data structures
  22617.  
  22618.    ■   A program prototyped in C that you're translating to MASM for
  22619.        compactness and fast execution
  22620.  
  22621.  
  22622.  The H2INC program translates data declarations, function prototypes, and
  22623.  type definitions. H2INC does not convert C code into MASM code. When H2INC
  22624.  encounters a C statement that would compile into executable code, H2INC
  22625.  ignores the statement and issues a warning message to the standard output.
  22626.  
  22627.  H2INC accepts C source code compatible with Microsoft C 6.0 and creates
  22628.  include files suitable for MASM 6.0. These include files will not work with
  22629.  versions of MASM prior to 6.0.
  22630.  
  22631.  H2INC is designed to translate project header files that you have written
  22632.  specifically for translation to MASM 6.0 include files. It is not designed
  22633.  to translate header files such as PM.H and WINDOWS.H.
  22634.  
  22635.  This chapter explains how H2INC performs the C code translation and how the
  22636.  command-line options control the conversions.
  22637.  
  22638.  
  22639.  16.1  Basic H2INC Operation
  22640.  
  22641.  H2INC is designed to provide automatic translation of C declarations that
  22642.  you need to include in the MASM portions of an application. However, the set
  22643.  of C statements processed by H2INC must be those needed by and interpretable
  22644.  by MASM. H2INC converts only function prototypes, some preprocessor
  22645.  directives,
  22646.  
  22647.  and C declarations outside the scope of procedures. For example, H2INC
  22648.  translates the C statement
  22649.  
  22650.    #define MAX_EMPLOYEES 400
  22651.  
  22652.  into this MASM statement:
  22653.  
  22654.    MAX_EMPLOYEES EQU 400t
  22655.  
  22656.  The t specifies the decimal radix.
  22657.  
  22658.  H2INC does not translate C code into MASM code. Statements such as the
  22659.  following are ignored:
  22660.  
  22661.    printf( "This is an executable statement.\n" );
  22662.  
  22663.  H2INC translates declarations, not executable code.
  22664.  
  22665.  By default, H2INC creates a single .INC file. If the C header file includes
  22666.  other header files, the statements from the original and nested files are
  22667.  translated and combined into one .INC file. This behavior can be changed
  22668.  with the /Ni option (see Section 16.2).
  22669.  
  22670.  The program also preprocesses some statements, just as the C preprocessor
  22671.  would. For example, given the following statements, if  VERSION  is not
  22672.  defined, H2INC ignores the #ifdef block.
  22673.  
  22674.    #ifdef VERSION
  22675.    #define BOX_VALUE 4
  22676.    #endif
  22677.  
  22678.  If  VERSION  is defined, H2INC translates the statements inside the block
  22679.  from C syntax to MASM syntax.
  22680.  
  22681.  H2INC normally discards comments. If you use the /C option, C comments are
  22682.  passed to the output file. If the line starts with a  /*  or  // , the
  22683.  comment specifier is converted to a semicolon (;). If the line is part of a
  22684.  multiline comment, a semicolon is prefixed to each line.
  22685.  
  22686.  H2INC ignores anything that is not a comment or that cannot be translated.
  22687.  These items do not appear in the output file. If H2INC encounters an error,
  22688.  it stops translating and deletes the resulting .INC file.
  22689.  
  22690.  
  22691.  16.2  H2INC Syntax and Options
  22692.  
  22693.  To run H2INC, type  H2INC  at the command-line prompt, followed by the
  22694.  options desired and the names of the .H files you want to convert:
  22695.  
  22696.    H2INC [[options]] file.H ...
  22697.  
  22698.  You can specify more than one file.H. File names are separated by a space.
  22699.  The contents of each file.H are translated into a single file in the current
  22700.  directory with the name file.INC. The original file.H is not altered.
  22701.  
  22702.  The following lists describe the available options. You can specify more
  22703.  than one option. Note that the options are case sensitive except for /HELP.
  22704.  
  22705.  
  22706.  H2INC recognizes /? to display a summary of H2INC syntax, and /HELP to
  22707.  invoke QuickHelp for H2INC. If QuickHelp is not available, H2INC displays a
  22708.  short list of H2INC options. This option is not case sensitive.
  22709.  
  22710.  H2INC recognizes but ignores C 6.0 options that aren't specified in the
  22711.  following two lists.
  22712.  
  22713.  
  22714.  Options Directly Affecting H2INC Output
  22715.  
  22716.  This first list describes the options that directly affect the H2INC output:
  22717.  
  22718.  
  22719.  Option                            Action
  22720.  ────────────────────────────────────────────────────────────────────────────
  22721.  /C                                Passes comments in the .H file to the
  22722.                                    .INC file.
  22723.  
  22724.  /Fa «filename»                    Specifies that the output file contain
  22725.                                    only equivalent MASM statements. This is
  22726.                                    the default. If specified, the filename
  22727.                                    overrides the default, keeping the base
  22728.                                    name of the C header files and adding
  22729.                                    the .INC extension.
  22730.  
  22731.  /Fc «filename»                    Specifies that the output file contain
  22732.                                    equivalent MASM statements plus original
  22733.                                    C statements converted to comment lines.
  22734.  
  22735.  /Mn                               Assumes the .MODEL directive is not
  22736.                                    specified for the MASM source or the
  22737.                                    generated .INC files. Instructs H2INC to
  22738.                                    declare explicitly the distances for all
  22739.                                    pointers and functions.
  22740.  
  22741.  /Ni                               Suppresses the expansion of nested
  22742.                                    include files.
  22743.  
  22744.  /Zu                               Makes all structure and union tag names
  22745.                                    unique.
  22746.  
  22747.  
  22748.  Options Indirectly Affecting H2INC Output
  22749.  
  22750.  This second list describes the options that indirectly affect the H2INC
  22751.  output:
  22752.  
  22753.  Option                            Action
  22754.  ────────────────────────────────────────────────────────────────────────────
  22755.  /AT                               Specifies tiny memory model (.COM).
  22756.  
  22757.  /AS                               Specifies small memory model, the
  22758.                                    default.
  22759.  
  22760.  /AC                               Specifies compact memory model.
  22761.  
  22762.  /AM                               Specifies medium memory model.
  22763.  
  22764.  /AL                               Specifies large memory model.
  22765.  
  22766.  /AH                               Specifies huge memory model.
  22767.  
  22768.  /D«const«=value» »                Defines a constant or macro.
  22769.  
  22770.  /G0                               Enables 8086/8088 instructions (default).
  22771.  
  22772.  /G1                               Enables 80186/80188 instructions.
  22773.  
  22774.  /G2                               Enables 80286 instructions.
  22775.  
  22776.  /G3                               Enables 80386 instructions. Changes the
  22777.                                    default word size to DWORD.
  22778.  
  22779.  /G4                               Enables 80486 instructions. Changes the
  22780.                                    default word size to DWORD.
  22781.  
  22782.  /Gc                               Specifies Pascal as the default calling
  22783.                                    convention.
  22784.  
  22785.  /Gd                               Specifies C as the default calling
  22786.                                    convention for functions (default).
  22787.  
  22788.  /Gr                               Specifies the _fastcall calling
  22789.                                    convention for functions. Generates a
  22790.                                    warning since H2INC does not translate
  22791.                                    _fastcall functions and prototypes.
  22792.  
  22793.  /Ht                               Enables generation of text equates. By
  22794.                                    default, text items are not translated.
  22795.  
  22796.  /Ipaths                           Searches named paths for include files
  22797.                                    before searching the paths in the
  22798.                                    INCLUDE environment variable. Paths are
  22799.                                    separated with a semicolon (;).
  22800.  
  22801.  /J                                Changes default character type from
  22802.                                    signed char to unsigned char.
  22803.  
  22804.  /nologo                           Suppresses display of the sign-on banner.
  22805.  
  22806.  Option                            Action
  22807.  ────────────────────────────────────────────────────────────────────────────
  22808.  /Tc «filename»                    Enables the processing of files whose
  22809.                                    name does not end in .H.
  22810.  
  22811.  /uident                           "Undefines" one of the predefined
  22812.                                    identifiers. (See Section 16.3.1.)
  22813.  
  22814.  /U                                "Undefines" all predefined identifiers.
  22815.                                    (See Section 16.3.1.)
  22816.  
  22817.  /w                                Suppresses compiler warning messages;
  22818.                                    same as /W0.
  22819.  
  22820.  /W0                               Suppresses all warning messages.
  22821.  
  22822.  /W1                               Displays level 1 warning messages
  22823.                                    (default).
  22824.  
  22825.  /W2                               Displays level 1 and level 2 warning
  22826.                                    messages.
  22827.  
  22828.  /W3                               Displays level 1, 2, and 3 warning
  22829.                                    messages.
  22830.  
  22831.  /W4                               Displays all warning messages.
  22832.  
  22833.  /X                                Excludes search for include files in the
  22834.                                    standard places.
  22835.  
  22836.  /Za                               Disables language extensions (allows
  22837.                                    ANSI standard only).
  22838.  
  22839.  /Zc                               Causes functions declared as _pascal to
  22840.                                    be case insensitive.
  22841.  
  22842.  /Ze                               Enables language extensions (default).
  22843.  
  22844.  /Zn string                        Adds string to all names generated by
  22845.                                    H2INC. Used to eliminate name conflicts
  22846.                                    with other H2INC-generated include files.
  22847.  
  22848.  /Zp{1 | 2 | 4}                    Packs structure on a 1-, 2-, or 4-byte
  22849.                                    boundary, following C packing rules.
  22850.                                    Default is /Zp2.
  22851.  
  22852.  
  22853.  16.3  Converting Data and Data Structures
  22854.  
  22855.  The primary use of H2INC is to convert data automatically from C format into
  22856.  MASM format. This section shows how H2INC converts constants, variables,
  22857.  pointers, and other C data structures to definitions recognizable to MASM.
  22858.  
  22859.  Since the names of the items translated by H2INC may be distinguished only
  22860.  by the case of the names, you should specify OPTION CASEMAP:NONE in any MASM
  22861.  files that include .INC files generated with H2INC.
  22862.  
  22863.  
  22864.  16.3.1  User-Defined and Predefined Constants
  22865.  
  22866.  H2INC translates constants from C to MASM format. For example, C symbolic
  22867.  constants of the form
  22868.  
  22869.    #define CORNERS 4
  22870.  
  22871.  are translated to MASM constants of the form
  22872.  
  22873.    CORNERS EQU 4t
  22874.  
  22875.  in cases where  CORNERS  is an integer constant or is preprocessed to an
  22876.  integer constant. See Section 1.2.4, "Integer Constants and Constant
  22877.  Expressions," for more information on integer constants in MASM.
  22878.  
  22879.  TEXTEQU is new to MASM 6.0.
  22880.  
  22881.  When the defined expression evaluates to a noninteger value, such as a
  22882.  floating-point number or a string, H2INC defines the expression with TEXTEQU
  22883.  and adds angle brackets to create text macros. By default, however, these
  22884.  TEXTEQU expressions are not added to the include file. Set the /Ht option to
  22885.  tell H2INC to generate TEXTEQU expressions.
  22886.  
  22887.    /* #define PI 3.1415 */
  22888.    PI TEXTEQU <3.1415>
  22889.  
  22890.  H2INC uses this form when the expression is anything other than a constant
  22891.  integer expression. H2INC does not check the constant or string for
  22892.  validity. For example, although the following C definitions are valid, H2INC
  22893.  creates invalid string equates without generating an error.
  22894.  
  22895.  These C statements
  22896.  
  22897.    #define INT 6
  22898.    #define FOREVER for(;;)
  22899.  
  22900.  generate these MASM statements:
  22901.  
  22902.    INT EQU 6t
  22903.    FOREVER TEXTEQU <for(;;)>
  22904.  
  22905.  The first #define statement is invalid because INT is a MASM instruction; in
  22906.  MASM 6.0, instructions are reserved and cannot be used as identifiers. The
  22907.  for loop definition is invalid because MASM cannot assemble C code.
  22908.  
  22909.  Predefined constants control the contents of .INC files.
  22910.  
  22911.  You can make use of the following predefined constants in your C code to
  22912.  conditionally generate the code in .INC files. The predefined constants and
  22913.  the conditions under which they are defined are
  22914.  
  22915.  Predefined Constant               When Defined
  22916.  ────────────────────────────────────────────────────────────────────────────
  22917.  _H2INC                            Always defined
  22918.  
  22919.  M_I86                             Always defined
  22920.  
  22921.  MSDOS                             Always defined
  22922.  
  22923.  _MSC_VER                          Defined as 600 for this release
  22924.  
  22925.  M_I8086                           Defined if /G0 is specified
  22926.  
  22927.  M_I286                            Defined if /G0 is not specified
  22928.  
  22929.  NO_EXT_KEYS                       Defined if /Za is specified
  22930.  
  22931.  _CHAR_UNSIGNED                    Defined if /J is specified
  22932.  
  22933.  M_I86SM                           Defined if /AS is specified
  22934.  
  22935.  M_I86MM                           Defined if /AM is specified
  22936.  
  22937.  M_I86CM                           Defined if /AC is specified
  22938.  
  22939.  M_I86LM                           Defined if /AL is specified
  22940.  
  22941.  M_I86HM                           Defined if /AH is specified
  22942.  
  22943.  For example, if your C header file includes definitions which are specific
  22944.  to the C portion of the program or otherwise are not appropriate for
  22945.  translation by H2INC, you can bracket the C-specific code with
  22946.  
  22947.    #ifndef _H2INC
  22948.         /* C-specific code */
  22949.    #endif
  22950.  
  22951.  In this case, only the C compiler processes the bracketed code.
  22952.  
  22953.  The /u and /U options affect these predefined constants. The /uarg option
  22954.  undefines the constant specified as the argument. The /U option disables the
  22955.  definition of all predefined constants. Neither /u or /U affects constants
  22956.  defined by the /D option.
  22957.  
  22958.  H2INC places an OPTION EXPR32 directive in the .INC file so that MASM
  22959.  correctly handles long integers within expressions. This means that the .INC
  22960.  files as well as all the .ASM files which include .INC files created with
  22961.  H2INC will resolve integer expressions in 32 bits instead of 16 bits.
  22962.  
  22963.  
  22964.  16.3.2  Variables
  22965.  
  22966.  H2INC translates variables from C to MASM format. For example, this C
  22967.  declaration
  22968.  
  22969.    int my_var;
  22970.  
  22971.  is translated into the MASM declaration
  22972.  
  22973.    EXTERNDEF my_var:SWORD
  22974.  
  22975.  H2INC converts C variable types to MASM types as follows:
  22976.  
  22977.  C Type                            MASM Type
  22978.  ────────────────────────────────────────────────────────────────────────────
  22979.  char                              BYTE or SBYTE (controlled by /J option)
  22980.  
  22981.  signed char                       SBYTE
  22982.  
  22983.  unsigned char                     BYTE
  22984.  
  22985.  short                             SWORD
  22986.  
  22987.  unsigned short                    WORD
  22988.  
  22989.  int                               SWORD (SDWORD with /G3 or /G4 option)
  22990.  
  22991.  unsigned int                      WORD (DWORD with /G3 or /G4 option)
  22992.  
  22993.  long                              SDWORD
  22994.  
  22995.  unsigned long                     DWORD
  22996.  
  22997.  float                             REAL4
  22998.  
  22999.  double                            REAL8
  23000.  
  23001.  long double                       REAL10
  23002.  
  23003.  H2INC assumes that a variable is external unless the variable is explicitly
  23004.  declared as static. For example, the C declaration
  23005.  
  23006.    long big_data;
  23007.  
  23008.  is converted to this MASM declaration:
  23009.  
  23010.    EXTERNDEF big_data:SDWORD
  23011.  
  23012.  See Sections 1.2.6, "Data Types," and 4.1.1, "Allocating Memory for Integer
  23013.  Variables," for more information on MASM data types, and Section 8.2.2,
  23014.  "Declaring Symbols Public and External," for information on EXTERNDEF.
  23015.  
  23016.  H2INC does not allocate space for arrays since all variables are assumed to
  23017.  be external. For example, the C declaration
  23018.  
  23019.    int two_d[10][20];
  23020.  
  23021.  translates to
  23022.  
  23023.    EXTERNDEF two_d:SWORD
  23024.  
  23025.  H2INC does not translate static variables, since the scope of these
  23026.  variables extends only to the file where they are declared.
  23027.  
  23028.  
  23029.  16.3.3  Pointers
  23030.  
  23031.  H2INC translates C pointer variables into their MASM equivalents. The C
  23032.  declarations
  23033.  
  23034.    int *ptr_var;
  23035.    char NEAR *pCh;
  23036.  
  23037.  are translated into these MASM statements:
  23038.  
  23039.    EXTERNDEF ptr_var:PTR SWORD
  23040.    EXTERNDEF pCh:NEAR PTR SBYTE
  23041.  
  23042.  If you set the /Mn option, H2INC specifies all distances explicitly (for
  23043.  example, NEAR PTR instead of PTR). If /Mn is not set, the distances are
  23044.  generated only when they differ from the default values implied by the
  23045.  memory model specified by the /A command-line option.
  23046.  
  23047.  H2INC converts _segment and _based variables to type WORD in MASM.
  23048.  
  23049.  See Sections 1.2.6, "Data Types," and 3.3, "Accessing Data with Pointers and
  23050.  Addresses," for information about MASM pointers.
  23051.  
  23052.  
  23053.  16.3.4  Structures and Unions
  23054.  
  23055.  H2INC translates C structures and unions into their MASM equivalents. H2INC
  23056.  modifies the C structure or union definition to account for differences from
  23057.  MASM structure and union definitions. This list describes these
  23058.  modifications.
  23059.  
  23060.  
  23061.    ■   C allows a structure or union variable to have the same name as the
  23062.        type name, but MASM does not. The H2INC /Zu option prevents the
  23063.        structure name from matching a variable or instance by prefixing every
  23064.        MASM structure name with  @tag_.
  23065.  
  23066.    ■   If a C structure or union definition does not have a name, H2INC
  23067.        supplies one for the MASM conversion. These generated structure names
  23068.        take the form  @tag_n, where n is an integer that starts at zero and
  23069.        is incremented for each structure name H2INC generates.
  23070.  
  23071.    ■   If the /Zn option is specified, H2INC inserts the given string between
  23072.        the underscore and the number in the generated structure names. This
  23073.        eliminates name conflicts with other H2INC-generated include files.
  23074.  
  23075.    ■   H2INC adds the alignment value to the converted structure definition.
  23076.  
  23077.  
  23078.  The following examples show how these rules are applied when converting
  23079.  structures. (Union conversions are not shown; they are handled identically.)
  23080.  These examples assume that the C header file defines an alignment value of
  23081.  2. (See Section 5.2.1, "Declaring Structure and Union Types," for
  23082.  information on alignment values.)
  23083.  
  23084.  The following named C structure definition
  23085.  
  23086.    struct file_info
  23087.    {
  23088.       unsigned char  file_addr;
  23089.       unsigned int   file_size;
  23090.    };
  23091.  
  23092.  is converted to the following MASM form. Except for explicitly specifying
  23093.  the alignment value, the conversion is direct:
  23094.  
  23095.    file_info          STRUCT 2t
  23096.    file_addr          BYTE          ?
  23097.    file_size          WORD          ?
  23098.    file_info          ENDS
  23099.  
  23100.  If the same C structure definition is converted using the /Zu option, the
  23101.  @tag_  prefix is added to the structure's name so that the name does not
  23102.  duplicate the name of a structure component:
  23103.  
  23104.    @tag_file_info     STRUCT 2t
  23105.    file_addr          BYTE          ?
  23106.    file_size          WORD          ?
  23107.    @tag_file_info     ENDS
  23108.  
  23109.  If the original C structure definition is modified to be an unnamed-type
  23110.  declaration of a specific instance (myfile)
  23111.  
  23112.    struct
  23113.    {
  23114.       unsigned char  file_addr;
  23115.       unsigned int   file_size;
  23116.    } myfile ;
  23117.  
  23118.  its MASM conversion looks like the following example. (The specific integer
  23119.  added to the  @tag_  prefix is determined by the sequence in which H2INC
  23120.  creates tag names.)
  23121.  
  23122.    @tag_7          STRUCT 2t
  23123.    file_addr       BYTE ?
  23124.    file_size       WORD ?
  23125.    @tag_7          ENDS
  23126.    EXTERNDEF       C myfile:@tag_7
  23127.  
  23128.  Nested structures may have as many levels as desired; they are not limited
  23129.  to one level. Nested structures are "unnested" (expanded) in the correct
  23130.  hierarchical sequence, as shown with the C structure and H2INC-generated
  23131.  code in this example.
  23132.  
  23133.    /* C code: */
  23134.    struct phone
  23135.    {
  23136.        int  areacode;
  23137.        long number;
  23138.    };
  23139.  
  23140.     struct person
  23141.    {
  23142.        char   name[30];
  23143.        char   sex;
  23144.        int    age;
  23145.        int    weight;
  23146.        struct phone;
  23147.    } Jim;
  23148.  
  23149.    ; H2INC generated code:
  23150.    phone           STRUCT 2t
  23151.    areacode        SWORD          ?
  23152.    number          SDWORD         ?
  23153.    phone           ENDS
  23154.  
  23155.    person          STRUCT 2t
  23156.    name            SBYTE          30t DUP (?)
  23157.    sex             SBYTE          ?
  23158.    age             SWORD          ?
  23159.    weight          SWORD          ?
  23160.    STRUCT
  23161.      areacode      SWORD          ?
  23162.      number        SDWORD         ?
  23163.    ENDS
  23164.    person          ENDS
  23165.  
  23166.    EXTERNDEF       C Jim:person
  23167.  
  23168.  See Section 5.2 for information on MASM structures and unions.
  23169.  
  23170.  
  23171.  16.3.5  Bit Fields
  23172.  
  23173.  H2INC translates C bit fields into MASM records. H2INC looks at a structure
  23174.  definition; if it consists only of bit fields of the same type and if the
  23175.  total size of the bit fields does not exceed the type of the bit fields,
  23176.  then H2INC outputs a RECORD definition with the name of the structure. All
  23177.  bit-field names are modified to include the structure name for uniqueness,
  23178.  since record fields have global scope in MASM.
  23179.  
  23180.  For example,
  23181.  
  23182.    struct s
  23183.    {
  23184.       int i:4;
  23185.       int j:4;
  23186.       int k:4;
  23187.    }
  23188.  
  23189.  becomes:
  23190.  
  23191.    s       RECORD  @tag_0:4,
  23192.                    k@s:4,
  23193.                    j@s:4,
  23194.                    i@s:4
  23195.  
  23196.  The  @tag  variable pads out the record to the type size of the bit fields
  23197.  so alignment of the structures will be correct.
  23198.  
  23199.  If the bit fields are too large, are not of the same type, or are mixed with
  23200.  fields that are not bit fields, H2INC generates a RECORD definition inside
  23201.  the structure and then uses the definition.
  23202.  
  23203.  For example,
  23204.  
  23205.    struct t
  23206.    {
  23207.        int i;
  23208.        unsigned char a:4;
  23209.        int j:9;
  23210.        int k:9;
  23211.        long l;
  23212.    }  m;
  23213.  
  23214.  becomes:
  23215.  
  23216.    t         STRUCT 2t
  23217.    i         SWORD       ?
  23218.    rec@t_0   RECORD      @tag_1:4,
  23219.              a@t:4
  23220.    @bit_0    rec@t_0     <>
  23221.    rec@t_1   RECORD      @tag_2:7,
  23222.              j@t:9
  23223.    @bit_1    rec@t_1     <>
  23224.    rec@t_2   RECORD      @tag_3:7,
  23225.              k@t:9
  23226.    @bit_2    rec@t_2     <>
  23227.    l         SDWORD      ?
  23228.    t         ENDS
  23229.  
  23230.    EXTERNDEF C m:t
  23231.  
  23232.  Notice that  j  and  k  are not packed because their total size exceeds the
  23233.  16 bits of an integer in C.
  23234.  
  23235.  Since the  @bit  field names are local to the structure, these begin with  0
  23236.   for each structure type; the  @rec  variables have global scope and so
  23237.  their number always increases.
  23238.  
  23239.  The C bit-field declaration
  23240.  
  23241.    struct SCREENMODE
  23242.    {
  23243.       unsigned int disp_mode : 4;
  23244.       unsigned int fg_color  : 3;
  23245.       unsigned int bg_color  : 3;
  23246.    };
  23247.  
  23248.  is converted into the following MASM record:
  23249.  
  23250.    SCREENMODE      RECORD          disp_mode@SCREENMODE:4,
  23251.                                    fg_color@SCREENMODE:3,
  23252.                                    bg_color@SCREENMODE:3
  23253.  
  23254.  See Section 5.3 for information about MASM records.
  23255.  
  23256.  
  23257.  16.3.6  Enumerations
  23258.  
  23259.  H2INC converts C enumeration declarations into MASM EQU definitions that are
  23260.  treated as standard integer constants. If the C declaration is not assigned
  23261.  a value, the H2INC generates an EQU statement that supplies a value
  23262.  equivalent to its position in the list. For example, the C enumeration
  23263.  declaration
  23264.  
  23265.    enum tagName
  23266.    {
  23267.       id1,
  23268.       id2,
  23269.       id3 = 42,
  23270.       id4
  23271.    };
  23272.  
  23273.  is converted into the following EQU statements:
  23274.  
  23275.    id1     EQU     0t
  23276.    id2     EQU     1t
  23277.    id3     EQU     42t
  23278.    id4     EQU     43t
  23279.  
  23280.  See Section 1.2.4 for information on MASM integer constants.
  23281.  
  23282.  
  23283.  16.3.7  Type Definitions
  23284.  
  23285.  All type definitions using C base types are translated directly. For
  23286.  example, H2INC converts the C type definitions
  23287.  
  23288.    typedef int INTEGER;
  23289.    typedef float FLOAT;
  23290.  
  23291.  to these MASM forms:
  23292.  
  23293.    INTEGER TYPEDEF SWORD
  23294.    FLOAT   TYPEDEF REAL4
  23295.  
  23296.  Pointer types are converted in a similar fashion. The following declarations
  23297.  
  23298.  
  23299.    typedef int *PINT
  23300.    typedef int **PINT
  23301.    typedef int far *PINT
  23302.  
  23303.  become (respectively)
  23304.  
  23305.    PINT TYPEDEF PTR SWORD
  23306.    PINT TYPEDEF PTR PTR SWORD
  23307.    PINT TYPEDEF FAR PTR SWORD
  23308.  
  23309.  Addressing mode determines pointer size.
  23310.  
  23311.  The number of bytes allocated for the pointer is set by the addressing mode
  23312.  you have selected unless if is specifically overridden in the type
  23313.  definition.
  23314.  
  23315.  C statements using typedef which convert to a type with the same name as the
  23316.  type do not generate errors, but are not converted. For example, H2INC does
  23317.  not convert
  23318.  
  23319.    typedef int SWORD
  23320.    typedef unsigned char BYTE
  23321.  
  23322.  since these typedef statements would generate these MASM statements:
  23323.  
  23324.    SWORD   TYPEDEF SWORD
  23325.    BYTE    TYPEDEF BYTE
  23326.  
  23327.  See Section 3.3, "Accessing Data with Pointers and Addresses," for
  23328.  information on using TYPEDEF in MASM 6.0.
  23329.  
  23330.  
  23331.  16.4  Converting Function Prototypes
  23332.  
  23333.  When H2INC converts C function prototypes into MASM function prototypes, the
  23334.  elements of the C syntax are converted into the corresponding elements of
  23335.  the MASM syntax.
  23336.  
  23337.  The syntax of a C function prototype is
  23338.  
  23339.    [[storage]] [[distance]]
  23340.    [[ret_type]] [[langtype]]
  23341.    label ( [[parmlist»  )
  23342.  
  23343.  In C syntax, storage can be STATIC or EXTERN. H2INC does not translate
  23344.  static function prototypes because static functions are visible only within
  23345.  the current source module, and standard include files do not contain
  23346.  executable code.
  23347.  
  23348.  Procedures for returning values depend on the langtype specified.
  23349.  
  23350.  In C, the ret_type is the data type of the return value. Because the MASM
  23351.  PROTO directive does not specify how to handle return values, H2INC does not
  23352.  translate the return type. However, H2INC checks the langtype specified in
  23353.  the C prototype to determine how particular languages return the
  23354.  value─through the stack or through registers.
  23355.  
  23356.  For the Pascal, FORTRAN, or Basic langtype specifications, H2INC appends an
  23357.  additional parameter to the argument list if the return type is longer than
  23358.  four bytes. This parameter is always a near pointer with the type of the
  23359.  return value. If the value of the return value type is not supported, this
  23360.  parameter is an untyped near pointer.
  23361.  
  23362.  For the _cdecl langtype specification in the C prototype, all returned data
  23363.  is passed in registers (AX or AX plus DX). There is no restriction on the
  23364.  return type. Additional parameters are not necessary.
  23365.  
  23366.  The langtype represents the naming and passing conventions for a language
  23367.  type. H2INC accepts the following C language types and converts them to
  23368.  their corresponding MASM language types:
  23369.  
  23370.  C Language Type                   MASM Language Type
  23371.  ────────────────────────────────────────────────────────────────────────────
  23372.  _cdecl                            C
  23373.  
  23374.  _fortran                          FORTRAN
  23375.  
  23376.  _pascal                           PASCAL
  23377.  
  23378.  _stdcall                          STDCALL
  23379.  
  23380.  _syscall                          SYSCALL
  23381.  
  23382.  H2INC explicitly includes the langtype in every function prototype. If no
  23383.  language type is specified in the .H file prototype, the default language is
  23384.  _cdecl (unless the default is overridden by the /Gc command-line option).
  23385.  
  23386.  In the MASM prototype syntax, the label is the name of the function or
  23387.  procedure.
  23388.  
  23389.  If you select the /Mn option, H2INC specifies the distance of the function
  23390.  (near or far), whether or not the C prototype specifies the distance. If /Mn
  23391.  is not set, H2INC specifies the distance only when it is different from the
  23392.  default distance specified by the memory model.
  23393.  
  23394.  If the C prototype's parameter list ends with a comma plus an ellipsis (,
  23395.  ...), the function can accept a variable number of arguments. H2INC converts
  23396.  this to the MASM form: a comma followed by the :VARARG keyword (, :VARARG)
  23397.  appended to the last parameter.
  23398.  
  23399.  H2INC does not translate _fastcall functions. Functions explicitly declared
  23400.  _fastcall (or invoking H2INC with the /Gr option) generate a warning
  23401.  indicating that the function declaration has been ignored.
  23402.  
  23403.  The following examples show how the preceding rules control the conversion
  23404.  of C prototypes to MASM prototypes (when the memory model default is small).
  23405.  The example function is  my_func. The TYPEDEF generated by H2INC for the
  23406.  PROTO is given along with the PROTO statement.
  23407.  
  23408.    /* C prototype */
  23409.                my_func (float fNum, unsigned int x);
  23410.    ; MASM TYPEDEF
  23411.                @proto_0 TYPEDEF PROTO C :REAL4, :WORD
  23412.    ; MASM prototype
  23413.                my_func  PROTO   @proto_0
  23414.  
  23415.    /* C prototype */
  23416.                extern my_func1 (char *argv[]);
  23417.    ; MASM TYPEDEF
  23418.                @proto_1  TYPEDEF  PROTO C :PTR PTR SBYTE
  23419.    ; MASM prototype
  23420.                my_func1  PROTO    @proto_1
  23421.  
  23422.    /* C prototype */
  23423.                struct vconfig _far * _far pascal my_func2 (int, scri
  23424.    );
  23425.    ; MASM TYPEDEF
  23426.                @proto_2  TYPEDEF  PROTO FAR PASCAL :SWORD, :scri
  23427.    ; MASM prototype
  23428.                my_func2  PROTO    @proto_2
  23429.  
  23430.    /* C prototype */
  23431.                long pascal my_func3 (double y, struct vconfig vc);
  23432.    ; MASM TYPEDEF
  23433.                @proto_3  TYPEDEF  PROTO PASCAL :REAL8, :vconfig
  23434.    ; MASM prototype
  23435.                my_func3    PROTO    @proto_3
  23436.  
  23437.    /* C prototype */
  23438.                void _far _cdecl myfunc4 ( char _huge *, short);
  23439.    ; MASM TYPEDEF
  23440.                @proto_4  TYPEDEF  PROTO FAR C :FAR PTR SBYTE, :SWORD
  23441.  
  23442.    ; MASM prototype
  23443.                myfunc4  PROTO  @proto_4
  23444.  
  23445.    /* C prototype */
  23446.                short my_func5 (void *);
  23447.    ; MASM TYPEDEF
  23448.                @proto_5  TYPEDEF  PROTO C :PTR
  23449.    ; MASM prototype
  23450.                my_func5  PROTO  @proto_5
  23451.  
  23452.    /* C prototype */
  23453.                char my_func6 (int, ...);
  23454.    ; MASM TYPEDEF
  23455.                @proto_6  TYPEDEF  PROTO C :SWORD, :VARARG
  23456.    ; MASM prototype
  23457.                my_func6  PROTO  @proto_6
  23458.  
  23459.    /* C prototype */
  23460.                typedef char * ptrchar;
  23461.                ptrchar _cdecl my_func7 (char *);
  23462.    ; MASM TYPEDEF
  23463.                @proto_7  TYPEDEF  PROTO C :PTR SBYTE
  23464.    ; MASM prototype
  23465.                my_func7  PROTO  @proto_7
  23466.  
  23467.  See Section 7.3.6, "Declaring Procedure Prototypes," for more information on
  23468.  prototypes and Chapter 20, "Mixed-Language Programming," for information on
  23469.  calling conventions and mixed-language programs.
  23470.  
  23471.  
  23472.  16.5  Related Topics in Online Help
  23473.  
  23474.  In addition to information covered in this chapter, information on the
  23475.  following topics can be found in online help.
  23476.  
  23477.  Topic                             Access
  23478.  ────────────────────────────────────────────────────────────────────────────
  23479.  INCLUDE Directive                 From the "MASM 6.0 Contents" screen,
  23480.                                    choose "Directives" and then
  23481.                                    "Miscellaneous"
  23482.  
  23483.  Include files                     From the "MASM 6.0 Contents" screen,
  23484.                                    choose "Example Code"; then choose
  23485.                                    "INCLUDE Files" to see a list of the
  23486.                                    include files provided with MASM 6.0
  23487.  
  23488.  MASM data types (constants,       From the "MASM 6.0 Contents" screen,
  23489.  variables, structures, unions,    choose "Directives"; then choose "Data
  23490.  real numbers, records)            Allocation" or "Complex Data Types"
  23491.  
  23492.  TYPEDEF                           From the "MASM 6.0 Contents" screen,
  23493.                                    choose "Directives" and then "Complex
  23494.                                    Data Types"
  23495.  
  23496.  Procedures and prototypes         From the "MASM 6.0 Contents" screen,
  23497.                                    choose "Directives"; then choose
  23498.                                    "Procedure and Code Labels"
  23499.  
  23500.  
  23501.  
  23502.  
  23503.  
  23504.  
  23505.  Chapter 17  Writing OS/2 Applications
  23506.  ────────────────────────────────────────────────────────────────────────────
  23507.  
  23508.  Microsoft Operating System/2 (OS/2) takes full advantage of 80286 and later
  23509.  processors. It supports memory far beyond the DOS 640K limit and offers a
  23510.  rich set of multitasking system calls. Although OS/2 is much more powerful
  23511.  than DOS, you may ultimately find it easier to program for OS/2.
  23512.  
  23513.  This chapter shows how to develop an OS/2 application and how to write
  23514.  dual-mode programs to run under both OS/2 and DOS.
  23515.  
  23516.  To write OS/2 applications, you must learn OS/2 system calls. While this
  23517.  chapter mentions a few of these calls, you should consult the references
  23518.  listed in the book's introduction to learn more about OS/2 system functions.
  23519.  
  23520.  
  23521.  OS/2 supports two modes─real mode, which emulates the DOS environment, and
  23522.  protected mode, which supports all the advanced features. For simplicity's
  23523.  sake, the rest of this chapter equates OS/2 with protected mode.
  23524.  
  23525.  ────────────────────────────────────────────────────────────────────────────
  23526.  NOTE
  23527.  
  23528.  Examples in this chapter support OS/2 1.x. Future versions of OS/2 may
  23529.  support different calling conventions.
  23530.  ────────────────────────────────────────────────────────────────────────────
  23531.  
  23532.  
  23533.  17.1  OS/2 Overview
  23534.  
  23535.  There are three steps in developing OS/2 or dual-mode applications:
  23536.  
  23537.  
  23538.    1.  Write the source code, using procedure calls rather than interrupts to
  23539.        call system functions.
  23540.  
  23541.    2.  Assemble and link the program with OS2.LIB.
  23542.  
  23543.    3.  Optionally, convert the program so that it can run under both OS/2 and
  23544.        DOS.
  23545.  
  23546.  
  23547.  This chapter explains each of these steps, first looking at specific
  23548.  differences in how you write DOS and OS/2 code. Then it illustrates the
  23549.  development of a simple OS/2 program. Finally, the chapter discusses
  23550.  register initialization and additional OS/2 utilities.
  23551.  
  23552.  
  23553.  17.2  Differences between DOS and OS/2
  23554.  
  23555.  Assembly language is assembly language. Most machine instructions you use in
  23556.  a DOS program are the same instructions you use in an OS/2 program. When you
  23557.  start making calls to the operating system, however, things change.
  23558.  
  23559.  You should understand the following differences between the two operating
  23560.  systems before attempting to write an OS/2 program.
  23561.  
  23562.  
  23563.  System Calls
  23564.  
  23565.  System calls control I/O and screen access.
  23566.  
  23567.  OS/2 is similar to DOS in that it offers a series of system calls that
  23568.  perform tasks such as opening or closing a disk file. The OS/2 system calls
  23569.  that handle keyboard input (KbdCharIn, for example) correspond to the
  23570.  interrupt 16h instructions in DOS. The OS/2 system calls for screen output
  23571.  (VioScrollDn, for example) correspond to DOS interrupt 10h calls. And the
  23572.  OS/2 disk and operating-system calls (DosGetDateTime, for example)
  23573.  correspond to DOS interrupt 21h calls.
  23574.  
  23575.  The effect is similar, but the way you actually make the calls is different.
  23576.  In DOS, you issue an interrupt. In OS/2, you make the system call with the
  23577.  INVOKE directive or the CALL instruction.
  23578.  
  23579.  
  23580.  New Instructions
  23581.  
  23582.  OS/2 is designed for advanced processors, and you may want to write programs
  23583.  that take advantage of the new instructions available on the 80286-80486. To
  23584.  use the new instructions and still target OS/2 1.x, place a .286 directive
  23585.  at the beginning of your source code.
  23586.  
  23587.  In general, you should avoid the directives that enable privileged
  23588.  instructions (.286P, .386P, and .486P), unless you are writing system-level
  23589.  code.
  23590.  
  23591.  Many OS/2 programs can be converted to run under DOS as well. To write
  23592.  programs to run on all DOS and OS/2 systems, use the default processor
  23593.  setting (.8086).
  23594.  
  23595.  
  23596.  The OS/2 Library
  23597.  
  23598.  MASM 6.0 provides OS2.INC and OS2.LIB.
  23599.  
  23600.  OS/2 programs must be linked to the system-call import library, OS2.LIB. The
  23601.  best way to perform this task is to use the INCLUDELIB directive, as shown
  23602.  in the example in the next section. In addition, you can include the OS2.INC
  23603.  file as an alternative to adding the prototypes for the OS/2 functions to
  23604.  your file.
  23605.  
  23606.  The OS2.LIB file makes system calls possible; it contains import definitions
  23607.  for all system calls. An import definition specifies the name of a procedure
  23608.  and the dynamic-link library (DLL) where the procedure resides. You can
  23609.  learn more about DLLs in Chapter 18, "Creating Dynamic-Link Libraries." To
  23610.  create an OS/2 application, however, you need to know only that OS2.LIB is
  23611.  required.
  23612.  
  23613.  
  23614.  Start-Up Code
  23615.  
  23616.  Unlike DOS, OS/2 automatically initializes all segment registers as required
  23617.  by the standard segment model. No special start-up sequence is required,
  23618.  although OS/2 places useful information in AX, BX, and CX (see Section 17.6,
  23619.  "Register and Memory Initialization") that you may want to save.
  23620.  
  23621.  
  23622.  Calling Conventions
  23623.  
  23624.  OS/2 1.x uses the Pascal calling convention.
  23625.  
  23626.  OS/2 system calls follow the Pascal calling and naming conventions. One way
  23627.  to enforce these conventions is to specify PASCAL in the .MODEL directive,
  23628.  then use the INVOKE directive to generate the correct code. Another is to
  23629.  include the OS2.INC file, which uses the PROTO directive to prototype the
  23630.  functions to follow the Pascal conventions. The prototypes specify Pascal as
  23631.  the calling convention. OS/2 functions return a value in AX. A nonzero value
  23632.  indicates an error. All registers except AX are preserved.
  23633.  
  23634.  The OS/2 2.x operating system uses different calling conventions. See the
  23635.  documentation provided with that product.
  23636.  
  23637.  
  23638.  Exit Code
  23639.  
  23640.  To exit an OS/2 program, call the OS/2 system function DosExit. If you use
  23641.  the .EXIT directive and the OS_OS2 attribute of the .MODEL statement, the
  23642.  assembler automatically generates the proper system call if you have a
  23643.  prototype for DosExit.
  23644.  
  23645.  
  23646.  Segment Restrictions
  23647.  
  23648.  Although OS/2 makes some operations easier, it does impose restrictions on
  23649.  the programmer. You cannot do segment arithmetic. That is, you cannot
  23650.  attempt to measure the distance between segments by subtracting one segment
  23651.  from another. In general, you also cannot add values to segment registers.
  23652.  Either operation may cause a protection violation, which would immediately
  23653.  terminate the program.
  23654.  
  23655.  Under OS/2, segment registers do not hold physical addresses; they hold
  23656.  "segment selectors." A segment selector is an index into the system's
  23657.  descriptor tables that hold the actual addresses. You can copy the segment
  23658.  selector or use it to access data, but you should not try to modify it.
  23659.  
  23660.  Huge pointer arithmetic is therefore different under OS/2. Under DOS, you
  23661.  can handle huge pointers easily by checking the OVERFLOW? flag after you
  23662.  increment or add to an offset address. If the result overflows (exceeds
  23663.  64K), then you increment the segment address. Under OS/2, manipulation of
  23664.  huge pointers requires special techniques. See your OS/2 documentation for
  23665.  more information.
  23666.  
  23667.  
  23668.  17.3  A Sample Program
  23669.  
  23670.  The following program prints  Hello, world. It runs under OS/2 protected
  23671.  mode.
  23672.  
  23673.    ; HELLO.ASM
  23674.    ;
  23675.                .MODEL  small, pascal, OS_OS2
  23676.                .286
  23677.  
  23678.                INCLUDELIB  os2.lib
  23679.                INCLUDE     os2.inc
  23680.  
  23681.                .STACK
  23682.                .DATA
  23683.    message     BYTE    "Hello, world.", 13, 10  ; Message to print
  23684.    bytecount   DWORD   ?                        ; Holds number of
  23685.                                                 ;  bytes written
  23686.                .CODE
  23687.  
  23688.                .STARTUP
  23689.                push        1                  ; Select standard output
  23690.                push        ds                 ; Pass address of message
  23691.                push        OFFSET message
  23692.                push        LENGTHOF message   ; Pass length of message
  23693.                push        ds                 ; Pass address of count
  23694.                push        OFFSET bytecount   ;  returned by function
  23695.                call        DosWrite           ; Call system write
  23696.                                               ;  function
  23697.                .EXIT       0                  ; Exit with 0 return code
  23698.                END
  23699.  
  23700.  .STARTUP and .EXIT automatically generate code.
  23701.  
  23702.  The .STARTUP and .EXIT directives are very useful because they automatically
  23703.  produce correct code for the operating-system type specified with the .MODEL
  23704.  directive (see Section 2.2, "Using Simplified Segment Directives"). As
  23705.  described in Section 17.6, OS/2 initializes all segment registers;
  23706.  therefore, .STARTUP does nothing but indicate the starting point. To
  23707.  correctly exit an OS/2 program, you must call the DosExit function. The
  23708.  DosExit prototype is always available to MASM programs.
  23709.  
  23710.  In the example above, .EXIT automatically generates the following code under
  23711.  OS/2:
  23712.  
  23713.    .EXIT     0
  23714.    0011  6A 01             *   push    +000000001h ; Action 1 ends
  23715.    all threads
  23716.    0013  6A 00             *   push    +000000000h ; Pass 0 return code
  23717.    0015  9A ---- 0000 E    *   call    DosExit     ; Call system function
  23718.                                         END
  23719.  
  23720.  Between .STARTUP and .EXIT, the entire program consists of a single call to
  23721.  the DosWrite function. The program pushes the parameters on the stack and
  23722.  then makes the call. No POP or ADD instructions are needed to restore the
  23723.  stack after DosWrite returns; DosWrite observes the Pascal calling
  23724.  convention and restores the stack itself before returning.
  23725.  
  23726.  The .MODEL statement helps ensure that the assembler produces correct code
  23727.  for calling DosWrite:
  23728.  
  23729.    .MODEL  small, pascal, OS_OS2
  23730.  
  23731.  When you run HELLO.EXE, OS/2 looks at the import definitions in the
  23732.  executable-file header and makes sure that all needed DLLs are in memory. It
  23733.  then loads any needed DLLs not already in memory.
  23734.  
  23735.  The assembler must be informed that DosWrite and DosExit are far and observe
  23736.  the Pascal calling convention. This information is in the prototype.
  23737.  
  23738.  In the call to DosWrite, note that although  OFFSET message  is an immediate
  23739.  operand, the program pushes it directly onto the stack. This operation is
  23740.  legal on 80186-80486 processors but not on the 8086 or 8088:
  23741.  
  23742.    push    OFFSET message
  23743.  
  23744.  The processors you want to target determine the instructions you should use.
  23745.  
  23746.  
  23747.  Since OS/2 programs can execute only on the 80286 or later processors, it is
  23748.  reasonable to use extended operations not supported by the 8086. However, if
  23749.  you want to write a program that can be converted to run under both OS/2 and
  23750.  DOS (as shown in Section 17.5), then you should write code that can run on
  23751.  the 8086. For example,
  23752.  
  23753.    mov ax, OFFSET msg
  23754.            push    ax
  23755.  
  23756.  The following revision of the sample program illustrates the usefulness of
  23757.  the INVOKE directive. This version does everything the previous example did
  23758.  with far fewer statements:
  23759.  
  23760.    ; HELLO.ASM
  23761.  
  23762.                .MODEL  small, pascal, OS_OS2
  23763.  
  23764.                INCLUDE     os2.inc
  23765.                INCLUDELIB  os2.lib
  23766.  
  23767.                .STACK
  23768.                .DATA
  23769.    message     BYTE   "Hello, world.", 13, 10  ; Message to print
  23770.    bytecount   DWORD   ?                       ; Holds number of
  23771.                                                ;  bytes written
  23772.                .CODE
  23773.                .STARTUP
  23774.  
  23775.    INVOKE  DosWrite,
  23776.                        1,
  23777.                        ADDR message,
  23778.                        LENGTHOF message,
  23779.                        ADDR bytecount
  23780.  
  23781.                .EXIT 0                   ; Exit with return code 0
  23782.                END
  23783.  
  23784.  The INVOKE directive generates a call to the given procedure after first
  23785.  pushing all other arguments on the stack. Like a call statement in a
  23786.  high-level language, the INVOKE directive handles types in a sophisticated
  23787.  way.
  23788.  
  23789.  
  23790.  17.4  Building an OS/2 Application
  23791.  
  23792.  The easiest way to assemble and link the program is from the Programmer's
  23793.  WorkBench (PWB). From the Options Menu, select Link Options and choose OS/2
  23794.  Application. When you select Build from the Make menu, PWB calls ML and
  23795.  LINK, passing the proper options.
  23796.  
  23797.  From the command line, type
  23798.  
  23799.    ML hello.asm
  23800.  
  23801.  The next section discusses how to "bind" the program─that is, convert it so
  23802.  that it runs under either DOS or OS/2.
  23803.  
  23804.  
  23805.  17.5  Binding OS/2 MASM Programs
  23806.  
  23807.  You can convert many OS/2 programs to run under both OS/2 and DOS 3.x. This
  23808.  conversion is called "binding" because it binds system calls to the API.LIB
  23809.  file provided with MASM 6.0. This file simulates OS/2 functions under DOS.
  23810.  The program must use a restricted set of system calls or it cannot be bound.
  23811.  
  23812.  
  23813.  OS/2 function calls are known collectively as the applications program
  23814.  interface (API). If you restrict your system calls to a subset of these
  23815.  functions known as the Family API, the program can be bound. See the
  23816.  Microsoft Operating System/2 Programmer's Reference for a list of the Family
  23817.  API functions.
  23818.  
  23819.  Online help also provides information on these utilities.
  23820.  
  23821.  If you use PWB, binding is easy. Select Bound Application from the LINK
  23822.  Options command in the Options menu. PWB does the rest, calling the BIND.EXE
  23823.  utility.
  23824.  
  23825.  If you want to bind the program to run under either OS/2 or DOS, use this
  23826.  command line:
  23827.  
  23828.    ML /Fb hello.asm
  23829.  
  23830.  You can use system calls outside the Family API provided that you never use
  23831.  them when running under DOS. The program can check the operating system and,
  23832.  if running under OS/2, can execute system calls that do not belong to the
  23833.  Family API. To follow this strategy, list OS/2-only calls with the BIND's /N
  23834.  option. It is the program's responsibility to make sure these calls are
  23835.  never made under DOS; otherwise, execution is terminated.
  23836.  
  23837.  
  23838.  17.6  Register and Memory Initialization
  23839.  
  23840.  When you execute an OS/2 program, OS/2 stores information about the program
  23841.  directly in registers. With DOS programs, the information is kept in a
  23842.  separate program segment prefix (PSP). The registers hold these values when
  23843.  an OS/2 program begins:
  23844.  
  23845. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  23846.  Register                          Contents at Program Start
  23847.  ────────────────────────────────────────────────────────────────────────────
  23848.  AX                                Segment address of program's environment
  23849.  
  23850.  BX                                Offset of command-line arguments within
  23851.                                    the
  23852.                                    environment
  23853.  
  23854.  CX                                Length of near data area (DGROUP)
  23855.  
  23856.  SP                                Offset of the top of the stack within
  23857.                                    the stack segment
  23858.  Register                          Contents at Program Start
  23859.  ────────────────────────────────────────────────────────────────────────────
  23860.                                   the stack segment
  23861.  
  23862.  CS:IP                             Program's entry point
  23863.  
  23864.  DS                                Segment address of near data area
  23865.                                    (DGROUP)
  23866.  
  23867.  SS                                Segment address of stack
  23868.  
  23869.  
  23870.  
  23871.  Note that OS/2 automatically initializes SS:SP correctly. If the .MODEL
  23872.  directive specifies FARSTACK, SS is initialized to its own segment address.
  23873.  If the model is NEARSTACK, OS/2 sets SS to DGROUP and SP to the top of the
  23874.  stack within DGROUP.
  23875.  
  23876.  You may want to save the AX, BX, and CX registers at startup.
  23877.  
  23878.  Upon start-up, AX, BX, and CX all contain information highly useful to some
  23879.  programs. If you want to access the program's command-line arguments or know
  23880.  the size of DGROUP, you must save the contents of these registers
  23881.  immediately:
  23882.  
  23883.    FPBYTE TYPEDEF FAR PTR BYTE
  23884.  
  23885.            .DATA
  23886.  
  23887.    args    FPBYTE  0
  23888.    cmds    FPBYTE  0
  23889.  
  23890.            .CODE
  23891.  
  23892.    mov WORD PTR args[0], ax ; Save segment of args
  23893.            mov WORD PTR args[2], 0  ; Offset is 0
  23894.            mov WORD PTR cmds[0], ax ; Save segment of cmds
  23895.            mov WORD PTR cmds[2], bx ; Save offset of cmds
  23896.  
  23897.  The AX register points to the segment value of the start of the program's
  23898.  environment. AX:BX points to the starting address of arguments within the
  23899.  environment, the first of which is the program name. This name is followed
  23900.  by a null (zero) byte and the command-line arguments exactly as typed at the
  23901.  command prompt. A second null marks the end of the arguments.
  23902.  
  23903.  If you use simplified segments, .DATA is equivalent to DGROUP.
  23904.  
  23905.  Under OS/2, the data segment register, DS, contains the segment of the near
  23906.  data area, DGROUP. If you use simplified segment directives, this is the
  23907.  .DATA segment. You must place one data segment in a group called DGROUP if
  23908.  you do not use the simplified directives:
  23909.  
  23910.    _DATA  SEGMENT WORD PUBLIC 'DATA'
  23911.           .
  23912.           .
  23913.           .
  23914.    _DATA  ENDS
  23915.  
  23916.    DGROUP GROUP _DATA
  23917.           ASSUME DS:DGROUP
  23918.  
  23919.  Calling the group anything other than DGROUP, or not having a DGROUP, causes
  23920.  an error. Only the memory required by the program is allocated by OS/2. This
  23921.  means that the system has space in reserve for later memory requests and for
  23922.  other programs.
  23923.  
  23924.  
  23925.  17.7  Other OS/2 Utilities
  23926.  
  23927.  In addition to LINK and BIND, MASM 6.0 provides other utilities useful for
  23928.  working with OS/2.
  23929.  
  23930.  
  23931.  EXEHDR
  23932.  
  23933.  The EXEHDR utility examines and can modify a DOS, Windows, or OS/2
  23934.  executable file header. In the case of OS/2 and Windows, EXEHDR reports a
  23935.  great deal more information: specifically, it displays the contents of
  23936.  segment tables and lists the attributes of the individual segments.
  23937.  
  23938.  
  23939.  IMPLIB
  23940.  
  23941.  The IMPLIB utility creates an import library that you can use when linking
  23942.  with a DLL or group of DLLs. Generally, there are three steps in using a
  23943.  DLL:
  23944.  
  23945.  
  23946.    1.  Copy the DLL to a directory listed in your CONFIG.SYS LIBPATH setting.
  23947.  
  23948.    2.  Run IMPLIB on the DLL to create an import library, or write a
  23949.        moduledefinition file.
  23950.  
  23951.    3.  Link the import library or module-definition file with any application
  23952.        that uses the DLL.
  23953.  
  23954.  
  23955.  An import library does not contain executable code but does contain the name
  23956.  and location of dynamic-link calls. These calls are resolved during run
  23957.  time.
  23958.  
  23959.  Chapter 18 goes into more detail about how to write DLLs.
  23960.  
  23961.  
  23962.  17.8  Module-Definition Files
  23963.  
  23964.  You can create a module-definition file for an application. A
  23965.  module-definition file is a text file that contains statements that give
  23966.  directions to the linker. These statements can alter the attributes of
  23967.  individual segments─for example, whether multiple instances of the program
  23968.  share data. Module-definition files are optional. If you use one, begin the
  23969.  file with the NAME statement. The following sample module-definition file
  23970.  specifies an application,  MYPROG, that shares the  CONSTDAT  segment:
  23971.  
  23972.    NAME MYPROG
  23973.  
  23974.    SEGMENTS CONSTDAT SHARED
  23975.  
  23976.  
  23977.  17.9  Related Topics in Online Help
  23978.  
  23979.  In addition to information covered in this chapter, information on the
  23980.  following topics can be found in online help:
  23981.  
  23982. ╓┌─────────────────────────────────┌─────────────────────────────────────────╖
  23983.  Topic                             Access
  23984.  Topic                             Access
  23985.  ────────────────────────────────────────────────────────────────────────────
  23986.  BIND                              See the "Microsoft Advisor Contents"
  23987.                                    screen
  23988.  
  23989.  OS/2 Include files                Choose from the "MASM 6.0 Contents"
  23990.                                    screen
  23991.  
  23992.  PROTO, INVOKE                     From the "MASM 6.0 Contents" screen,
  23993.                                    choose "Directives" and then "Procedure
  23994.                                    and Code Labels"
  23995.  
  23996.  INCLUDE, INCLUDELIB               From the "MASM 6.0  Contents" screen,
  23997.                                    select "Directives" and then
  23998.                                    "Miscellaneous Language Directives"
  23999.  
  24000.  EXEHDR                            From the "Microsoft Advisor Contents"
  24001.                                    screen, select "Miscellaneous" under
  24002.                                    "Microsoft Utilities"
  24003.  
  24004.  INCL_NOCOMMON                     Select "OS/2 Include Files" from the
  24005.  Topic                             Access
  24006.  ────────────────────────────────────────────────────────────────────────────
  24007. INCL_NOCOMMON                     Select "OS/2 Include Files" from the
  24008.                                    "MASM 6.0 Contents" screen; from the
  24009.                                    next screen, select "Category Summary"
  24010.  
  24011.  CALL                              From the "MASM 6.0 Contents" screen,
  24012.                                    choose "Processor Instruction" and then
  24013.                                    "Control Flow"
  24014.  
  24015.  SHOW.EXE                          From the "MASM 6.0 Contents" screen,
  24016.                                    choose "Example Code" and then "SHOW
  24017.                                    (Text Viewer)"
  24018.  
  24019.  
  24020.  
  24021.  
  24022.  
  24023.  
  24024.  
  24025.  
  24026.  Chapter 18  Creating Dynamic-Link Libraries
  24027.  ────────────────────────────────────────────────────────────────────────────
  24028.  
  24029.  A "dynamic-link library" (DLL) links to the main program at run time (hence
  24030.  the term dynamic link). The program that calls the DLL is known as the
  24031.  "client program." One DLL can supply services for several clients
  24032.  simultaneously.
  24033.  
  24034.  The client program can choose to load the DLL into memory at the same time
  24035.  the main program loads, or it can choose to load the DLL only when it is
  24036.  needed.
  24037.  
  24038.  DLLs are available only in OS/2 and Windows. In non-Windows DOS programs,
  24039.  all object modules are statically linked to the program at link time. This
  24040.  chapter discusses DLL programming for OS/2 1.x only.
  24041.  
  24042.  After an overview of DLLs, this chapter describes the following stages in
  24043.  developing a DLL:
  24044.  
  24045.  
  24046.    ■   Understanding general DLL programming considerations
  24047.  
  24048.    ■   Writing an interface to the DLL's exported procedures and data
  24049.  
  24050.    ■   Writing initialization and termination code
  24051.  
  24052.    ■   Building the DLL
  24053.  
  24054.  
  24055.  The last step requires use of a module-definition file and an import
  24056.  library.
  24057.  
  24058.  
  24059.  18.1  DLL Overview
  24060.  
  24061.  Like a standard (object-code) library, a DLL contains procedures that one or
  24062.  more programs can call. Yet unlike standard-library procedures, DLL
  24063.  procedures are never copied into an application's executable file. They
  24064.  reside only on disk in the DLL file.
  24065.  
  24066.  DLLs have several advantages:
  24067.  
  24068.  
  24069.    ■   Dynamic link libraries save significant space since the DLL's code and
  24070.        data exist in only one place, no matter how many different programs
  24071.        call the DLL. Applications that need a particular DLL can share it.
  24072.  
  24073.        In contrast, a standard library routine (the printf function in C, for
  24074.        example) becomes part of the executable code for each application that
  24075.        uses it. For example, if three different programs use the statically
  24076.        linked printf function, three copies of the printf code are on disk.
  24077.        Furthermore, if all three programs run at once, the printf code occurs
  24078.        three times in memory. If the same function were part of a DLL, it
  24079.        would exist in only one location on disk and in memory.
  24080.  
  24081.    ■   Dynamic linking makes applications and libraries more independent, and
  24082.        therefore they are easier to maintain. You can update a DLL without
  24083.        having to relink any of the programs that use it.
  24084.  
  24085.    ■   Applications link faster because the executable code for a dynamic
  24086.        link function is not copied into the application's .EXE file. Instead,
  24087.        only an import definition is copied.
  24088.  
  24089.  
  24090.  The purpose of a DLL is to supply ("export") procedures and data to client
  24091.  programs at run time. Items not exported are visible only within the DLL.
  24092.  
  24093.  Exported procedures are visible to the client program.
  24094.  
  24095.  The concept of exporting is analogous to the action of the PUBLIC directive,
  24096.  but goes further. A public item is available only to other source modules
  24097.  within the same program or DLL. An exported item is available to all
  24098.  programs running on the system. In addition to global procedures and data, a
  24099.  DLL can contain other procedures and data definitions to support the
  24100.  operations of exported procedures.
  24101.  
  24102.  Finally, a DLL can contain initialization and termination code to allocate
  24103.  and release resources needed by the procedures. Resources are typically
  24104.  files or dynamic memory. System services for OS/2 and Windows are provided
  24105.  through DLLs.
  24106.  
  24107.  
  24108.  18.2  DLL Programming Requirements
  24109.  
  24110.  Four programming requirements arise from the nature of DLLs. These
  24111.  requirements apply to all code used in a dynamic-link call─both in an
  24112.  exported procedure and in any procedure it may call:
  24113.  
  24114.  
  24115.    ■   You cannot assume that the SS and DS registers hold the same value,
  24116.        unless you explicitly set SS equal to DS.
  24117.  
  24118.    ■   You should avoid using the math coprocessor or emulator routines
  24119.        unless you are certain a coprocessor or emulator library is available.
  24120.  
  24121.    ■   The DLL should be "re-entrant," because there is no guarantee that
  24122.        only one program will use the DLL. A re-entrant procedure is one that
  24123.        can be called by different programs concurrently. This creates
  24124.        problems for static data in the DLL, unless you declare data to be
  24125.        NONSHARED in the module-definitions file.
  24126.  
  24127.    ■   Be careful how you place data and code in segments. The location of
  24128.        data and code in different segments and the contents of the
  24129.        module-definition file also determine the content of the executable
  24130.        file.
  24131.  
  24132.  
  24133.  This section discusses these requirements.
  24134.  
  24135.  
  24136.  18.2.1  Separate Stack and Data Requirement
  24137.  
  24138.  The separate stack and data requirement involves both assembler assumptions
  24139.  and coding techniques. If you used the FARSTACK keyword as described in
  24140.  Section 18.3.1, "Choosing Module Attributes," the assembler makes correct
  24141.  assumptions about the contents of DS and SS.
  24142.  
  24143.  Do not assume that SS equals DS.
  24144.  
  24145.  In your own code, avoid any optimizing techniques that use SS to access
  24146.  items in the data segment or DS to access stack data. For example, the
  24147.  following code uses the ASSUME statement to be sure the correct stack is
  24148.  accessed:
  24149.  
  24150.    ASSUME  DS:DGROUP
  24151.            .
  24152.            .
  24153.            .
  24154.            push    ds
  24155.            lds     si, sourcead  ; Load DS for string ops
  24156.    ASSUME  DS:NOTHING
  24157.            .
  24158.            .
  24159.            .
  24160.    ASSUME  SS:STACK
  24161.            mov     bx, ss:thing  ; Access near data thing through SS
  24162.    ASSUME  SS:NOTHING
  24163.  
  24164.  Thread-specific variables can be stored on the stack, as shown in the
  24165.  example above.
  24166.  
  24167.  
  24168.  18.2.2  Floating-Point Math Requirement
  24169.  
  24170.  Don't assume the math coprocessor is available to the DLL.
  24171.  
  24172.  A stand-alone DLL─that is, a DLL created for general use by many programs─
  24173.  can make few assumptions about the calling program. Therefore, the safest
  24174.  way to perform floating-point calculations is to use alternate math
  24175.  routines. If you link to a Microsoft high-level language, you can access
  24176.  these routines through a language library. These routines give the fastest
  24177.  results possible without a coprocessor. See Section 6.3, "Using Emulator
  24178.  Libraries," for more information.
  24179.  
  24180.  Floating-point operations in DLLs can use a coprocessor or emulator routines
  24181.  if you are certain that a coprocessor or emulator libraries are available.
  24182.  
  24183.  
  24184.  18.2.3  Re-entrance Requirement
  24185.  
  24186.  A procedure may be called by any number of different programs concurrently.
  24187.  That is, program A may call a DLL procedure while program B is still
  24188.  executing the same procedure. The basic problem of re-entrance is how data
  24189.  is shared.
  24190.  
  24191.  Be aware that re-entering the DLL can modify its data.
  24192.  
  24193.  For example, suppose you have a DLL that contains an accounting package; one
  24194.  of the functions adds up an employee's salary for a whole year. First it
  24195.  initializes the total to zero; then it increments this total one week at a
  24196.  time. While program A is in the middle of this function, program B could
  24197.  enter the procedure; its first action would be to initialize the total to
  24198.  zero. Control could then pass back to program A, which would then have zero
  24199.  total for salary. The problem is that two instances of the DLL share the
  24200.  same variable for totals.
  24201.  
  24202.  A procedure in a DLL must therefore follow this rule: it can access static
  24203.  data items but must not alter them. Otherwise, one instance of a procedure
  24204.  could corrupt data relied on by another instance of the procedure.
  24205.  
  24206.  There are several exceptions to this rule. First, if data is declared
  24207.  NONSHARED in the module-definitions file, each instance has its own copy of
  24208.  the data segment, and there is no conflict. Second, you can use semaphores
  24209.  to allow mutually exclusive access to data items. Finally, there may be some
  24210.  items you deliberately want all instances to alter─such as a global counter
  24211.  to keep track of number of instances.
  24212.  
  24213.  Section 18.4.1, "Writing the Module-Definition File," explains how to
  24214.  declare some data items as SHARED while declaring others to be NONSHARED.
  24215.  
  24216.  
  24217.  18.2.4  Segment Strategy in a DLL
  24218.  
  24219.  Be careful how you place different kinds of data and code in different
  24220.  segments. When loading the DLL, OS/2 checks to see if the DLL is already in
  24221.  memory. If so, it loads only new copies of NONSHARED segments; it does not
  24222.  reload SHARED segments. Code segments are always SHARED.
  24223.  
  24224.  Control of DLL data and code works at the segment level. The DATA statement
  24225.  assigns default attributes for all data segments in the DLL, but the
  24226.  moduledefinition SEGMENTS statement overrides these attributes for any given
  24227.  segment.
  24228.  
  24229.  You may want to create a DLL that has some data shared between all programs
  24230.  that call the DLL and some data that is private to each instance. The
  24231.  following module-definition statement specifies that all data in  GLOBDAT
  24232.  is shared and all data in  PRIVDAT  is not:
  24233.  
  24234.    SEGMENTS
  24235.        GLOBDAT SHARED 'data'
  24236.        PRIVDAT NONSHARED 'data'
  24237.  
  24238.  The segments have class `code' unless you specifically define the class as
  24239.  shown in this example. See Section 18.4.1 for more information on
  24240.  module-definition files.
  24241.  
  24242.  
  24243.  18.3  Writing the DLL Code
  24244.  
  24245.  When you write the code for the DLL module, you need to select the correct
  24246.  module attributes, define the procedures and data in your DLL, and write the
  24247.  initialization and termination code. This section discusses these tasks.
  24248.  
  24249.  
  24250.  18.3.1  Choosing Module Attributes
  24251.  
  24252.  As noted in Chapter 2, there are four fields for the .MODEL directive:
  24253.  memory model, language type, operating system, and stack type. When you
  24254.  write a DLL, you can choose the attributes you would normally use for the
  24255.  first two fields. OS/2 system calls use the Pascal calling convention, so
  24256.  you may find it convenient to make all your modules use this convention as
  24257.  well.
  24258.  
  24259.  DLLs use the OS_OS2 and FARSTACK attributes.
  24260.  
  24261.  The operating system and stack fields should be OS_OS2 and FARSTACK,
  24262.  respectively. You should use the NEARSTACK attribute only if you switch
  24263.  execution to your own stack.
  24264.  
  24265.  A usable declaration is therefore
  24266.  
  24267.    .MODEL  large, pascal, os_os2, farstack
  24268.  
  24269.  If you are using full segment definitions, remember to generate an ASSUME
  24270.  directive for DS but not for SS.
  24271.  
  24272.    ASSUME  DS:DGROUP ; Necessary with full segment definitions
  24273.  
  24274.  
  24275.  18.3.2  Defining Procedures and Data
  24276.  
  24277.  Procedures and data in DLLs can be either global (available to the client
  24278.  process) or local (used only by the DLL). To create a global data item, make
  24279.  sure that it is public:
  24280.  
  24281.    EXTERNDEF   dllvar
  24282.                .DATA
  24283.    dllvar      WORD    0
  24284.  
  24285.  The variable must then be exported in a module-definition file, as shown in
  24286.  Section 18.4.1, "Writing the Module-Definition File." When executable files
  24287.  other than the DLL access the variable, they must treat it as far data, as
  24288.  in the following example:
  24289.  
  24290.    mov     ax, SEG dllvar
  24291.    mov     es, ax
  24292.    mov     bx, es:dllvar
  24293.  
  24294.  An exported procedure (often called a dynamic-link procedure) must follow
  24295.  these rules:
  24296.  
  24297.  
  24298.    ■   It must be declared far and public. The MASM keyword EXPORT does both
  24299.        of these.
  24300.  
  24301.    ■   The procedure should initialize DS upon entry (unless you are not
  24302.        going to be accessing any static near data).
  24303.  
  24304.    ■   Data pointers in the parameter list should be far.
  24305.  
  24306.  
  24307.  The easiest way to realize most of these requirements is to use the EXPORT
  24308.  keyword and LOADDS in the procedure's prologuearg list (see Section 7.3.8).
  24309.  LOADDS generates instructions to save DS and load it with the value of the
  24310.  DLL's data segment. The EXPORT keyword makes the procedure FAR and PUBLIC,
  24311.  overriding the memory model. You may also need to use FORCEFRAME, which
  24312.  instructs the assembler to generate a stack frame even if there are no
  24313.  parameters or locals.
  24314.  
  24315.  The example DLL used in the chapter, CSTR.DLL, illustrates how DLLs can be
  24316.  shared by several processes. The procedures in the DLL write a string and
  24317.  keep track of the number of times the string is written. When more than one
  24318.  process uses the DLL, they all increment the global variable  GCount, but
  24319.  each process increments its own private instance of the  PCount  variable.
  24320.  
  24321.  The only initialization code this DLL needs is code to set up the exit code.
  24322.  The next section shows how to write a module-definition file to create an
  24323.  import library and how to create a DLL from this code.
  24324.  
  24325.  The code for the CSTR.DLL example looks like this:
  24326.  
  24327.    .MODEL  small, pascal, os_os2, farstack
  24328.            .286
  24329.  
  24330.    INCL_NOCOMMON   EQU     1
  24331.    INCL_DOSPROCESS EQU     1
  24332.    INCL_VIO        EQU     1
  24333.  
  24334.            INCLUDE    OS2.INC
  24335.            INCLUDELIB OS2.LIB
  24336.  
  24337.            .DOSSEG
  24338.  
  24339.    VioWrtCStr PROTO FAR PASCAL, pchString:PCH, hv:HVIO
  24340.    GetGCount  PROTO     PASCAL
  24341.    GetPCount  PROTO     PASCAL
  24342.    CStrExit   PROTO FAR
  24343.  
  24344.            .STACK
  24345.            .DATA               ; Default segment is SHARED
  24346.  
  24347.    GCount  WORD    0           ; Count of all calls
  24348.  
  24349.    @CurSeg ENDS
  24350.  
  24351.    PRIVDAT SEGMENT WORD     ; Private segment is NONSHARED
  24352.  
  24353.    PCount  WORD    0           ; Count of all this process
  24354.                                ;  calls to VioWrtCStr
  24355.    PRIVDAT ENDS
  24356.  
  24357.            .CODE
  24358.            .STARTUP
  24359.  
  24360.        pusha
  24361.  
  24362.            ; Initialization goes here. In this case, the only
  24363.            ;  initialization is setting up the exit behavior.
  24364.  
  24365.            INVOKE  DosExitList, EXLST_ADD, CStrExit
  24366.            INVOKE  DosExitList, EXLST_EXIT,0
  24367.  
  24368.            popa
  24369.            retf
  24370.  
  24371.    VioWrtCStr PROC FAR PASCAL EXPORT <LOADDS> USES cx di si,
  24372.            pchString:PCH,
  24373.            hv:HVIO
  24374.  
  24375.            sub     al, al         ; Search for zero
  24376.            mov     cx, 0FFFFh     ; Set maximum length
  24377.            les     di, pchString  ; Load pointer
  24378.            mov     si, di         ; Copy it
  24379.            repne   scasb          ; Find null
  24380.            .IF     zero?          ; Continue if found
  24381.            sub     di, si         ; Calculate length
  24382.            xchg    di, si         ; Restore address and save length
  24383.  
  24384.            INVOKE  VioWrtTTy,     ; Let OS/2 do output
  24385.                    es:di,         ; Address of string
  24386.                    si,            ; Calculated length
  24387.                    hv             ; Video handle
  24388.  
  24389.            inc     GCount         ; Count as one of total calls
  24390.  
  24391.    ASSUME  DS:PRIVDAT
  24392.            mov     ax, PRIVDAT
  24393.            mov     ds, ax
  24394.            inc     PCount         ; Count as one of process calls
  24395.            ASSUME  DS:DGROUP
  24396.            sub     ax, ax         ; Success
  24397.            .ELSE
  24398.            mov     ax, 1          ; Error
  24399.            .ENDIF
  24400.            ret
  24401.    VioWrtCStr ENDP
  24402.  
  24403.    GetGCount PROC  FAR PASCAL EXPORT <LOADDS, FORCEFRAME>
  24404.            mov     ax, GCount
  24405.            ret
  24406.    GetGCount ENDP
  24407.  
  24408.    GetPCount PROC  FAR PASCAL EXPORT <LOADDS, FORCEFRAME> USES ds
  24409.            ASSUME  DS:PRIVDAT
  24410.            mov     ax, PRIVDAT
  24411.            mov     ds, ax
  24412.            mov     ax, PCount
  24413.            ASSUME  DS:NOTHING
  24414.            ret
  24415.    GetPCount ENDP
  24416.  
  24417.            .DATA
  24418.    szOut   BYTE    13, 10, "Exiting DLL...", 13, 10, 0
  24419.            .CODE
  24420.  
  24421.    CStrExit PROC   FAR  <LOADDS, FORCEFRAME>
  24422.            INVOKE  VioWrtCStr,
  24423.                    ADDR szOut,
  24424.                    0
  24425.            INVOKE  DosExitList, EXLST_EXIT, 0
  24426.    CStrExit ENDP
  24427.  
  24428.            END
  24429.  
  24430.  These generated code for the  VIOWrtCStr  procedure follows. The code marked
  24431.  with asterisks is generated by the assembler.
  24432.  
  24433.    VioWrtCStr PROC FAR PASCAL EXPORT <LOADDS> USES cx di si,
  24434.            pchString:PCH,
  24435.            hv:HVIO
  24436.     0000  55        *         push   bp
  24437.     0001  8B EC     *         mov    bp, sp
  24438.     0003  1E        *         push   ds
  24439.     0004  B8 ---- R *         mov    ax, DGROUP
  24440.     0007  8E D8     *         mov    ds, ax
  24441.     0009  51        *         push   cx
  24442.     000A  57        *         push   di
  24443.     000B  56        *         push   si
  24444.            .
  24445.            .                      ; Procedure code here
  24446.            .
  24447.                               ret
  24448.     000C  5E        *         pop    si
  24449.     000D  5F        *         pop    di
  24450.     000E  59        *         pop    cx
  24451.     000F  1F        *         pop    ds
  24452.     0010  C9        *         leave
  24453.     0011  CA 0006   *         ret    00006h
  24454.     0014               VioWrtCStr ENDP
  24455.  
  24456.  The DLL should establish its own data segment.
  24457.  
  24458.  The DLL should change DS in this manner because each client program has its
  24459.  own private version of DGROUP. When a program calls your dynamic-link
  24460.  procedure, DS points to the program's data area, not yours. The solution is
  24461.  to initialize DS so that it points to your own default data area.
  24462.  
  24463.  However, one side effect of this approach is that it alters DS so that it no
  24464.  longer is equal to SS. Consequently, all data pointers in the parameter list
  24465.  must be far pointers, even if the data was stack data or near data.
  24466.  
  24467.  
  24468.  18.3.3  Creating Initialization and Termination Code
  24469.  
  24470.  Begin initialization code with the .STARTUP directive.
  24471.  
  24472.  A DLL can contain procedures that require special resources, such as
  24473.  temporary files or dynamic memory blocks. Resources allocated during
  24474.  initialization exist for the lifetime of the client program and are removed
  24475.  when the client program exits. Usually the best method for managing these
  24476.  resources is to write initialization and termination code.
  24477.  
  24478.  A DLL can have a starting point just as an application does. In the case of
  24479.  a DLL, this starting point marks the beginning of the initialization code. A
  24480.  DLL does not need a starting point if it has no need for initialization. Do
  24481.  not use .EXIT, since .EXIT will terminate the client program.
  24482.  
  24483.  Attributes of the initialization code are defined in the module-definition
  24484.  file (see Section 18.4.1). Initialization code can have the INITGLOBAL or
  24485.  INITINSTANCE attribute.
  24486.  
  24487.  INITGLOBAL specifies that the initialization code executes only once─when
  24488.  the DLL is first loaded into memory. INITINSTANCE specifies that
  24489.  initialization code should execute once for each program that uses the DLL.
  24490.  INITGLOBAL is the default. You should use termination code only for DLLs
  24491.  that have been defined with INITINSTANCE unless you know that the first
  24492.  process to use the DLL is the last to terminate.
  24493.  
  24494.  To specify INITINSTANCE, place the LIBRARY statement in your
  24495.  moduledefinition file:
  24496.  
  24497.    LIBRARY CSTR INITINSTANCE
  24498.  
  24499.  In the statement above, CSTR is the name of the DLL.
  24500.  
  24501.  To include a termination procedure, invoke DosExitList in the initialization
  24502.  code. DosExitList is a system function that attaches a termination procedure
  24503.  to a program. When the program terminates, OS/2 executes the procedure as
  24504.  part of the program exit sequence. In the termination procedure itself,
  24505.  release any system resources (such as memory or files) allocated during
  24506.  initialization.
  24507.  
  24508.  This is the termination code for the CSTR.DLL module:
  24509.  
  24510.    CStrExit PROC   FAR  <LOADDS, FORCEFRAME>
  24511.            INVOKE  VioWrtCStr,
  24512.                    ADDR szOut,
  24513.                    0
  24514.            INVOKE  DosExitList, EXLST_EXIT, 0
  24515.    CStrExit ENDP
  24516.  
  24517.  The termination code in CSTR.DLL uses the INVOKE directive to set up a call
  24518.  to the DosExitList function. You can perform a similar operation by simply
  24519.  pushing arguments on the stack and observing the correct calling convention.
  24520.  
  24521.  
  24522.  The effect of DosExitList in the initialization code is to make OS/2 call
  24523.  the termination procedure when the current process exits. The "current
  24524.  process" in this case is the client program, not the DLL or the DLL
  24525.  initialization code.
  24526.  
  24527.  
  24528.  18.4  Building the DLL
  24529.  
  24530.  To create a DLL, you need to assemble the DLL code, write a
  24531.  module-definition file, use LINK to create the DLL, generate an import
  24532.  library, and then link the DLL to the client program.
  24533.  
  24534.  
  24535.  18.4.1  Writing the Module-Definition File
  24536.  
  24537.  A module-definition file is required for DLLs.
  24538.  
  24539.  The module-definition file is an ASCII text file that lists attributes of a
  24540.  library or application (in the case of an application, this file is
  24541.  optional). The moduledefinition file gives directions to the linker that
  24542.  supplement the information on the command line.
  24543.  
  24544.  This module-definition file tells the linker to create a DLL called CSTR.DLL
  24545.  with INITINSTANCE data. The library has exported procedure  VioWrtCStr,
  24546.  GetPCount, and  GetGCount, and the data segment  PRIVDAT  is not shared
  24547.  between programs:
  24548.  
  24549.    LIBRARY CSTR INITINSTANCE
  24550.  
  24551.    EXPORTS
  24552.        VioWrtCstr
  24553.        GetGCount
  24554.        GetPCount
  24555.  
  24556.    DATA SINGLE NONSHARED
  24557.  
  24558.  The LIBRARY statement need not specify a name. If the name is omitted, the
  24559.  linker gives the library the base filename of the module-definition file.
  24560.  The default file extension is .DLL. The INITINSTANCE attribute is optional
  24561.  and is significant only if you have initialization code. If you specify
  24562.  INITINSTANCE, then the library initialization is called each time a new
  24563.  process gains access to the library. Otherwise, it will be called once only.
  24564.  
  24565.  
  24566.   At least one procedure must be listed after EXPORTS.
  24567.  
  24568.  The EXPORTS statement lists identifiers (procedures and variables) that can
  24569.  be accessed directly by client programs. Note that if you give a procedure
  24570.  the EXPORTS attribute from within the source code, you do not need to list
  24571.  the procedure here. The EXPORTS keyword automatically exports the procedure
  24572.  by name, so putting the names of the procedures in the module-definition
  24573.  file is not required. However, exported variables must be listed in a
  24574.  module-definition file.
  24575.  
  24576.  The DATA statement lists attributes for data segments (DGROUP) in the DLL.
  24577.  The default for DLLs, SINGLE, specifies that one DGROUP is shared by all
  24578.  instances of the DLL. NONSHARED specifies that all other data segments are
  24579.  not to be shared. See Section 13.15, "CODE, DATA, and SEGMENTS Attributes."
  24580.  
  24581.  
  24582.  
  24583.  18.4.2  Generating an Import Library with IMPLIB
  24584.  
  24585.  The DLL exports a procedure; the client program imports it.
  24586.  
  24587.  Just as a procedure is exported by a DLL, it must be imported by an
  24588.  application. An application's EXE header must indicate what dynamic-link
  24589.  procedures are used and where they reside. The easiest way to specify this
  24590.  information is with an "import library," which is a .LIB file that contains
  24591.  the import information in object-record form. The IMPLIB utility automates
  24592.  this process for you.
  24593.  
  24594.  To create an import library, run the IMPLIB utility on the module-definition
  24595.  file:
  24596.  
  24597.    IMPLIB MYDYNLIB.LIB MYDYNLIB.DEF
  24598.  
  24599.  The result is the import library, MYDYNLIB.LIB, which you then link to any
  24600.  program that calls CSTR.DLL. You would then list MYDYNLIB.LIB in the
  24601.  libraries field (the fourth field) of the LINK command. Or, in
  24602.  assembly-language programs, you can link to this library automatically by
  24603.  just adding the following statement to the source code of your program:
  24604.  
  24605.    INCLUDELIB MYDYNLIB.LIB
  24606.  
  24607.  
  24608.  18.4.3  Creating and Using the DLL
  24609.  
  24610.  Now you can use LINK to create the DLL. The LINK utility uses the object
  24611.  module of the DLL code and the module definition to create the CSTR.DLL:
  24612.  
  24613.    LINK CSTR.OBJ , , , , MYDYNLIB.DEF
  24614.  
  24615.  If linking is successful, the linker creates a file with a .DLL extension.
  24616.  
  24617.  You can link several modules together to create a DLL. The following command
  24618.  line links several object modules and an object-code library (BIGLIB.LIB) to
  24619.  form a DLL. The module-definition file is MYDYNLIB.DEF:
  24620.  
  24621.    LINK  MOD1 MOD2 MOD3,,, BIGLIB, MYDYNLIB
  24622.  
  24623.  To use the DLL, copy the .DLL file to a directory listed in the LIBPATH
  24624.  setting in your CONFIG.SYS file.
  24625.  
  24626.  To create an executable file using the DLL, link the client program with the
  24627.  import library as shown:
  24628.  
  24629.    LINK CALLDLL.OBJ , , , MYDYNLIB.LIB
  24630.  
  24631.  By running CALLDLL.EXE in separate OS/2 windows, you can see that both
  24632.  client programs access the DDL at the same time. When the last process exits
  24633.  the DLL, the DLL is removed from memory.
  24634.  
  24635.  
  24636.  18.5  Related Topics in Online Help
  24637.  
  24638.  In addition to information covered in this chapter, information on the
  24639.  following topics can be found in online help.
  24640.  
  24641.  Topic                             Access
  24642.  ────────────────────────────────────────────────────────────────────────────
  24643.  LINK                              From the "Microsoft Advisor Contents"
  24644.                                    screen, select LINK
  24645.  
  24646.  Module-definition files           Select Module-Definition Files from the
  24647.                                    "LINK Contents" screen
  24648.  
  24649.  EXPORT                            Select from the MASM Language Index
  24650.  
  24651.  EXTERNDEF                         From the "MASM 6.0 Contents" screen,
  24652.                                    select "Directives"; then select "Scope
  24653.                                    and Visibility" from the next screen
  24654.  
  24655.  LOADDS,                           Choose "Proc" from the MASM Language
  24656.  FORCEFRAME                        Index
  24657.  
  24658.  IMPLIB                            Select "IMPLIB Summary" from the "LINK
  24659.                                    Contents" screen
  24660.  
  24661.  
  24662.  
  24663.  
  24664.  
  24665.  
  24666.  Chapter 19  Writing Memory-Resident Software
  24667.  ────────────────────────────────────────────────────────────────────────────
  24668.  
  24669.  Through its memory-management system, DOS allows a program to remain
  24670.  resident in memory after terminating. The resident program can later regain
  24671.  control of the processor to perform tasks such as background printing or
  24672.  "popping up" a calculator on the screen. Such a program is commonly called a
  24673.  TSR, from the Terminate-and-Stay-Resident function it uses to return to DOS.
  24674.  
  24675.  
  24676.  This chapter explains the techniques of writing memory-resident software.
  24677.  The first two sections present introductory material. Following sections
  24678.  describe important DOS and BIOS interrupts and focus on how to write safe,
  24679.  compatible, memory-resident software. Two example programs illustrate the
  24680.  techniques described in the chapter. These programs are also available as
  24681.  sample programs on the MASM 6.0 disks.
  24682.  
  24683.  
  24684.  19.1  Terminate-and-Stay-Resident Programs
  24685.  
  24686.  DOS maintains a pointer to the beginning of unused memory. Programs load
  24687.  into memory at this position. They terminate execution by returning control
  24688.  to DOS. Normally, the pointer remains unchanged, allowing DOS to reuse
  24689.  memory when loading other programs.
  24690.  
  24691.  A terminating program can, however, prevent other programs from loading on
  24692.  top of it. It does this by returning to DOS through the
  24693.  terminate-and-stay-resident function, which resets the free-memory pointer
  24694.  to a higher position. This leaves the program resident in a protected block
  24695.  of memory, even though it is no longer running.
  24696.  
  24697.  The terminate-and-stay-resident function (Function 31h) is one of the DOS
  24698.  services invoked through Interrupt 21h. The following fragment shows how a
  24699.  TSR program terminates using Function 31h and remains resident in a
  24700.  1000h-byte block of memory:
  24701.  
  24702.    mov     ah, 31h          ; Request DOS Function 31h
  24703.            mov     al, err          ; Set return code
  24704.            mov     dx, 100h         ; Reserve 100h paragraphs
  24705.                                     ;  (1000h bytes)
  24706.            int     21h              ; Terminate-and-stay-resident
  24707.  
  24708.  ────────────────────────────────────────────────────────────────────────────
  24709.  NOTE
  24710.  
  24711.  In current versions of DOS, Interrupt 27h also provides a
  24712.  terminate-and-stayresident service. However, Microsoft cannot guarantee
  24713.  future support for Interrupt 27h and does not recommend its use.
  24714.  ────────────────────────────────────────────────────────────────────────────
  24715.  
  24716.  
  24717.  19.1.1  Structure of a TSR
  24718.  
  24719.  TSRs consist of two distinct parts that execute at different times. The
  24720.  first part is the installation section, which executes only once, when DOS
  24721.  loads the program. The installation code performs any initialization tasks
  24722.  required by the TSR and then exits through the terminate-and-stay-resident
  24723.  function.
  24724.  
  24725.  A TSR consists of an installation section and a resident section.
  24726.  
  24727.  The second part of the TSR, called the resident section, consists of code
  24728.  and data left in memory after termination. Though often identified with the
  24729.  TSR itself, the resident section makes up only part of the entire program.
  24730.  
  24731.  The TSR's resident code must be able to regain control of the processor and
  24732.  execute after the program has terminated. Methods of executing a TSR are
  24733.  classified as either passive or active.
  24734.  
  24735.  
  24736.  19.1.2  Passive TSRs
  24737.  
  24738.  The simplest way to execute a TSR is to transfer control to it explicitly
  24739.  from another program. Because the TSR in this case does not solicit
  24740.  processor control, it is said to be passive. If the calling program can
  24741.  determine the TSR's memory address, it can grant control via a far jump or
  24742.  call. More commonly, a program activates a passive TSR through a software
  24743.  interrupt. The installation section of the TSR writes the address of its
  24744.  resident code to the proper position in the interrupt vector table (see
  24745.  Section 7.4, "DOS Interrupts"). Any subsequent program can then execute the
  24746.  TSR by calling the interrupt.
  24747.  
  24748.  Passive TSRs often replace existing software interrupts. For example, a
  24749.  passive TSR might replace Interrupt 10h, the BIOS video service. By
  24750.  intercepting calls that read or write to the screen, the TSR can access the
  24751.  video buffer directly, increasing display speed.
  24752.  
  24753.  Passive TSRs allow limited access since they can be invoked only from
  24754.  another program. They have the advantage of executing within the context of
  24755.  the calling program, and thus run no risk of interfering with another
  24756.  process, which could happen with active TSRs.
  24757.  
  24758.  
  24759.  19.1.3  Active TSRs
  24760.  
  24761.  The second method of executing a TSR involves signaling it through some
  24762.  hardware event, such as a predetermined sequence of keystrokes. This type of
  24763.  TSR is called active because it must continually search for its start-up
  24764.  signal. The advantage of active TSRs lies in their accessibility. They can
  24765.  take control from any running application, execute, and return, all on
  24766.  demand.
  24767.  
  24768.  An active TSR, however, must not seize processor control blindly. It must
  24769.  contain additional code that determines the proper moment at which to
  24770.  execute. The extra code consists of one or more routines called "interrupt
  24771.  handlers," described in the following section.
  24772.  
  24773.  
  24774.  19.2  Interrupt Handlers in Active TSRs
  24775.  
  24776.  The memory-resident portion of an active TSR consists of two parts. One part
  24777.  contains the body of the TSR─the code and data that perform the program's
  24778.  main tasks. The other part contains the TSR's interrupt handlers.
  24779.  
  24780.  An interrupt handler is a routine that takes control when a specific
  24781.  interrupt occurs. Although sometimes called an "interrupt service routine,"
  24782.  a TSR's handler usually does not service the interrupt. Instead, it passes
  24783.  control to the original interrupt routine, which does the actual interrupt
  24784.  servicing.
  24785.  
  24786.  Collectively, interrupt handlers ensure that a TSR operates compatibly with
  24787.  the rest of the system. Individually, each handler fulfills at least one of
  24788.  the following functions:
  24789.  
  24790.  
  24791.    ■   Auditing hardware events that may signal a request for the TSR
  24792.  
  24793.    ■   Monitoring system status
  24794.  
  24795.    ■   Determining whether a request for the TSR should be honored, based on
  24796.        current system status
  24797.  
  24798.  
  24799.  
  24800.  19.2.1  Auditing Hardware Events for TSR Requests
  24801.  
  24802.  Active TSRs commonly use a special keystroke sequence or the timer as a
  24803.  request signal. A TSR invoked through one of these channels must be equipped
  24804.  with handlers that audit keyboard or timer events.
  24805.  
  24806.  A keyboard handler receives control at every keystroke. It examines each
  24807.  key, searching for the proper signal or "hot key." Generally, a keyboard
  24808.  handler should not attempt to call the TSR directly when it detects the hot
  24809.  key. If the TSR cannot safely interrupt the current process at that moment,
  24810.  the keyboard handler is forced to exit to allow the process to continue.
  24811.  Since the handler cannot regain control until the next keystroke, the user
  24812.  has to press the hot key repeatedly until the handler can comply with the
  24813.  request.
  24814.  
  24815.  Instead, the handler should merely set a request flag when it detects a
  24816.  hot-key signal and then exit normally. Examples in the following paragraphs
  24817.  illustrate this technique.
  24818.  
  24819.  For computers other than the IBM PS/2 (R) series, an active TSR audits
  24820.  keystrokes through a handler for Interrupt 09, the keyboard interrupt:
  24821.  
  24822.    Keybrd  PROC    FAR
  24823.            sti                   ; Interrupts are okay
  24824.            push    ax            ; Save AX register
  24825.            in      al, 60h       ; AL = scan code of current key
  24826.            call    CheckHotKey   ; Check for hot key
  24827.            .IF     !carry?       ; If not hot key:
  24828.    ; Hot key pressed. Reset the keyboard to throw away keystroke.
  24829.            cli                   ; Disable interrupts while resetting
  24830.            in      al, 61h       ; Get current port 61h state
  24831.            or      al, 10000000y ; Turn on bit 7 to signal clear keybrd
  24832.            out     61h, al       ; Send to port
  24833.            and     al, 01111111y ; Turn off bit 7 to signal break
  24834.            out     61h, al       ; Send to port
  24835.            mov     al, 20h       ; Reset interrupt controller
  24836.            out     20h, al
  24837.            sti                   ; Reenable interrupts
  24838.            pop     ax            ; Recover AX
  24839.            mov     cs:TsrRequestFlag, TRUE ; Raise request flag
  24840.            iret                  ; Exit interrupt handler
  24841.            .ENDIF                ; End hot-key check
  24842.  
  24843.    ; No hot key was pressed, so let normal Int 09 service
  24844.    ; routine take over
  24845.  
  24846.            pop     ax            ; Recover AX and fall through
  24847.            cli                   ; Interrupts cleared for service
  24848.    KeybrdMonitor LABEL FAR       ; Installed as Int 09 handler for
  24849.                                  ;  PS/2 or for time-activated TSR
  24850.                                  ; Signal that interrupt is busy
  24851.            mov     cs:intKeybrd.Flag, TRUE
  24852.            pushf                 ; Simulate interrupt by pushing flags,
  24853.                                  ;  far-calling old Int 09 routine
  24854.            call    cs:intKeybrd.OldHand
  24855.            mov     cs:intKeybrd.Flag, FALSE
  24856.            iret
  24857.    Keybrd  ENDP
  24858.  
  24859.  A TSR running on a PS/2 computer cannot reliably read key-scan codes using
  24860.  the above method. Instead, the TSR must search for its hot key through a
  24861.  handler for Interrupt 15h (Miscellaneous System Services). The handler
  24862.  determines the current keypress from the AL register when AH equals 4Fh, as
  24863.  shown here:
  24864.  
  24865.    MiscServ PROC   FAR
  24866.            sti                   ; Interrupts okay
  24867.            .IF     ah == 4Fh     ; If Keyboard Intercept Service:
  24868.            push    ax            ; Preserve AX
  24869.            call    CheckHotKey   ; Check for hot key
  24870.            pop     ax
  24871.            .IF     !carry?       ; If hot key:
  24872.            mov     cs:TsrRequestFlag, TRUE ; Raise request flag
  24873.            clc                   ; Signal BIOS not to process the key
  24874.            ret     2             ; Simulate IRET without popping flags
  24875.            .ENDIF                ; End carry flag check
  24876.            .ENDIF                ; End Keyboard Intercept check
  24877.            cli                   ; Disable interrupts and fall through
  24878.    SkipMiscServ LABEL FAR        ; Interrupt 15h handler if PC/AT
  24879.            jmp     cs:intMisc.OldHand
  24880.    MiscServ ENDP
  24881.  
  24882.  The example program in Section 19.8 demonstrates how a TSR tests for a PS/2
  24883.  machine and then sets up a handler for either Interrupt 09 or Interrupt 15h
  24884.  to audit keystrokes.
  24885.  
  24886.  Setting a request flag in the keyboard handler allows other code, such as
  24887.  the timer handler (Interrupt 08), to recognize a request for the TSR. The
  24888.  timer handler gains control at every timer interrupt; the interrupts occur
  24889.  an average of 18.2 times per second. The following fragment shows how a
  24890.  timer handler tests the request flag and continually polls until it can
  24891.  safely execute the TSR.
  24892.  
  24893.    TestFlag PROC FAR
  24894.            .
  24895.            .
  24896.            .
  24897.            cmp     TsrRequestFlag, FALSE ; Has TSR been requested?
  24898.            je      exit                  ; If not, exit
  24899.            call    CheckSystem           ; Can system be interrupted
  24900.                                          ;  safely?
  24901.            jc      exit                  ; If not, exit
  24902.            call    ActivateTsr           ; If okay, call TSR
  24903.  
  24904.  Figure 19.1 illustrates the process. It shows a time line for a typical TSR
  24905.  signaled from the keyboard. When the keyboard handler detects the proper hot
  24906.  key, it sets a request flag called  TsrRequestFlag. Thereafter, the timer
  24907.  handler continually checks the system status until it can safely call the
  24908.  TSR.
  24909.  
  24910.  The timer itself can serve as the start-up signal if the TSR executes
  24911.  periodically. Screen clocks that continuously show seconds and minutes are
  24912.  examples of TSRs that use the timer this way. ALARM.ASM, a program described
  24913.  in the next section, shows another example of a timer-driven TSR.
  24914.  
  24915.  (This figure may be found in the printed book.)
  24916.  
  24917.  
  24918.  19.2.2  Monitoring System Status
  24919.  
  24920.  A TSR that uses a hardware device such as the video or disk must not
  24921.  interrupt while the device is active. A TSR monitors a device by handling
  24922.  the device's interrupt. Each interrupt handler need only set a flag to
  24923.  indicate that the device is in use and then clear the flag when the
  24924.  interrupt finishes.
  24925.  
  24926.  The following shows a typical monitor handler:
  24927.  
  24928.    NewHandler PROC    FAR
  24929.            mov     ActiveFlag, TRUE  ; Set active flag
  24930.            pushf                     ; Simulate interrupt by
  24931.                                      ;  pushing flags,
  24932.            call    OldHandler        ;  then calling original routine
  24933.            mov     ActiveFlag, FALSE ; Clear active flag
  24934.            iret                      ; Return from interrupt
  24935.    NewHandler ENDP
  24936.  
  24937.  Only hardware used by the TSR requires monitoring. For example, a TSR that
  24938.  performs disk input/output (I/O) must monitor disk use through Interrupt
  24939.  13h. The disk handler sets an active flag that prevents the TSR from
  24940.  executing during a read or write operation. Otherwise, the TSR's own I/O
  24941.  would move the disk head. This would cause the suspended disk operation to
  24942.  continue with the head incorrectly positioned when the TSR returned control
  24943.  to the interrupted program.
  24944.  
  24945.  In the same way, an active TSR that displays to the screen must monitor
  24946.  calls to Interrupt 10h. The Interrupt 10h BIOS routine does not protect
  24947.  critical sections of code that program the video controller. The TSR must
  24948.  therefore ensure that it does not interrupt such nonreentrant operations.
  24949.  
  24950.  The activities of the operating system also affect the system status. With
  24951.  few exceptions, DOS functions are not reentrant and must not be interrupted.
  24952.  However, monitoring DOS is somewhat more complicated than monitoring
  24953.  hardware. Discussion of this subject is deferred until Section 19.4.
  24954.  
  24955.  The following comments describe the chain of events depicted in Figure 19.1.
  24956.  Each comment refers to one of the numbered pointers in the figure.
  24957.  
  24958.  
  24959.    1.  At time = t, the timer handler activates. It finds the flag
  24960.        TsrRequestFlag  clear, indicating that the TSR has not been requested.
  24961.        The handler terminates without taking further action. Notice that
  24962.        Interrupt 13h is currently processing a disk I/O operation.
  24963.  
  24964.    2.  Before the next timer interrupt, the keyboard handler detects the hot
  24965.        key, signalling a request for the TSR. The handler sets
  24966.        TsrRequestFlag  and returns.
  24967.  
  24968.    3.  At time = t + 1/18 second, the timer handler again activates and finds
  24969.         TsrRequestFlag  set. The handler checks other active flags to
  24970.        determine if the TSR can safely execute. Since Interrupt 13h has not
  24971.        yet completed its disk operation, the timer handler finds
  24972.        DiskActiveFlag  set. The handler therefore terminates without invoking
  24973.        the TSR.
  24974.  
  24975.    4.  At time = t + 2/18 second, the timer handler again finds
  24976.        TsrRequestFlag set and repeats its scan of the active flags.
  24977.        DiskActiveFlag  is now clear, but in the interim, Interrupt 10h has
  24978.        activated as indicated by the flag  VideoActiveFlag. The timer handler
  24979.        accordingly terminates without invoking the TSR.
  24980.  
  24981.    5.  At time = t + 3/18 second, the timer handler repeats the process. This
  24982.        time it finds all active flags clear, indicating that the TSR may
  24983.        safely execute. The timer handler calls the TSR, which sets its own
  24984.        active flag to ensure that it will not interrupt itself if requested
  24985.        again.
  24986.  
  24987.    6.  The timer and other interrupts continue to function normally while the
  24988.        TSR executes.
  24989.  
  24990.  
  24991.  
  24992.  19.2.3  Determining Whether to Invoke the TSR
  24993.  
  24994.  Once a handler receives a request signal for the TSR, it checks the various
  24995.  active flags maintained by the handlers that monitor system status. If any
  24996.  of the flags are set, the handler ignores the request and exits. If the
  24997.  flags are clear, the handler invokes the TSR, usually through a near or far
  24998.  call. Figure 19.1 illustrates how a timer handler detects a request and then
  24999.  periodically scans various active flags until all the flags are clear.
  25000.  
  25001.  A TSR that changes stacks must not interrupt itself. Otherwise, the second
  25002.  execution would overwrite the stack data belonging to the first. A TSR
  25003.  prevents this by setting its own active flag before executing, as shown in
  25004.  Figure 19.1. A handler must check this flag along with the other active
  25005.  flags when determining whether the TSR can safely execute.
  25006.  
  25007.  
  25008.  19.3  Example of a Simple TSR: ALARM
  25009.  
  25010.  This section presents a simple alarm clock TSR that demonstrates some of the
  25011.  material covered so far. The program accepts an argument from the command
  25012.  line that specifies the alarm setting in military form, such as 1635 for
  25013.  4:35 P.M. For the sake of simplicity, the argument must consist of four
  25014.  digits, including leading zeros. To set the alarm at 7:45 A.M., for example,
  25015.  enter:
  25016.  
  25017.    ALARM 0745
  25018.  
  25019.  The installation section of the program begins with the  Install  procedure.
  25020.   Install  computes the number of five-second intervals that must elapse
  25021.  before the alarm sounds and stores this number in the word  CountDown. The
  25022.  procedure then obtains the vector for Interrupt 08 (timer) through Interrupt
  25023.  21h Function 35h and stores it in the far pointer  OldTimer. Interrupt 21h
  25024.  Function 25h replaces the vector with the far address of the new timer
  25025.  handler  NewTimer. Once installed, the new timer handler executes at every
  25026.  timer interrupt. These interrupts occur 18.2 times per second or 91 times
  25027.  every five seconds.
  25028.  
  25029.  Each time it executes, NewTimer  subtracts one from a secondary counter
  25030.  called  Tick91. By counting 91 timer ticks,  Tick91  accurately measures a
  25031.  period of five seconds. When  Tick91  reaches zero, it's reset to 91 and
  25032.  CountDown  is decremented by one. When  CountDown  reaches zero, the alarm
  25033.