I--, Programmer's Utilities Guide for the IBM'OPersonal Computer Disk Operating System Copyright @ 1983 Digital Research P.O. Box 579 160 Central Avenue Pacific Grove, CA 93950 (408) 649-3896 TWX 910 360 5001 All Rights Reserved COPYRIGHT Copyright 0 1983 by Digital Research. All rights reserved. No part of this publication may be reproduced, transmitted, transcribed, stored in a retrieval system, or translated into any language or computer language, in any form or by any means, electronic, mechanical, magnetic, optical, chemical, manual or otherwise, without the prior written permission of Digital Research, Post Office Box 579, Pacific Grove, California, 93950. This manual is, however, tutorial in nature. Thus, the reader is granted permission to include the example programs, either in whole or in part, in his or her own programs. DISCLAIMER Digital Research makes no representations or warranties with respect to the contents hereof and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Further, Digital Research reserves the right to revise this publication and to make changes from time to time in the content hereof without obligation of Digital Research to notify any person of such revision or changes. TRADEMARKS CP/M-86 is a registered trademark of Digital Research. CB80, CB86, Concurrent CP/M-86, LIB-86, LINK-86, MP/M-86, PL/I-86, RASM-86, and SID-86 are trademarks of Digital Research. Intel is a registered trademark of Intel Corporation. MCS-86 is a trademark of Intel Corporation. IBM is a registered trademark of International Business Machines. IBM Personal Computer is a tradename of International Business Machines. The Programmer's Utilities Guide for the IBM Personal Computer Disk Operating System was prepared using the Digital Research TEX Text Formatter and printed in the United States of America. First Edition: April 1983 Foreword This manual describes several utility programs that aid programmers and system designers in the software development process. Collectively, these utilities allow you to assemble 8086 assembly language modules, link them together to form a program that runs, and generate a cross-reference map of the variables used in a program. You can also use these utilities to create and manage your own libraries of subroutines and program modules, as well as create large programs by breaking them into separate overlays. The Programmer's Utilities Guide assumes that you are familiar with the DOS operating system environment. It also assumes that you are familiar with the basic elements of 8086 assembly language programming. RASM-86T11 is an assembler that translates 8086 assembly language statements into a relocatable object file in the Intel@ format. RASM-86 facilities include assembly of Intel 8086 mnemonics, assembly-time expressions, conditional assembly, page formatting of listing files, and powerful code-macro capabilities. Section 1 describes the overall operation of RASM-86 and its optional run-time parameters. Section 2 describes elements of RASM-86 assembly language, including the character set, delimiters, constants, identifiers, operators, expressions, and statements. Section 3 describes the various RASM-86 directives that control the assembly process. Section 4 contains a brief description of the RASM-86 instructions for data transfer, mathematical operations, string manipulation, control transfer, and processor control. Section 5 describes the code-macro facilities of RASM-86. Section 6 describes XREF-86 TM , an assembly language cross reference program used with RASM-86. Section 7 describes LINK-86Tm , the linkage editor that combines relocatable object modules into an absolute file that runs under DOS. Section 8 explains how to use LIB-86 TM , the software librarian that creates and manages libraries. The appendixes contain a complete list of error messages output by each of the utility programs. Table of Contents I Introduction to RASM-86 1.1 Assembler Operation . . . . . . . . . . . . . . . . 1.2 Invoking RASM-86 . . . . 1-2 1.3 Optional Run-time Parameters 2 Elements of RASM-86 Assembly Language 2.1 RASM-86 Character Set . . . . . . . . 2.2 Tokens and Separators . . . . 2.3 Delimiters . . . . . . . . . 2.4 Constants . . . . . . . . . . 2.4.1 Numeric Constants . . . . . . . . . . . . . 2-3 2.4.2 Character Strings . . . . . . . . . . . . . 2-3 2.5 Identifiers . . . . . . . . . . . . . . . . . . . . 2-4 2.5.1 Keywords . . . . . . . . . . . . . . . . . . 2-5 2.5.2 Symbols and Their Attributes . . . . . . . . 2-6 2.6 Operators . . . . . . . . . . . . . . . . . . . . . 2-7 2.6.1 Operator Examples . . . . . . . . . . . . . 2-11 2.6.2 Operator Precedence . . . . . . . . . . . . 2-13 2.7 Expressions . . . . . . . . . . . . . . . . . . . . 2-14 2.8 Statements . . . . . . . . . . . . . . . . . . . . 2-15 3 Assembler Directives 3.1 Segments . . . . . . 3.2 The Segment Directive 3.2.1 3.2.2 . 3.2.3 3.3 The GROUP Directive . . . 3.4 The ORG Directive . . . v Table of Contents (continued) 3.5 The END Directive . . . . . . . . . . . . . . . . . 3-5 3.6 The NAME Directive . . . . . . . . . . . . . . . . 3-6 3.7 The PUBLIC Directive . . . . . . . . . . . . . . . 3-6 3.8 The EXTRN Directive . . . . . . . . . . . . . . . 3-6 3.9 The IF, ELSE, and ENDIF Directives . . . . . . . . 3-7 3.10 The EQU Directive . . . . . . . . . . . . . . . . . 3-7 3.11 The DB Directive . . . . . . . . . . . . . . . . . 3-8 3.12 The DW Directive . . . . . . . . . . . . . . . . . 3-9 3.13 The DD Directive . . . . . . . . . . . . . . . . . 3-9 3.14 The RS Directive . . . . . . . . . . . . . . . . . 3-9 3.15 The RB Directive . . . . . . . . . . . . . . . . . 3-10 3.16 The RW Directive . . . . . . . . . . . . . . . . . 3-10 3.17 The RD Directive . . . . . . . . . . . . . . . . . 3-10 3.18 The EJECT Directive . . . . . . . . . . . . . . . . 3-10 3.19 The NOIFLIST and IFLIST Directives . . . . . . . . 3-10 3.20 The NOLIST and LIST Directives . . . . . . . . . . 3-11 3.21 The PAGESIZE Directive . . . . . . . . . . . . . . 3-11 3.22 The PAGEWIDTH Directive . . . . . . . . . . . . . . 3-11 3.23 The SIMFORM Directive . . . . . . . . . . . . . . . 3-11 3.24 The TITLE Directive . . . . . . . . . . . . . . . . 3-11 3.25 The INCLUDE Directive . . . . . . . . . . . . . . . 3-12 4 The RASM-86 instruction Set 4.1 Introduction . . . . . . . . . . . . . . . . . . . 4-1 4.2 Data Transfer Instructions . . . . . . . . . . . . 4-3 vi Table of Contents (continued) 4.3 Arithmetic, Logical, and Shift Instructions . . . . 4-4 4.4 String Instructions . . . . . . . . . . . . . . . . 4-10 4.5 Control Transfer Instructions . . . . . . . . . . . 4-12 4.6 Processor Control Instructions . . . . . . . . . . 4-16 5 Code-macro Facilities 5.1 Introduction to Code-macros . . . . . . . . . . . . 5-1 5.2 Specifiers . . . . . . . . . . . . . . . . . . . . 5-3 5.3 Modifiers . . . . . . . . . . . . . . . . . . . . . 5-3 5.4 Range Specifiers . . . . . . . . . . . . . . . . . 5-4 5.5 Code-macro Directives . . . . . . . . . . . . . . . 5-4 5.5.1 SEGFIX . . . . . . . . . . . . . . . . . . . 5-5 5.5.2 NOSEGFIX . . . . . . . . . . . . . . . . . . 5-5 5.5.3 momm . . . . . . . . . . . . . . . . . . . 5-5 5.5.4 RELB and RELW . . . . . . . . . . . . . . . 5-6 5.5.5 DB, DW and DD . . . . . . . . . . . . . . . 5-7 5.5.6 DBIT . . . . . . . . . . . . . . . . . . . . 5-7 6 XREF-86 6.1 Introduction . . . . . . 6-1 6.2 Invoking XREF-86 7 LINK-86 7.1 Introduction . . . . . . . . . . . . . . . . . . . 7-1 7.2 Invoking LINK-86 . . . . . . . . . . . . . . . . . 7-2 7.3 Definitions . . . . . . . . . . . . . . . . . . . . 7-3 7.4 The Link Process . . . . . . . . . . . . . . . . . 7-4 7.4.1 Phase 1 - Collection . . . . . . . . . . . . 7-4 7.4.2 Phase 2 - Positioning . . . . . . . . . . . 7-7 vii Table of Contents (continued) 7.5 LINK-86 Command Options . . . . . . . . . . . . . . 7-9 7.6 EXE File Options . . . . . . . . . . . . . . . . . 7-11 7.6.1 ADDITIONAL, MAXIMUM . . . . . . . . . . . . 7-11 7.6.2 FILL/NOFILL . . . . . . . . . . . . . . . . 7-12 7.7 SYM File Options . . . . . . . . . . . . . . . . . 7-12 7.7.1 LOCALS/NOLOCALS . . . . . . . . . . . . . . 7-13 7.7.2 LIBSYMS/NOLIBSYMS . . . . . . . . . . . . . 7-13 7.8 MAP File Options . . . . . . . . . . . . . . . . . 7-13 7.9 L86 File Options . . . . . 7.10 Command Input File Options 7.11 1/0 Options 7 7.11.1 $Cd - Command . . . . . . . . . . . . . . . 7-16 7.11.2 $Ld - Library . . . . . . . . . . . . . . . 7-16 7.11.3 $Md - Map . . . . . . . . . . . . . . . . . 7-16 7.11.4 $Od - Object . . . . . . . . . . . . . . . 7-16 7.11.5 $Sd - Symbol . . . . . . . . . . . . . . . 7-16 7.12 Command Line Errors . . . . . . . . . . . . . . . 7-17 8 LIB-86 8.1 LIB-86 Operation . . . . . . . . . . . . . . . . . 8-1 8.2 LIB-86 Command Options . . . . . . . . . . . . . . 8-2 8.3 Creating and Updating Libraries . . . . . . . . . . 8-3 8.3.1 Creating a New Library . . . . . . . . . . . 8-3 8.3.2 Adding to a Library . . . . . . . . . . . . 8-3 8.3.3 Replacing a Module . . . . . . . . . . . . . 8-4 8.3.4 Deleting a Module . . . . . . . . . . . . . 8-4 8.3.5 Selecting a Module . . . . . . . . . . . . . 8-5 8.4 Displaying Library Information . . . . . . . . . . 8-5 8.4.1 Cross-reference File . . . . . . . . . . . . 8-6 8.4.2 Library Module Map . . . . . . . . . . . . . 8-6 8.4.3 Partial Library Maps . . . . . . . . . . . . 8-6 viii Table of Contents (continued) 8.5 LIB-86 Commands on Disk . . . . . . . . . . . . . . 8-7 8.6 Redirecting 1/0 . . . . . . . . . . . . . . . . . . 8-7 Appendixes * Mnemonic Differences from the Intel Assembler . . . . A-1 * Reserved words . . . . . . . . . . . . . . . . . . . . B-1 C RASM-86 Instruction Set . . . . . . . . . . . . . . . C-1 * Code-macro Definition Syntax . . . . . . . . . . . . . D-1 * Sample Program . . . . . . . . . . . . . . . . . . . . E-1 * RASM-86 Error messages . . . . . . . . . . . . . . . F-1 * LINK-86 Error Messages . . . . . . . . . . . . . . . G-1 * LIB-86 Error Messages . . . . . . . . . . . . . . . . H-1 I XREF-86 Error Messages . . . . . . . . . . . . . . . I-1 ix Tables, Figures, and Listings Tables 1-1. RASM-86 Run-time Parameters . . . . . . . . . . 1-2. RASM-86 Command Line Examples. . 2-1. Separators and Delimiters . . . . 2-2. Radix Indicators for Constants . . . . . . . . 2-3. String Constant Examples . . . . . . . . 2-4. Register Keywords . . . . . . . . . . . 2-5. RASM-86 Operators . . . . . . . . . . . 2-6. Precedence of Operations in RASM-86. 3-1. Default Segment Names . . . . . . 3-2. Default Align Types . . . . . . . 4-1. Operand Type Symbols . . . . . . . . . . . . . . 4-1 4-2. Flag Register Symbols . . . . . . . . . . . . . . 4-2 4-3. Data Transfer Instructions . . . . . . . . . . . 4-3 4-4. Effects of Arithmetic Instructions on Flags . . . 4-5 4-5. Arithmetic Instructions . . . . . . . . . . . . . 4-5 4-6. Logical and Shift Instructions . . . . . . . . .4-7 4-7. String Instructions . . . . . . . . . . . . . . . 4-10 4-8. Prefix Instructions . . . . . . . . . . . . . . . 4-12 4-9. Control Instructions . . . . . . . . . . . . . . 4-13 4-10. Processor Control Instructions . . . . . . . . . 4-16 Code-macro Operand Specifiers . . . . . . . . . . 5-3 Code-macro Operand Modifiers . . . . . . . . . . 5-4 7-1. LINK-86 Definitions . . . . . . . . . . . . . . 7-3 7-2. LINK-86 Usage of Class Names . . . . . . . . . . 7-9 7-3. LINK-86 Command Options . . . . . . . . . . . . . 7-10 7-4. EXE File Option Parameters . . . . . . . . . . . 7-11 7-5. Default Values for EXE File Options . . . . . . . 7-12 8-1. LIB-86 Filetypes . . . . . . . . . . . . . . . . 8-2 8-2. LIB-86 Command Line Options . . . . . . . . . . . 8-2 A-1. Mnemonic Differences . . . . . . . . . . . . . . A-1 B-1. Reserved Words . . . . . . . . . . . . . . . . . B-1 C-1. RASM-86 Instruction Summary . . . . . . . . . . C-1 F-1. RASM-86 Nonrecoverable Errors . . . . . . . . . . F-1 F-2. RASM-86 Diagnostic Error Messages . . . . . . . . F-2 G-1. LINK-86 Error Messages . . . H-1. LIB-86 Error Messages . . . . . . . . . . . . . . H-1 I-1. XREF-86 Error Messages . . . . . . . . . . . . .I-1 x Tables, Figures, and Listings (continued) Figures 1-1. RASM-86 Source and object Files . . . . . . . . . 1-1 6-1. XREF-86 Operation . . . . . . . 7-1. LINK-86 Operation . . . . . . . . . . . . . . . . 7-2 7-2. Combining Segments with the Public Combine Type. 7-4 7-3. Combining Segments with the Common Combine Type. 7-5 7-4. Combining Segments using the Align Type . . . . . 7-6 7-5. Paragraph Alignment . . . . . . . . . . . . . . . 7-7 7-6. The Effect of Grouping Segments . . . . . . . . . 7-8 7-6a. Segments without Groups . . . . . . . . . . . . . 7-8 7-6b. Segments within a Group . . . . . . . . . . . . .7-8 8-1. LIB-86 Operation . . . . . . . . . . . . . . . . B-1 Listing E-1. Sample Program APPE.A86 . . . . . . . . . . . . . E-1 xi Section 1 Introduction to RASM-86 1.1 Assembler Operation RASM-86 processes an 8086 assembly language source file in three passes and produces an 8086 machine language object file. RASM-86 can optionally produce three output files from one source file as shown in Figure 1-1. LIST FIL (FILENAME. LST) SOURCE FILE RASM-86 OBJECT FILE (FILE (FILENAMEA83~6) NAME.OBJ V SYMBOL FILE FILENAME.SYM Figure 1-1. RASM-86 Source and Object Files The LST list file contains the assembly language listing with any error messages. The OBJ object file contains the object code in Intel 8086 relocatable object format. The SYM symbol file lists any user-defined symbols. The three files have the same filename as the source file. For example, if the name of the source file is BIOS88.A86, RASM-86 produces the files BIOS88.OBJ, BIOS88.LST, and BIOS88.SYM. 1- 1 Programmer's Utilities Guide 1.2 Invoking RASM-86 1.2 Invoking RASM-86 Invoke RASM-86 with a command in the form: RASM86 source file ($ optional parameters) The filespec has the form: [d:]filename[.typj where d: is an optional drive specification denoting the source file Is 1 o c a t i o n . The dr ive specification is not needed if the, source is on current drive. filename is a valid filename of 1 to 8 characters. typ is a valid filetype of 1 to 3 characters, usually A86. RASM-86 accepts a source file with any filetype. If you omit the filetype from the command line, RASM-86 searches the directory for the specified filename with the filetype A86. The following are some examples of valid RASM-86 commands: A>rasm86 b:bios88 A>rasm86 bios88.a86 $ aa ob pb sb A>rasm86 d:test Once invoked, RASM-86 responds with the message: RASM-86 Relocating Assembler Version X.X Serial No. xxxx-0000-654321 All Rights Reserved Copyright (C) 1982,1983 Digital Research, Inc. -------------------------------------------------- RASM-86 then attempts to open the source file. If the file does not exist on the designated drive or does not have the correct filetype, RASM-86 displays the message: NO FILE and stops processing. 1-2 Programmer's Utilities Guide L2 Invoking RASM-86 By default, RASM-86 creates the output files on the currently logged-in disk drive. However, you can redirect the output files by using the optional parameters, or by a drive specification in the 10~ source filename. In the latter case, RASM-86 directs the output files to the drive specified in the source filename. When the assembly is complete, RASM-86 displays the message: END OF ASSEMBLY. NUMBER OF ERRORS: n USE FACTOR: pp% The Use Factor indicates how much of the available Symbol Table space was actually used during the assembly. The Use Factor is expressed as a decimal percentage ranging from 0 to 99. 1.3 Optional Run-time Parameters The dollar sign character, $, denotes an optional string of run-time parameters. A parameter is a single-letter followed by a single-letter device name specification. The parameters are shown in Table 1-1. Table 1-1. RASM-86 Run-time Parameters Parameter Specifies Valid Arguments A Source file device A, B, C, P L Local symbols in object file 0 0 object file device A P, Z P List file device A P, X, Y, Z S Symbol file device A P, X, Y, Z All the parameters are optional, and you can enter them in the command line in any order. Enter the dollar sign only once at the beginning of the parameter string. Spaces can separate parameters, but are not required. However, no space is permitted between a parameter and its device name. If you specify an invalid parameter in the parameter list, RASM-86 displays the message: SYNTAX ERROR RASM-86 then echoes the command tail up to the point where the error occurs and follows with a question mark. (Appendix F contains the complete list of RASM-86 error messages.) A device name must follow the parameters A, 0, P, and S. The devices are labeled as follows: Ar B, C, ... P or X, Yr Z Programmer's Utilities Guide 1.3 Run-time Parameters Device names A through P specify disk drives A through P, respectively. X specifies the user console, Y specifies the list device, and Z suppresses output. If you direct the output to the console, you can temporarily stop the display at any time by typing a CTRL-S, and then restart it by typing CTRL-Q. The LO parameter directs RASM-86 to include local symbols in the object file so that they appear in the SYM file created by LINK 86. Otherwise, only public symbols appear in the SYM file. You can use the SYM file with a symbolic instruction debugger to simplify program debugging. Table 1-2. RASK-86 Command Line Examples Command Line I Result rasm86 io Assembles file IO.A86 and produces IO.OBJ, IO.LST, and IO.SYM, all on the default drive. rasm86 io.asm $ ad sz Assembles file IO.ASM on drive D and produces 10 . L S T and IO.OBJ. Suppresses the symbol file. rasm86 io $ py sx Assembles file IO.A86, produces IO.OBJ, and sends listing directly to printer. Also outputs symbols on console. rasm86 io $ lo Includes local symbols in IO.OBJ. End of Section 1 1-4 Section 2 Elements of RASM-86 Assembly Language 2.1 RASM-86 Character Set RASM-86 recognizes a subset of the ASCII character set. The valid characters are the alphanumerics, special characters, and nonprinting characters shown below: A B C D E F G H I J K L M N 0 P Q R S T U V W X Y Z a b c d e f g h i j k 1 m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + - * / = ( ) [ I ; , - ! , - : @ $ ? space, tab, carriage return, and line-feed RASM-86 treats lower-case letters as upper-case except within strings. Only alphanumerics, special characters, and spaces can appear in a string. 2.2 Tokens and Separators A token is the smallest meaningful unit of a RASM-86 source program, much as a word is the smallest meaningful unit of a sentence. Adjacent tokens within the source are commonly separated by a blank character or space. Any sequence of spaces can appear wherever a single space is allowed. RASM-86 recognizes horizontal tabs as separators and interprets them as spaces. RASM-86 expands tabs to spaces in the list file. The tab stops are at each eighth column. 2.3 Deliniters Delimiters mark the end of a token and add special meaning to the instruction; separators merely mark the end of a token. When a delimiter is present, separators need not be used. However, using separators after delimiters can make your program easier to read. Table 2-1 describes RASM-86 separators and delimiters. Some delimiters are also operators; these are explained in greater detail in Section 2.6. 2-1 Programmer's Utilities Guide 2.3 Delimiters Table 2-1. Separators and Delimiters Character I Name J Use 20H space separator 09H tab legal in source files, expanded in list files CR carriage return terminates source lines LF line-feed legal after CR; if in source lines, it is interpreted as a space ; semicolon starts comment field : colon identifies a label; used in segment override specification . period forms variables from numbers $ dollar sign notation for present value of location counter; legal, but ignored in identifiers or numbers + plus arithmetic operator for addition - minus arithmetic operator for subtraction * asterisk arithmetic operator for multiplication / slash arithmetic operator for division @ at legal in identifiers _ underscore legal in identifiers ! exclamation logically terminates a point statement, allowing multiple statements on a single source line ' apostrophe delimits string constants 2-2 Programmer's Utilities Guide 2.4 Constants 2.4 Constants A constant is a value known at assembly time that does not change while the assembled program is running. It can be either an integer or a character string. 2.4.1 Numeric Constants A numeric constant is a 16-bit value in one of several bases. The base, called the radix of the constant, is denoted by a trailing radix indicator. The radix indicators are shown in Table 2-2. Table 2-2. Radix Indicators for Constants Indicatorl Constant Type Base B or b binary 2 O or o octal 8 Q or q octal 8 D or d decimal 10 H or h hexadecimal 16 RASM-86 assumes that any numeric constant that does not terminate with a radix indicator is a decimal constant. Radix indicators can be upper- or lower-case. A constant is thus a sequence of digits followed by an optional radix indicator where the digits are in the range for the radix. Binary constants must be composed of zeros and ones. Octal digits range from 0 to 7; decimal digits range from 0 to 9. Hexadecimal constants contain decimal digits and the hexadecimal digits A (10D) , B (11D) , C (12D) , D (13D) , E (14D) , and F (15D) . The leading character of a hexadecimal constant must be a decimal digit so that RASM-86 cannot confuse a hex constant with an identifier. The following are valid numeric constants; 1234 1234D 1100B 1111000011110000B 1234H 0FFEH 3377o 13772Q 3377O 0FE3H 1234d 0ffffh 2.4.2 Character Strings A character string constant is a string of ASCII characters delimited by apostrophes. All RASM-86 instructions that allow numeric constants as arguments, accept only one- or two- character constants as valid arguments. All instructions treat a one character string as an 8-bit number, and a two-character string as a 16-bit number. The value of the second character is in the low order byte, and the value of the first character is in the high order byte. 2-3 Programmer's Utilities Guide 2.4 Constants The numeric value of a character is its ASCII code. RASM-86 does not translate case in character strings, so you can use both upper- and lower-case letters. Note that RASM-86 allows only alphanumerics, special characters, and spaces in character strings. A DB directive is the only RASM-86 statement that can contain strings longer than two characters (see Section 3.8). The string cannot exceed 255 bytes. If you want to include an apostrophe in the string, you must enter it twice. RASM-86 interprets the two keystrokes '' as a single apostrophe. Table 2-3 shows valid character strings and how they appear after processing. Table 2-3. String Constant Examples String in source text I As processed by RASM-86 'a' a 'Ab''Cd' Ab'Cd 'I like IBM' I like IBM 'I'' I' 'ONLY UPPER CASE' ONLY UPPER CASE 'only lower case' only lower case 2.5 Identifiers The following rules apply to all identifiers: • Identifiers can be up to 80 characters long. • The first character must be alphabetic, one of the special characters ?, @, or the underscore _ character • Any subsequent characters can be either alphabetic numeric, or the special characters ?, @, _, or $. RASM-86 ignores the special character $ in identifiers, so that you can use it to improve readability in long identifiers. For example, RASM-86 treats the identifier interrupt$flag as interruptflag. There are two types of identifiers. The first type are keywords that have predefined meanings to RASM-86. The second type are symbols you define. The following are all valid identifiers: NOLIST WORD AH Third_street How_are_you_today ble@number@1234567890 varia 2-4 Programmer's Utilities Guide 2.5 Identifiers 2.5.1 Keywords Keywords are reserved for use by RASM-86; you cannot define an identifier identical to a keyword. Appendix D contains the complete list of keywords. RASM-86 recognizes five types of keywords: • instructions • directives • operators • registers • predefined numbers Section 4 defines the 8086 instruction mnemonic keywords and the actions they initiate. Section 3 discusses RASM-86 directives. Section 2.6 defines operators. Table 2-4 lists the RASM-86 keywords that identify 8086 registers. Three keywords, BYTE, WORD, and DWORD, are predefined numbers. The values of these numbers are 1, 2, and 4, respectively. RASM-86 also associates a Type attribute with each of these numbers. The keyword's Type attribute is equal to the keyword's numeric value. Table 2-4. Register Keywords Register Numeric Symbol Size(bytes) Value Meaning AH 1 100 Accumulator High Byte BH 1 111 Base Register High Byte CH 1 101 Count Register High Byte DH 1 110 Data Register High Byte AL 1 000 Accumulator Low Byte BL 1 011 Base Register Low Byte CL 1 001 Count Register Low Byte DL 1 010 Data Register Low Byte AX 2 000 Accumulator (full word) BX 2 011 Base Register (full word) CX 2 001 Count Register (full word) DX 2 010 Data Register (full word) BP 2 101 Base Pointer SP 2 100 Stack Pointer SI 2 110 Source Index DI 2 111 Destination Index 2-5 I Programmer's Utilities Guide 2.5 Identifiers Table 2-4. (continued) Register Numeric Symbol Size(bytes) Value Meaning CS 2 01 Code Segment Register DS 2 11 Data Segment Register SS 2 10 Stack Segment Register ES 2 00 Extra Segment Register 2.5.2 Symbols and Their Attributes A symbol is a user-defined identifier that has attributes specifying the kind of information the symbol represents. Symbols fall into three categories: • variables • labels • numbers Variables identify data stored at a particular location in memory. All variables have the following three attributes: • Segment tells which segment was being assembled when the variable was defined. • Offset tells how many bytes there are between the beginning of the segment and the location of this variable. • Type tells how many bytes of data are manipulated when this variable is referenced. A segment can be a code segment, a data segment, a stack segment, or an extra segment, depending on its contents and the register that contains its starting address (see Section 3.2) . The segment's starting address is a number between 0 and 65,535D. This number indicates the paragraph in memory to which the current segment is assigned, either when the program is assembled, when it is linked, or when it is loaded. The offset of a variable is the address of the variable relative to the starting address of the segment. The offset can be any number between 0 and OFFFFH or 65,535D. A variable has one of the following Type attributes: o BYTE o WORD o DWORD 2-6 Programmer's Utilities Guide 2.5 Identifiers BYTE specifies a one-byte variable; WORD, a two-byte variable, and DWORD, a four-byte variable. The DB, DW, and DD directives define variables as these three types (see Section 3). For example, a variable is defined when it appears as the name for a storage directive: my_yariable db 0 You can also define a variable as the name for an EQU directive referencing another variable, as shown below: another-variable equ my_yariable Labels identify locations in memory that contain instruction statements. They are referenced with jumps or calls. All labels have two attributes, segment and offset. Label segment and offset attributes are essentially the same as variable segment and offset attributes. A label is defined when it precedes an instruction. A colon separates the label from instruction. For example, my_label: add ax,bx A label can also appear as the name for an EQU directive referencing another label. For example, another-label equ my_label You can also define numbers as symbols. RASM-86 treats a number symbol as though you have explicitly coded the number it represents. For example, Number-five equ 5 mov al,Number-five is equivalent to: mov al,5 Section 2.6 describes operators and their effects on numbers and number symbols. 2.6 Operators RASM-86 operators fall into the following categories: arithmetic logical relational segment override variable manipulators and creators 2-7 Programmer's Utilities Guide 2.6 Operators Table 2-5 defines the RASM-86 operators. In this table, a and b represent two elements of the expression. The validity column defines the type of operands the operator can manipulate. The vertical bar character | separates alternatives. In this table, number refers to an absolute number which is a number whose value is known at assembly-time, such as a numeric constant. A relocatable number is a number whose value is unknown at assembly-time, because it can change during the linking process. For example, the offset of a variable located in a segment that will be combined with some other segments at link-time is a relocatable number. Table 2-5. RASM-86 Operators Syntax Result Validity Logical Operators a XOR b bit-by-bit logical EXCLUSIVE a, b = number OR of a and b a OR b bit-by-bit logical OR of a a, b = number and b a AND b bit-by-bit logical AND of a a, b = number and b NOT a logical inverse of a: all 0s a = 16-bit number become 1s, 1s become 0s Relational Operators a EQ b returns 0FFFFH if a = b, a, b = unsigned otherwise 0 numbers; or labels, variables, or relocatable numbers defined in the same segment a LT b returns OFFFFH if a < b, a, b = unsigned otherwise 0 numbers; or labels, variables, or relocatable numbers defined in the same segment a LE b returns OFFFFH if a <= b, a, b = unsigned otherwise 0 numbers; or labels, variables, or relocatable numbers defined in the same segment 2-8 Programmer's Utilities Guide 2.6 Operators Table 2-5. (continued) Syntax Result -7 Validity a GT b returns OFFFFH if a > b, a, b = unsigned otherwise 0 numbers; or labels, variables, or relocatable numbers defined in the same segment a GE b returns OFFFFH if a b, a, b = unsigned otherwise 0 numbers; or labels, variables, or relocatable numbers defined in the same segment a NE b returns OFFFFH if a <> b, a, b = unsigned otherwise 0 numbers; or labels, variables, or relocatable numbers defined in the same segment Arithmetic Operators a + b arithmetic sum of a and b a = number, variable, label, relocatable number, or external b = number a - b arithmetic difference of a = number, a and b variable, label, relocatable number, or external b = number; or variable, label, or relocatable number in the same segment as a a*b does unsigned multipli- b = number cation of a and b a/b does unsigned division of a, b = number a and b a MOD b returns remainder of a / b a, b = number a SHL b returns the value that a, b = number results from shifting a to left by an amount b 2-9 1 Programmer's Utilities Guide 2.6 Operators Table 2-5. (continued) Syntax I Result Validity a SHR b returns the value that a, b = number results from shifting a to the right by an amount b * a gives a a = number - a gives 0 - a a = number Segment Override : overrides assembler's choice of segment register CS, DS, SS or ES Variable Manipulators, Creators SEG a creates a number whose a = label variable value is the segment value of the variable or label a OFFSET a creates a number whose a = label variable value is the offset value of the variable or label a TYPE a creates a number. If a = label variable the variable a is of type BYTE, WORD or DWORD, the value of the number is 1, 2, or 4, respectively LENGTH a creates a number whose a variable value is the length attribute of the variable a. The length attribute is the number of bytes associated with the variable LAST a if LENGTH a > 0, then a = variable LAST a = LENGTH a - 1; if LENGTH a = 0, then LAST a = 0. a PTR b creates virtual variable a =BYTE | WORD or label with type of a | DWORD and attributes of b Programmer's Utilities Guide 2.6 Operators Table 2-5. (continued) Syntax Result Validity .a creates variable with an a = number offset attribute of a. Segment attribute is current data segment $ creates label with offset no argument equal to current value of location counter; segment attribute is current segment 2.6.1 Operator Examples Logical operators accept only numbers as operands. They perform the Boolean logic operations AND, OR, XOR, and NOT. For example, 00FC mask equ 0fch 0080 signbit equ 80h 0000 B180 mov cl,mask and signbit 0002 B003 mov al,not mask Relational operators treat all operands as unsigned numbers. The relational operators are EQ (equal), LT (less than), LE (less than or equal), GT (greater than), GE (greater than or equal), and NE (not equal) . Each operator compares two operands and returns all ones (OFFFFH) if the specified relation is true, and all zeros if it is not. For example, 000A limit1 equ 10 0019 limit2 equ 25 0004 B8FFFF mov ax,limit1 lt limit2 0007 B80000 mov ax,limit1 gt limit2 Addition and subtraction operators compute the arithmetic sum and difference of two operands. The first operand can be a variable, label, or number. For addition, the second operand must be a number. For subtraction, the second operand can be a number, or it can be a variable or label in the same segment as the first operand. When a number is added to a variable or label, the result is a variable or label with an offset whose numeric value is the second operand plus the offset of the first operand. Subtraction from a variable or label returns a variable or label whose offset is 2-11 Programmer's Utilities Guide 2.6 operators the first operand's offset, decremented by the number specified in the second operand. For example, 0002 count equ 2 0005 displ equ 5 OOOA FF flag db offh OOOB 2EAOOBOO mov al,flag+l OOOF 2E8AOEOFOO mov cl,flag+displ 0014 B303 mov bl,displ-count The multiplication and division operators *, /, MOD, SHL, and SHR accept only numbers as operands. * and / treat all operators as unsigned numbers. For example, 0016 BE5500 mov si,256/3 0019 B310 mov bl,64/4 0050 buffersize equ 80 001B B8AOOO mov ax,buffersize * 2 Unary operators accept both signed and unsigned operators, as shown below. 001E B123 mov cl,+35 0020 B007 mov al,2--5 0022 B2F4 mov dl,-12 When manipulating variables, RASM-86 decides which segment register to use. You can override this choice by specifying a different register with the segment override operator. The syntax for the override operator is segment register: address expression where the segment register is CS, DS, SS, or ES. For example, 0024 368B472D mov ax,ss:wordbuffer[bx] 0028 268BOE5BOO mov cx,es:array 002D 26A4 movs byte ptr [di],es:[si] A variable manipulator creates a number equal to one attribute of its variable operand. SEG extracts the variable's segment value; OFFSET, its offset value; TYPE, its type value (1, 2, or 4), and LENGTH, the number of bytes associated with the variable. LAST compares the variable's LENGTH with zero. If LENGTH is greater than zero, LAST decrements LENGTH by one. If LENGTH equals zero, LAST leaves it unchanged. Variable manipulators accept only variables as operators. For example, 2-12 Programmer's Utilities Guide 2.6 operators 002D 000000000000 wordbuffer dw 0,0,0 0033 0102030405 buffer db 1,2,3,4,5 0038 0500 mov ax,length buffer 003B 0400 mov ax,last buffer 003E 0100 mov ax,type buffer 0041 0200 mov ax,type wordbuffer The PTR operator creates a virtual variable or label valid only during the execution of the instruction. PTR makes no changes to either of its operands. The temporary symbol has the same Type attribute as the left operator, and all other attributes of the right operator as shown below. 0044 C60705 mov byte ptr [bx], 5 0047 8A07 mov al,byte ptr [bx] 0049 FF04 inc word ptr [si] The period operator . creates a variable in the current Data segment. The new variable has a segment attribute equal to the current Data segment and an offset attribute equal to its operand Its operand must be a number. For example, 004B AX DS:0000 mov ax, .0 004E BX DS:0040 mov bx, es: .4000h The dollar sign operator $ creates a label with an offset attribute equal to the current value of the location counter. The label segment value is the same as the current segment. This operator takes no operand. For example, 0053 E9FDFF jmp $ 0056 EBFE jmps $ 0058 E9FD2F jmp $+3000h 2.6.2 Operator Precedence Expressions combine variables, labels, or numbers with operators. RASM-86 allows several kinds of expressions (see Section 2.7). This section defines the order in which RASM-86 performs operations if more than one operator appear in an expression. RASM-86 evaluates expressions from left to right, but evaluates operators with higher precedence before operators with lower precedence. When two operators have equal precedence, RASM-86 evaluates the leftmost operator first. Table 2-6 shows RASM-86 operators in order of increasing precedence. 2-13 Programmer's Utilities Guide 2.6 Operators You can use parentheses to override the precedence rules. RASM-86 first evaluates the part of an expression enclosed in parentheses. If you nest parentheses, RASM-86 evaluates the innermost expressions first. For example, 15/3 + 18/9 = 5 + 2 = 7 15/(3 + 18/9) = 15/(3 + 2) = 15/5 = 3 (20*4) + ((27/9 - 4/2)) = (20*4) + (3 - 2) = 80 + 1 = 81 Note that RASM-86 allows five levels of nested parentheses. Table 2-6. Precedence of Operations in RASK-86 Order Operator Type Operators 1 Logical XOR, OR 2 Logical AND 3 Logical NOT 4 Relational EQ, LT, LE, GT, GE, NE 5 Addition/subtraction 6 multiplication/division MOD, SHL, SHR 7 Unary +, - 8 Segment override : 9 Variable manipulators, SEG, OFFSET, PTR, creators TYPE, LENGTH, LAST 10 Parentheses/brackets I I 11 Period and Dollar $ 2.7 Expressions RASM-86 allows address, numeric, and bracketed expressions. An address expression evaluates to a memory address and has three components: * a segment value * an offset value * a type 2-14 Programmer's Utilities Guide 2.7 Expressions Both variables and labels are address expressions. An address expression is not a number, but its components are numbers. You can combine numbers with operators such as PTR to make an address expression. A numeric expression evaluates to a number. It contains no variables or labels, only numbers and operands. Bracketed expressions specify base- and index-addressing modes. The base registers are BX and BP, and the index registers are DI and SI. A bracketed expression can consist of a base register, an index register, or both. Use the + operator between a base register and an index register to specify both base- and index-register addressing. For example, mov variable[bx],0 mov ax, [bx+di] mov ax,[si] 2.8 Statements Statements can be instructions or directives. RASM-86 translates instructions into 8086 machine language instructions. RASM-86 does not translate directives into machine code. Directives simply tell RASM-86 to perform certain functions. You must terminate each assembly language statement with a carriage return (CR) and line-feed (LF) , or with an exclamation point. RASM-86 treats these as an end-of-line. You can write multiple assembly language statements without comments on the same physical line and separate them with exclamation points. only the last statement on a line can have a comment because the comment field extends to the physical end of the line. Section 3 describes the RASM-86 instruction set in detail. The syntax for an instruction statement is [label:] [prefix] mnemonic (operand(s)] [;comment] where the fields are defined as: label A symbol followed by a colon defines a label at the current value of the location counter in the current segment. This field is optional. prefix Certain machine instructions such as LOCK and REP can prefix other instructions. This field is optional. 2-15 Programmer's Utilities Guide 2.8 Statements mnemonic A symbol defined as a machine instruction, either by RASM-86 or by an EQU directive. This field is optional unless preceded by a prefix instruction. If you omit this field, no operands can be present, although the other fields can appear. Section 4 describes the RASM-86 mnemonics. operand(s) An instruction mnemonic can require other symbols to represent operands to the instruction. Instructions can have zero, one, or two operands. comment Any semicolon appearing outside a character string begins a comment. A comment ends with a carriage return. This field is optional, but you should use comments to facilitate program maintenance and debugging. Section 3 describes the RASM-86 directives. The syntax for a directive statement is [name] directive operand(s) [;comment] where the fields are defined as: name Names are legal for CSEG, DSEG, ESEG, SSEG, GROUP, DB, DW, DD, RB, RW, RD, RS, and EQU directives. The name is required for the EQU and GROUP directives, but it is optional for the other directives. Unlike the label field of an instruction, the name field of a directive is never terminated with a colon. directive One of the directive keywords defined in Section 3. operand(s) Analogous to the operands for instruction mnemonics. Some directives, such as DB and DW allow any operand; others have special requirements. comment Exactly as defined for instruction statements. End of Section 2 2-16 Section 3 Assembler Directives Assembler directives control the assembly process by performing functions such as assigning portions of code to logical segments, requesting conditional assembly, defining data items, allocating memory, specifying listing file format, and including source text from external files. Section 2.8 shows the general syntax for directive statements. The following sections give the specific syntax and explanation for each directive statement. In the general syntax line for each statement, square brackets [] enclose optional arguments, user supplied arguments are shown in angle brackets. Assembler directives are grouped into the following categories: • segment control CSEG DSEG ESEG SSEG GROUP • linkage control NAME PUBLIC EXTRN END • conditional assembly IF ELSE ENDIF • symbol definition EQU • data definition and memory allocation DB DW DD RS RB RW RD • output listing control EJECT IFLIST/NOIFLIST LIST/NOLIST PAGESIZE PAGEWIDTH SIMFORM TITLE • miscellaneous INCLUDE ORG Programmer's Utilities Guide 3.1 Segments 3.1 Segments The 8086 CPU can address one megabyte (1,048,576 bytes) of memory. This entire address space can be subdivided into an arbitrary number of smaller units called segments. These can be up to 64K bytes in length. Each segment is comprised of contiguous memory locations that make up a logically independent and separately addressable unit. Each segment must have a base address that specifies its starting location in the memory space. Each segment base address must begin on a boundary divisible by 16, but there are no other restrictions on segment boundaries. Every location in the memory space has a physical address and a logical address. A physical address is a 20-bit value that specifies a unique byte location within the memory space. A logical address is the combination of a 16-bit segment base value and a 16 bit offset value. The offset value is the address relative to the base of the segment. At run-time, every memory reference is the combination of a segment base value and an offset value that produces a 20-bit physical address. Note that a physical address can be contained in more than one logical segment. The CPU can access four segments at a time. The base address of each segment is contained in a segment register. The CS register points to the current Code segment that contains instructions. The DS register points to the current Data segment that usually contains program variables. The SS register points to the current Stack segment where stack operations such as temporary storage or parameter passing are performed. The ES register points to the current Extra segment that also typically contains data. RASM-86 segment directives allow you to divide your assembly language source program into segments that correspond to the memory segments into which the resulting object code is eventually loaded at run-time. The size and type of segments you use in a program determine the type of memory execution model used by the operating system. You can intermix all of the code and data in a single 64K segment, or you can have separate Code and Data segments, each up to 64K in length. With RASM-86, you can also create an arbitrary number of Code, Data, Stack, and Extra segments to more fully use the address space of the 8086 processor. You can therefore have more than 64K of code or data by using several segments and managing the segments with the assembler directives. 3.2 The Segment Directive Every instruction and variable in a program must be contained in a segment. Instruction statements must be assigned to the Code Segment, but directive statements can be assigned to any segment. Create a segment and name it by using the following Segment directive. [1(J(] 3-2 Programmer's Utilities Guide 3.2 The Segment Directive where is one of the following: * CSEG (Code Segment) * DSEG (Data Segment) * ESEG (Extra Segment) * SSEG (Stack Segment) For example, DATASEG DSEG PARA CODE1 CSEG BYTE XYZ DSEG WORD COMMON 3.2.1 The can be any valid RASM-86 identifier. If you do not specify a , RASM-86 supplies a default name. Table 3-1 shows the default names. Table 3-1. Default Segment Names Segment Directive T Default Name CSEG CODE DSEG DATA ESEG EXTRA SSEG STACK Once you use a Segment directive, RASM-86 assigns statements to the specified segment until it encounters another Segment directive. RASM-86 combines all segments with the same even if they are not contiguous in the source code. 3.2.2 The allows you to specify to the linkage editor a particular boundary for the segment. The linkage editor uses this alignment information to combine segments when it produces an executable file. You can specify one of three different types: * BYTE (byte alignment) * WORD (word alignment) * PARA (paragraph alignment) If you specify an , it must be with the first definition of the segment. You can omit the on subsequent Segment directives that name the same segment, but you cannot change the original value. If you do not specify an , RASM-86 supplies a default value. Table 3-2 shows the default values. 3-3 Programmer's Utilities Guide 3.2 The Segment Directive Table 3-2. Default Align Types Segment Directives T Default Align Type CSEG BYTE DSEG WORD ESEG WORD SSEG WORD BYTE alignment means that the segment begins at the next byte following the previous segment. WORD alignment means that the segment begins on an even boundary. An even boundary is a hexadecimal address ending in 0,2,4,6,8,A,C, or E. In certain cases, WORD alignment can increase execution speed because the CPU takes only one memory cycle when accessing word-length variables within a segment aligned on an even boundary. Two cycles are needed if the boundary is odd. PARA (paragraph) alignment means that the segment begins on a paragraph boundary, that is, an address whose four low-order bits are zero. 3.2.3 The determines how the linkage editor can combine the segment with other segments with the same . You can specify one of two different types: * PUBLIC * COMMON If you specify a , it must be with the first definition of the segment. You can omit the on subsequent Segment directives that name the same segment, but you cannot change the original type. If you do not specify a , RASM-86 supplies the default type, PUBLIC. PUBLIC means that the linkage editor can combine the segment with other segments that have the same name. All such segments with PUBLIC are concatenated in the order they are encountered by the linkage editor, with gaps, if any, determined by the of the segment. COMMON means that the segment shares identical memory locations with other segments of the same name. offsets inside a COMMON segment are absolute unless the segment is contained in a GROUP (see Section 3.3). 3-4 Programmer's Utilities Guide 3.3 The GROUP Directive 3.3 The GROUP Directive GROUP , .... The GROUP directive instructs RASM-86 to combine the named segments into a collection called a group whose length can be up to 64K. Offsets within any of the segments of a group are relative to the beginning of the group rather than the beginning of the segment. The order of the s in the directive is the order in which the linkage editor arranges the segments in the EXE file 3.4 The ORG Directive ORG The ORG directive sets the offset of the location counter in the current segment to the value specified in the numeric expression. You must define all elements of the expression before using the ORG directive, and the expression must evaluate to an absolute number. The is relative to the location counter within the segment at load-time. Thus, if you use an ORG statement in a segment that the linkage editor does not combine with other segments at link-time, such as a common segment that is not in a group, then indicates the actual offset within the segment. However, if the segment is combined with others at link-time, such as PUBLIC segments, then is not an absolute offset. It is relative to the beginning part of the segment, from the program being assembled. Use of groups can result in more efficient code, because a number of segments can be addressed from a single segment register without having to change the contents of the segment register. 3.5 The END Directive END [] The END directive marks the end of a source file. RASM-86 ignores any subsequent lines. The END directive is optional, and if omitted, RASM-86 processes the source file until it finds an end-of file character (1AH). The optional serves two purposes. First it defines the current module as the main program. When LINK-86 links modules together, only one can be a main program. The also indicates where the program is to start executing after it is loaded. If is omitted, program execution begins at the beginning of the first CSEG from the files linked. 3-5 I Programmer's Utilities Guide 3.6 The NAME Directive 3.6 The NAME Directive NAME '' The NAME directive assigns a name to the object module generated by RASM-86. The '' can be any valid identifier. If you do not specify a module name with the NAME directive, RASM-86 assigns the source filename to the object module. Both LINK-86 and LIB-86 use object module names to identify object modules. 3.7 The PUBLIC Directive PUBLIC [, .... The PUBLIC directive instructs RASM-86 that the names defined as PUBLIC can be referenced by other programs which are linked together. Each name must be a label, variable, or a number that is defined within the program being assembled. 3.8 The EXTRN Directive EXTRN [, .... The EXTRN directive tells RASM-86 that each can be referenced in the program being assembled but is defined in some other program. The consists of two parts: a symbol and a type. The symbol can be a variable, label, or number. Type is one of the following: * Variables: BYTE WORD DWORD * Labels: NEAR FAR * Numbers: ABS For example, EXTRN FCB:BYTE,BUFFER:WORD,INIT:FAR,MAX:ABS RASM-86 determines the Segment attribute of external variables and labels from the segment containing the EXTRN directive. Thus, an EXTRN directive for a given symbol must appear within the segment in which the symbol is defined in some other module. 3-6 Programmer's Utilities Guide 3.9 IF, ELSE, and ENDIF 3.9 The IF, ELSE, and ENDIF Directives IF < source line 1 > < source line 2 > . . < source line n > [ELSE] < alternate source line 1 > < alternate source line 2 > . . < alternate source line n > ENDIF The IF and ENDIF directives allow you to conditionally include or exclude a group of source lines from the assembly. The optional ELSE directive allows you to specify an alternative set of source lines. You can use these conditional directives to assemble several different versions of a single source program. You can nest IF directives to five levels. When RASM-86 encounters an IF directive, it evaluates the numeric expression following the IF keyword. You must define all elements in the numeric expression before you use them in the IF directive. If the value of the expression is nonzero, then RASM-86 assembles through . If the value of the expression is zero, then RASM-86 lists all the lines, but does not assemble them. If the value of the expression is zero, and you specify an ELSE directive between the IF and ENDIF directives, RASM-86 assembles the alternative source lines. 3.10 The EQU Directive symbol EQU symbol EQU
symbol EQU symbol EQU The EQU (equate) directive assigns values and attributes to user-defined symbols. Do not put a colon after the symbol name. once you define a symbol, you cannot redefine the symbol with a subsequent EQU or another directive. You must also define any elements used in numeric or address expressions before using the EQU directive. 3-7 Programmer's Utilities Guide 3.10 The EQU Directive The first form assigns a numeric value to the symbol. The second assigns a memory address. The third form assigns a new name to an 8086 register. The fourth form defines a new instruction (sub)set. The following are examples of these four forms. 0005 FIVE EQU 2*2+1 0033 NEXT EQU BUFFER 0001 COUNTER EQU CX MOVVV EQU Mov 005D 8BC3 MOVVV AX,BX 3.11 The DB Directive [symbol] DB [, ...] [symbol] DB [, ... ] The DB directive defines initialized storage areas in byte format. RASM-86 evaluates numeric expressions to 8-bit values and sequentially places them in the object file. RASM-86 places string constants in the object file according to the rules defined in Section 2.4.2. Note that RASM-86 does not perform translation from lower- to upper-case within strings. The DB directive is the only RASM-86 statement that accepts a string constant longer than two bytes. You can add multiple expressions or constants, separated by commas, to the definition as long as it does not exceed the physical line length. Use an optional symbol to reference the defined data area throughout the program. The symbol has four attributes: the segment and offset attributes determine the symbol's memory reference; the type attribute specifies single bytes, and the length attribute tells the number of bytes reserved. The following statements show DB directives with symbols: 005F 43502F4D2073 TEXT DB 'CP/M system',O 797374656DOO 006B ElAA DB 'a' + 80H 006C 0102030405 X DB 1,2,3,4,5 0071 B90COO MOV CX,LENGTH TEXT 3-8 Programmer's Utilities Guide 3.12 The DW Directive 3.12 The DW Directive [symbol] DW [, ...] [symbol] DW [, ... ] The DW directive initializes two-byte words of storage. The DW directive initializes storage the same way as the DB directive, except that each numeric expression, or string constant initializes two bytes of memory with the low-order byte stored first. The DW directive does not accept string constants longer than two characters. The following are examples of DW statements: 0074 0000 CNTR DW 0 0076 63C166C169C1 JMPTAB DW SUBR1,SUBR2,SUBR3 007C 010002000300 DW 1,2,3,4,5,6 040005000600 3.13 The DD Directive [symbol] DD
[,
... ] The DD directive initializes four bytes of storage. The offset attribute of the address expression is stored in the two lower bytes; the segment attribute is stored in the two upper bytes. Otherwise, DD follows the same procedure as DB. For example, CSEG 0000 6CC100006FC1 LONG_JMPTAB DD ROUT1,ROUT2 0000 0008 72C1000075C1 DD ROUT3,ROUT4 0000 3.14 The RS Directive [symbol] RS The RS directive allocates storage in memory but does not initialize it. The numeric expression gives the number of bytes to reserve. Note that the RS directive does not give a Byte attribute to the optional symbol. For example, 0010 BUF RS 80 0060 RS 4000H 4060 RS 1 3-9 Programmer's Utilities Guide 3.15 The RB Directive 3.15 The RB Directive [symbol] RB The RB directive allocates byte storage in memory without any initialization. The RB directive is identical to the RS directive except that it gives the byte attribute. 3.16 The RW Directive [symbol] RW The RW directive allocates two-byte word storage in memory but does not initialize it. The numeric expression gives the number of words to be reserved. For example, 4061 BUFF RW 128 4161 RW 4000H C161 RW 1 3.17 The RD Directive [symbol] RD The RD directive reserves a double word (four bytes) of storage but does not initialize it. For example, C163 DWTAB RD 4 C173 RD 1 3.18 The EJECT Directive EJECT The EJECT directive performs a page eject during printout. The EJECT directive is printed on the first line of the next page. 3.19 The NOIFLIST and IFLIST Directives NOIFLIST IFLIST The NOIFLIST directive suppresses the printout of the contents of conditional assembly blocks that are not assembled. The IFLIST directive resumes printout of these blocks. 3-10 Programmer's Utilities Guide 3.20 The NOLIST/LIST Directives 3.20 The NOLIST and LIST Directives NOLIST LIST The NOLIST directive suppresses the printout of lines following the directive. The LIST directive restarts the listing. 3.21 The PAGESIZE Directive PAGESIZE The PAGESIZE directive defines the number of lines on each printout page. The default page size is 66 lines. 3.22 The PAGEWIDTH Directive PAGEWIDTH The PAGEWIDTH directive defines the number of columns printed across the page of the listing file. The default page width is 120 unless the listing is routed directly to the console; then the default page width is 79. 3.23 The SIMPORM Directive SIMFORM The SIMFORM directive replaces a form-feed (FF) character in the list file with the correct number of line-feeds (LF) . Use this directive when directing a list file to a printer that is unable to interpret the form-feed character. 3.24 The TITLE Directive TITLE RASM-86 prints the string constant defined by a TITLE directive statement at the top of each printout page in the listing file. The title character string can be up to 30 characters in length. For example, TITLE 'DOS monitor' 3-11 Programmer's Utilities Guide 3.25 The INCLUDE Directive 3.25 The INCLUDE Directive INCLUDE The INCLUDE directive includes another RASM-86 source file in the source text. For example, INCLUDE EQUALS.A86 You can use the INCLUDE directive when the source program is large and resides in several files. Note that you cannot nest INCLUDE directives; that is, a source file called by an INCLUDE directive cannot contain another INCLUDE directive. If the file named in the INCLUDE directive does not have a filetype, RASM-86 assumes the filetype to be A86. If you do not specify a drive name with the file, RASM-86 assumes the drive containing the source file. End of Section 3 3-12 Section 4 The RASM-86 Instruction Set 4.1 Introduction The RASM-86 instruction set includes all 8086 machine instructions. Section 2.7 gives the general syntax for instruction statements. The following sections define the specific syntax and required operand types for each instruction without reference to labels or comments. The instruction definitions are presented in tables for easy reference. For a more detailed description of each instruction, see the Intel MCS-86 Assembly Language Reference Manual. For descriptions of the instruction bit patterns and operations, see the Intel MCS-86 User's Manual. The instruction definition tables present RASM-86 instruction statements as combinations of mnemonics and operands. A mnemonic is a symbolic representation for an instruction; its operands are its required parameters. Instructions can take zero, one, or two operands. When two operands are specified, the left operand is the instruction's destination operand, and the two operands are separated by a comma. The instruction definition tables organize RASM-86 instructions into functional groups. In each table, the instructions are listed alphabetically. Table 4-1 shows the symbols used in the instruction definition tables to define operand types. Table 4-1. Operand Type Symbols Symbol Operand Type numb any numeric expression numb8 any numeric expression that evaluates to an 8-bit number acc accumulator register, AX or AL reg any general purpose register that is not a segment register reg16 a 16-bit general purpose register that is not a segment register segreg any segment register: CS, DS, SS, or ES 4-1 Programmer's Utilities Guide 4.1 Introduction Table 4-1.(continued) Symbol Operand Type mem any address expression with or without base- and/or index-addressing modes, such as: variable variable+3 variable[bx] variable [S I] variable[BX+SI] [BX] [BP+DI] simpmem any address expression without base- and index-addressing modes, such as: variable variable+4 mem1reg any expression symbolized by reg or mem memlregl6 any expression symbolized by mem1reg, but must be 16 bits label any address expression that evaluates to a label lab8 any label that is within +/- 128 bytes distance from the instruction The 8086 CPU has nine single-bit Flag registers that reflect the state of the processor. You cannot access these registers directly, but you can test them to determine the effects of an executed instruction upon an operand or register. The effects of instructions on Flag registers are also described in the instruction-definition tables, using the symbols shown in Table 4-2 to represent the nine Flag registers. Table 4-2. Flag Register Symbols Symbol Meaning AF Auxiliary Carry Flag CF Carry Flag DF Direction Flag IF Interrupt Enable Flag OF Overflow Flag PF Parity Flag SF Sign Flag TF Trap Flag ZF Zero Flag 4-2 Programmer's Utilities Guide 4.2 Data Transfer Instructions 4.2 Data Transfer Instructions There are four classes of data transfer operations: .oo__ • general purpose • accumulator specific • address-object • flag Only SAHF and POPF affect flag settings. Note in Table 4-3 that if acc = AL, a byte is transferred, but if acc = AX, a word is transferred. Table 4-3. Data Transfer Instructions Syntax Result IN acc,numb8 transfer data from input port given by numb8 (0-255) to accumulator IN acc,DX transfer data from input port given by DX register (0-0FFFFH) to accumulator LAHF transfer flags to the AH register LDS regl6,mem transfer the segment part of the memory address (DWORD variable) to the DS segment register; transfer the offset part to a general purpose 16-bit register LEA regl6,mem transfer the offset of the memory address to a 16-bit register LES regl6,mem transfer the segment part of the memory address to the ES segment register; transfer the offset part to a 16-bit general purpose register MOV reg,memlreg move memory or register to register MOV mem1reg,reg move register to memory or register MOV memlreg,numb move immediate data to memory or register MOV segreg,memiregl6 move memory or register to segment register 4-3 Programmer's Utilities Guide 4.2 Data Transfer Instructions Table 4-3. (continued) Syntax I Result MOV memlregl6,segreg move segment register to memory or register OUT numb8,acc transfer data from accumulator to output port (0-255) given by numb8 OUT DX,acc transfer data from accumulator to output port (0-0FFFFH) given by DX register POP memlregl6 move top stack element to memory or register POP segreg move top stack element to segment register; note that CS segment register is not allowed POPF transfer top stack element to flags PUSH memjregl6 move memory or register to top stack element PUSH segreg move segment register to top stack element PUSHF transfer flags to top stack element SAHF transfer the AH register to flags XCHG reg,memireg exchange register and memory or register XCHG mem1reg,reg exchange memory or register and register XLAT mem1reg perform tab1e 1ook up translation, table given by mem1reg, which is always BX. Replaces AL with AL offset from BX. 4.3 Arithmetic, Logical, and Shift Instructions The 8086 CPU performs the four basic mathematical operations in several ways. It supports both 8- and 16-bit operations and also signed and unsigned arithmetic. 4-4 Programmer's Utilities Guide 4.3 Arithmetic Instructions Six of the nine flag bits are set or cleared by most arithmetic operations to reflect the result of the operation. Table 4-4 summarizes the effects of arithmetic instructions on flag bits. Table 4-5 defines arithmetic instructions. Table 4-6 defines logical and shift instructions. Table 4-4. Effects of Arithmetic Instructions on Flags Flag Bit Result CF is set if the operation results in a carry out of (from addition) or a borrow into (from subtraction) the high-order bit of the result; otherwise CF is cleared. AF is set if the operation results in a carry out of (from addition) or a borrow into (from subtraction) the low-order four bits of the result; otherwise AF is cleared. ZF is set if the result of the operation is zero; otherwise ZF is cleared. SF is set if the result is negative. PF is set if the modulo 2 sum of the low-order eight bits of the result of the operation is 0 (even parity); otherwise PF is cleared (odd parity). OF is set if the operation results in an overflow; the size of the result exceeds the capacity of its destination. Table 4-5. Arithmetic Instructions Syntax Result AAA adjust unpacked BCD (ASCII) for addition - adjusts AL AAD adjust unpacked BCD (ASCII) for division - adjusts AL AAM adjust unpacked BCD (ASCII) for multiplication - adjusts AX AAS adjust unpacked BCD (ASCII) for subtraction - adjusts AL ADC reg,memireg add (with carry) memory or register to register 4-5 Programmer's Utilities Guide 4.3 Arithmetic Instructions Table 4-5. (continued) Syntax Result ADC mem1reg,reg add (with carry) register to memory or register ADC memlreg,numb add (with carry) immediate data to memory or register ADD reg,memlreg add memory or register to register ADD memireg,reg add register to memory or register ADD memireg,numb add immediate data to memory or register CBW convert byte in AL to word in AX by sign extension CMP reg,memireg compare memory or register with register CMP memlreg,reg compare register with memory or register CMP memireg,numb compare data constant with memory or register CWD convert word in AX to double word in DX/AX by sign extension DAA decimal adjust for addition, adjusts AL DAS decimal adjust for subtraction, adjusts AL DEC mem1reg subtract 1 from memory or register DIV mem1reg divide (unsigned) accumulator (AX or AL) by memory or register. If byte results, AL = quotient, AH = remainder. If word results, AX quotient, DX = remainder IDIV mem1reg divide (signed) accumulator (AX or AL) by memory or register - quotient and remainder stored as in DIV 4-6 Programmer's Utilities Guide 4.3 Arithmetic Instructions Table 4-5. (continued) Syntax -T Result IMUL mem1reg multiply (signed) memory or register by accumulator (AX or AL). If byte, results in AH, AL. If word, results in DX, AX. INC mem1reg add 1 to memory or register MUL memireg multiply (unsigned) memory or register by accumulator (AX or AL). Results stored as in IMUL. NEG mem1reg two's complement memory or register SBB reg,mem1reg subtract (with borrow) memory or register from register SBB memireg,reg subtract (with borrow) register from memory or register SBB memlreg,numb subtract (with borrow) immediate data from memory or register SUB reg,memlreg subtract memory or register from register SUB mem1reg,reg subtract register from memory or register SUB memlreg,numb subtract data constant from memory or register Table 4-6. Logical and Shift instructions Syntax Result AND reg,memlreg perform bitwise logical AND of a register and memory or register AND memlreg,reg perform bitwise logical AND of memory or register and register AND memlreg,numb perform bitwise logical AND of memory or register and data constant 4-7 Programmer's Utilities Guide 4.3 Arithmetic Instructions Table 4-6. (continued) Syntax Result NOT mem1reg form one Is complement of memory or register OR reg,mem1reg perform bitwise logical OR of a register and memory or register OR mem1reg,reg perform bitwise logical OR of memory or register and register OR memlreg,numb perform bitwise logical OR of memory or register and data constant RCL mem1reg,l rotate memory or register 1 bit left through carry flag RCL mem1reg,CL rotate memory or register left through carry flag, number of bits given by CL register RCR memireg,l rotate memory or register 1 bit right through carry flag RCR memlreg,CL rotate memory or register right through carry flag, number of bits given by CL register ROL memlreg,l rotate memory or register 1 bit left ROL memlreg,CL rotate memory or register left, number of bits given by CL register ROR memlreg,l rotate memory or register 1 bit right ROR memlreg,CL rotate memory or register right, number of bits given by CL register SAL memireg,l shift memory or register 1 bit left, shift in low-order zero bit SAL memlreg,CL shift memory or register left, number of bits given by CL register, shift in low-order zero bits 4-8 Programmer's Utilities Guide 4.3 Arithmetic Instructions Table 4-6. (continued) Syntax Result SAR memireg,l shift memory or register 1 bit right, shift in high-order bit equal to the original high order bit SAR memlreg,CL shift memory or register right, number of bits given by CL register, shift in high-order bits equal to the original high-order bit SHL memlreg,l shift memory or register 1 bit left, shift in low-order zero bit. Note that SHL is a different mnemonic for SAL. SHL memlreg,CL shift memory or register left, number of bits given by CL register, shift in low-order zero bits. Note that SHL is a different mnemonic for SAL. SHR memireg,l shift memory or register 1 bit right, shift in high-order zero bit SHR memlreg,CL shift memory or register right, number of bits given by CL register, shift in high-order zero bits TEST reg,memlreg perform bitwise logical AND of a register and memory or register - set condition flags but do not change destination. TEST memlreg,reg perform bitwise logical AND of memory or register and register - set condition flags, but do not change destination. TEST memlreg,numb perform bitwise logical AND of memory or register and data constant - set condition flags but do not change destination. 4-9 Programmer's Utilities Guide 4.3 Arithmetic Instructions Table 4-6. (continued) Syntax Result XOR reg,memlreg perform bitwise logical exclusive OR of a register and memory or register XOR memireg,reg perform bitwise logical exclusive OR of memory or register and register XOR memireg,numb perform bitwise logical exclusive OR of memory or register and data constant 4.4 String Instructions String instructions take zero, one, or two operands. The operands specify only the operand type, determining whether the operation is on bytes or words. If there are two operands, the source operand is addressed by the SI register and the destination operand is addressed by the DI register. The DI and SI registers are always used for addressing. Note that for string operations, destination operands addressed by DI must always reside in the Extra Segment (ES). The source operand is usually addressed by the DS register. However, you can designate a different register by using a segment override prefix. For example, MOVS WORD PTR[DI],CS:WORD PTR[SI] Table 4-7. String instructions Syntax Result CMPS memlreg,memlreg subtract source from destination, affect flags, but do not return result CMPSB an alternate mnemonic for CMPS that assumes a byte operand CMPSW an alternate mnemonic for CMPS that assumes a word operand LODS memireg transfer a byte or word from the source operand to the accumulator LODSB an alternate mnemonic for LODS that assumes a byte operand 4-10 Programmer's utilities Guide 4.4 String Instructions Table 4-7. (continued) Syntax Result LODSW an alternate mnemonic for LODS that assumes a word operand MOVS memireg,memlreg move 1 byte (or word) from source to destination MOVSB an alternate mnemonic for MOVS that assumes a byte operand MOVSW an alternate mnemonic for MOVS that assumes a word operand SCAS mem1reg subtract destination operand from accumulator (AX or AL) , affect flags, but do not return result SCASB an alternate mnemonic for SCAS that assumes a byte operand SCASW an alternate mnemonic for SCAS that assumes a word operand STOS mem1reg transfer a byte or word from accumulator to the destination operand STOSB an alternate mnemonic for STOS that assumes a byte operand STOSW an alternate mnemonic for STOS that assumes a word operand Table 4-8 defines prefixes for string instructions. A prefix repeats its string instruction the number of times contained in the CX register, which is decremented by 1 for each iteration. Prefix mnemonics precede the string instruction mnemonic in the statement line. 4-11 Programmer's Utilities Guide 4.4 String Instructions Table 4-8. Prefix Instructions Syntax Result REP repeat until CX register is zero REPE repeat until CX register is zero, and zero flag (ZF) is not zero REPNE repeat until CX register is zero, and zero flag (ZF) is zero REPNZ equal to REPNE REPZ equal to REPE 4.5 Control Transfer Instructions There are four classes of control transfer instructions: • calls, jumps, and returns • conditional jumps • iterational control • interrupts All control transfer instructions cause program execution to continue at some new location in memory, possibly in a new cod$ segment. The transfer can be absolute, or it can depend upon a certain condition. Table 4-9 defines control transfer instructions. In the definitions of conditional jumps, above and below refer to the relationship between unsigned values. Greater than and less than refer to the relationship between signed values. 4-12 Programmer's Utilities Guide 4.5 Control Transfer Instructions Table 4-9. Control Transfer Instructions Syntax Result CALL label push the offset address of the next instruction on the stack, jump to the target label CALL memlregl6 push the offset address of the next instruction on the stack, jump to location indicated by contents of specified memory or register CALLF label push CS segment register on the stack, push the offset address of the next instruction on the stack (after CS), jump to the target label CALLF mem push CS register on the stack, push the offset address of the next instruction on the stack, jump to location indicated by contents of specified double word in memory INT numb8 push the flag registers (as in PUSHF), clear TF and IF flags, transfer control with an indirect call through any one of the 256 interupt-vector elements - uses three levels of stack INTO if OF (the overflow flag) is set, push the flag registers (as in PUSHF) , clear TF and IF flags, transfer control with an indirect call through interrupt-vector element 4 (location 10H) . If the OF flag is cleared, no operation takes place IRET transfer control to the return address saved by a previous interrupt operation, restore saved flag registers, as well as CS and IP. Pops three levels of stack 4-13 Programmer's Utilities Guide 4.5 Control Transfer Instructions Table 4-9. (continued) Syntax Result JA lab8 Jump if "not below or equal" or "above" ( (CF or ZF)=O ) JAE lab8 jump if "not below" or "above or equal" ( CF=O ) JB lab8 jump if "below" or "not above or equal" ( CF=l ) JBE lab8 jump if "below or equal" or "not above" ((CF or ZF)=l JC lab8 same as JB JCXZ lab8 jump to target label if CX register is zero JE lab8 jump if "equal" or "zero" ( ZF=l ) JG lab8 jump if "not less or equal" or #.greater" (SF xor OF) or ZF)=O ) JGE lab8 jump if "not less" or "greater or equal" ((SF xor OF)=O ) JL lab8 jump if "less" or "not greater or equal" ((SF xor OF)=1 ) JLE lab8 jump if "less or equal" or "not greater" (SF xor OF) or ZF)=l ) jmp label jump to the target label jmp mem1regl6 jump to location indicated by contents of specified memory or register JMPF label jump to the target label possibly in another code segment JMPS lab8 jump to the target label within +/- 128 bytes from instruction JNA lab8 same as JBE JNAE lab8 same as JB 4-14 Programmer's Utilities Guide 4.5 Control Transfer Instructions Table 4-9. (continued) Syntax Result JNB lab8 same as JAE JNBE lab8 same as JA JNC lab8 same as JNB JNE lab8 jump if "not equal" or "not zero" ( ZF=O JNG lab8 same as JLE JNGE lab8 same as JL JNL lab8 same as JGE JNLE lab8 same as JG JNO lab8 jump if "not overflow" ( OF=O JNP lab8 jump if "not parity" or "parity odd" ( PF=O ) JNS lab8 jump if "not sign" SF=O JNZ lab8 same as JNE JO labB jump if "overflow" OF=l jp lab8 jump if "parity" or "parity even" ( PF=l JPE lab8 same as JP JPO lab8 same as JNP js lab8 jump if "sign" ( SF=l jz lab8 same as JE LOOP lab8 decrement CX register by one, jump to target label if CX is not zero LOOPE lab8 decrement CX register by one, jump to target label if CX is not zero and the ZF flag is set - "loop while zero" or "loop while equal" 4-15 Programmer's Utilities Guide 4.5 Control Transfer Instructions Table 4-9. (continued) Syntax Result LOOPNE lab8 decrement CX register by one, jump to target label if CX is not zero and ZF flag is cleared - "loop while not zero" or "loop while not equal" LOOPNZ lab8 same as LOOPNE LOOPZ lab8 same as LOOPE RET return to the address pushed by a previous CALL instruction, increment stack pointer by 2 RET numb return to the address pushed by a previous CALL, increment stack pointer by 2+numb RETF return to the address pushed by a previous CALLF instruction, increment stack pointer by 4 RETF numb return to the address pushed by a previous CALLF instruction, increment stack pointer by 4 +numb 4.6 Processor Control Instructions Processor control instructions manipulate the flag registers. moreover, some of these instructions synchronize the 8086 CPU with external hardware. Table 4-10. Processor Control Instructions Syntax Results CLC clear CF flag CLD clear DF flag, causing string instructions to auto-increment the operand registers CLI clear IF flag, disabling maskable external interrupts 4-16 Programmer's Utilities Guide 4.6 Processor Control Instructions Table 4-10. (continued) Syntax 7 Results CMC complement CF flag ESC numb8,memireg do no operation other than compute the effective address and place it on the address bus (ESC is used by the 8087 numeric coprocessor.) numb8 must be in the range 0 - 63 HLT cause 8086 processor to enter halt state until an interrupt is recognized LOCK PREFIX instruction, cause the 8086 processor to assert the bus-lock signal for the duration of the operation caused by the following instruction. The LOCK prefix instruction can precede any other instruction. Bus-lock prevents coprocessors from gaining the bus; this is useful for shared-resource semaphores NOP no operation is performed STC set CF flag STD set DF flag, causing string instructions to auto-decrement the operand registers STI set IF flag, enabling maskable external interrupts WAIT cause the 8086 processor to enter a wait state if the signal on its TEST pin is not asserted End of Section 4 4-17 Section 5 Code-macro Facilities 5.1 Introduction to Code-macros RASM-86 does not support traditional assembly language macros, but it does allow you to define your own instructions using the Code-macro directive. RASM-86 assembles code-macros wherever they appear in assembly language code, but there the similarity to traditional macros ends. Traditional assembly-language macros contain assembly-language instructions, but a RASM-86 code-macro contains only code-macro directives. Traditional assembly language macros are usually defined in the Symbol Table; RASM-86 code-macros are defined in the assembler's internal Symbol Table. A traditional macro simplifies the repeated use of the same block of instructions throughout a program, but a code-macro sends a bit stream to the output file, and in effect adds a new instruction to the assembler. RASM-86 treats a code-macro as an instruction, so that you can invoke code-macros by using them as instructions in your program. The following example shows how to invoke MYCODE, an instruction defined by a code-macro. XCHG BX,WORD3 MYCODE PARM1,PARM2 MUL AX,WORD4 Note that MYCODE accepts two operands that are its formal parameters. When you define MYCODE, RASM-86 classifies these two operands as to type, size, etc. The names of formal parameters are not fixed, so RASM-86 replaces them with the names or values supplied as operands when you invoke the code-macro. The formal parameters are placeholders that indicate where and how the operands are to be used. Programmer's Utilities Guide 5.1 Introduction to Code-macros A code-macro definition takes the general form: Code-Macro [] code-macro body EndM where the optional is defined: :[][] If you specify a formal parameter list, the specifier letter is required but the modifier letter is optional. Possible specifiers are A, C, D, E, M, R, S, and X. Possible modifier letters are b, df w, and sb. RASM-86 ignores case except within strings, but for clarity, this section shows specifiers in upper-case and modifiers in lower-case. Following subsections describe specifiers, modifiers, and the optional range in greater detail. The body of the code-macro describes the bit pattern and formal parameters. Only the following directives are legal within code macros: SEGFIX NOSEGFIX MODRM RELB RELW DB DW DD DBIT These directives are unique to code-macros. The code-macro directives DB, DW, and DD that appear to duplicate RASM-86 directives DB, DW, and DD have different meanings in code-macro context. These directives are discussed in detail in Section 5.5.5. CodeMacro, EndM, and the code-macro directives are all reserved words. The formal definition syntax for a code-macro is defined in Backus-Naur-like form in Appendix D. The following examples are typical code-macro definitions. CodeMacro AAA DB 37H EndM Codemacro DIV divisor:Eb SEGFIX divisor DB 6FH MODRM divisor EndM 5-2 Programmer's Utilities Guide 5.1 Introduction to Code-macros CodeMacro ESC opcode:Db(0,63),src:Eb SEGFIX src DBIT 5(lBH),3(opcode(3)) MODRM opcode,src EndM 5.2 Specifiers Every formal parameter must have a specifier letter that indicates what type of operand is needed to match the formal parameter. Table 5-1 defines the eight possible specifier letters. Table 5-1. Code-macro Operand Specifiers Letter T Operand Type A Accumulator register, AX or AL. C Code, a label expression only. D Data, a number used as an immediate value. E Effective address, either an M (memory address) or an R (register). M Memory address. This can be either a variable or a bracketed register expression. R A general register only. S Segment register only. X A direct memory reference. 5.3 Modifiers The optional modifier letter is a further requirement on the operand. The meaning of the modifier letter depends on the type of the operand. For variables, the modifier requires the operand to be of type b for byte, w for word, d for double-word, and sb for signed byte. For numbers, the modifiers require the number to be of a certain size: b for -256 to 255 and w for other numbers. Table 5-2 summarizes code-macro modifiers. 5-3 Programmer's Utilities Guide 5.3 Modifiers Table 5-2. Code-macro Operand Modifiers Variables Numbers Modifier Type Modifier Size b byte b -256 to 255 w word w anything else d dword sb signed byte 5.4 Range Specifiers The optional range is specified within parentheses by either one expression or two expressions separated by a comma. The following are valid formats: (numberb) (register) (numberb,numberb) (numberb, register) (register,numberb) (register,register) Numberb is an 8-bit number, not an address. The following example specifies that the input port must be identified by the DX register: CodeMacro IN dst:Aw,port:Rw(DX) The next example specifies that the CL register is to'contain the count of rotation: CodeMacro ROR dst:Ew,count:Rb(CL) The last example specifies that the opcode is to be immediate data, and can range from 0 to 63 inclusive: CodeMacro ESC opcode:Db(0,63),adds:Eb 5.5 Code-macro Directives Code-macro directives define the bit pattern and make further requirements on how the operand is to be treated. Directives are reserved words, and those that appear to duplicate assembly language instructions have different meanings within a code-macro definition. only the nine directives defined here are legal within code-macro definitions. 5-4 Programmer's Utilities Guide 5.5 Code-macro Directives 5.5.1 SEGFIX SEGFIX instructs RASM-86 to determine whether a segment override prefix byte is needed to access a given memory location. If so, it is output as the first byte of the instruction. If not, RASM-86 takes no action. SEGFIX has the form: SEGFIX where is the name of a formal parameter that represents the memory address. Because it represents a memory address, the formal parameter must have one of the specifiers E, M, or X. 5.5.2 NOSEGFIX Use NOSEGFIX for operands in instructions that must use the ES register for that operand. This applies only to the destination operand of these instructions: CMPS, MOVS, SCAS, STOS. NOSEGFIX has the form: NOSEGFIX segreg, where segreg is one of the segment registers ES, CS, SS, or DS, and is the name of the memory-address formal parameter that must have a specifier E, M, or X. No code is generated from this directive, but an error check is performed. The following is an example of NOSEGFIX use: CodeMacro MOVS si_ptr:Ew,di_ptr:Ew NOSEGFIX ES,di_ptr SEGFIX si_ptr DB OA5H EndM 5.5.3 MODRK This directive instructs RASM-86 to generate the MODRM byte that follows the opcode byte in many of the 8086's instructions. The MODRM byte contains either the indexing type or the register number to be used in the instruction. It also specifies which register is to be used, or gives more information to specify an instruction. The MODRM byte carries the information in three fields. The mod field occupies the two most significant bits of the byte, and combines with the register memory field to form 32 possible values: 8 registers and 24 indexing modes. The reg field occupies the three next bits following the mod field. It specifies either a register number or three more bits of opcode information. The meaning of the reg field is determined by the opcode byte. 5-5 I Programmer's Utilities Guide 5.5 Code-macro Directives The register memory field occupies the last three bits of the byte. It specifies a register as the location of an operand, or forms a part of the address-mode in combination with the mod field described above. For further information about the 8086's instructions and their bit patterns, see the Intel 8086 Assembly Language Programming Manual and the Intel 8086 Family User's Manual. MODRM has the forms: MODRM
, MODRM NUMBER7, where NUMBER7 is a value 0 to 7 inclusive, and is the name of a formal parameter. The following examples show how to use MODRM: CodeMacro RCR dst:Ew,count:Rb(CL) SEGFIX dst DB OD3H MODRM 3,dst EndM CodeMacro OR dst:Rw,src:Ew SEGFIX src DB OBH MODRM dst,src EndM 5.5.4 RELB and RELW These directives, used in IP-relative branch instructions, instruct RASM-86 to generate a displacement between the end of the instruction and the label that is supplied as an operand. RELB generates one byte and RELW two bytes of displacement. The directives have the following forms: RELB RELW where is the name of a formal parameter with a C (code) specifier. For example, CodeMacro LOOP place:Cb DB OE2H RELB place EndM 5-6 Programmer's Utilities Guide 5.5 Code-macro Directives 5.5.5 DB, DW, and DD These directives differ from those that occur outside code macros. The directives have the following forms: DB NUMBERB DW NUMBERW DD where NUMBERB is a single-byte number; NUMBERW is a two-byte number, and is a name of a formal parameter. For example, CodeMacro XOR dst:Ew,src:Db SEGFIX dst DB 81H MODRM 6,dst DW src EndM 5.5.6 DBIT This directive manipulates bits in combinations of a byte or less. The form is DBIT [,] where a , has two forms: (()) where ranges from 1 to 16, and specifies the number of bits to be set. specifies the desired bit combination. The total of all the s listed in the field descriptions must not exceed 16. The second form shown above contains , a formal parameter name that instructs the assembler to put a certain number in the specified position. This number normally refers to the register specified in the first line of the code-macro. The numbers used in this special case for each register are: AL: 0 CL: 1 DL: 2 BL: 3 AH: 4 CH: 5 DH: 6 BH: 7 AX: 0 CX: 1 DX: 2 5-7 Programmer's Utilities Guide 5.5 Code-macro Directives BX: 3 SP: 4 BP: 5 SI: 6 DI: 7 ES: 0 CS: 1 SS: 2 DS: 3 , which is contained in the innermost parentheses, specifies a number of right shifts. For example, 0 specifies no shift;l shifts right one bit; 2 shifts right two bits, and so on. The definition below uses this form. CodeMacro DEC dst:Rw DBIT 5(9H),3(dst(O)) EndM The first five bits of the byte have the value 9H. If the remaining bits are zero, the hex value of the byte is 48H. If the instruction DEC DX is assembled, and DX has a value of 2H, then 48H + 2H = 4AH, which is the final value of the byte for execution. If this sequence is present in the definition DBIT 5(9H),3(dst(l)) then the register number is shifted right once, and the result is 48H + 1H = 49H, which is erroneous. End of Section 5 5-8 Section 6 XREF-86 6.1 Introduction XREF-86 is an assembly language cross-reference utility program that creates a cross-reference file showing the use of symbols throughout the program. XREF-86 accepts two input files created by RASM-86. XREF-86 assumes these input files have the filetypes of LST and SYM respectively, and they both reside on the same disk drive. XREF-86 creates one output file with the filetype XRF. Figure 6-1 illustrates XREF-86 operation. FILENAME LST ST LISTING FILE XREF-86 FILE NAME XRF FILENAME.SYM CROSS-REFERENCE FILE SYMBOL TABLE FILE Figure 6-1. XREF-86 Operation 6.2 invoking XREF-86 Invoke XREF-86 with the command form: XREF86 XREF-86 reads .LST line by line, attaches a line number prefix to each line, and writes each prefixed line to the output file, .XRF. During this process, XREF-86 scans each line for any symbols that exist in the file .SYM. After completing this copy operation, XREF-86 appends to .XRF a cross-reference report that lists all the line numbers where each symbol in .SYM appears. XREF-86 flags with a # character each line number reference where the referenced symbol is the first token on the line. 6-1 Programmer's Utilities Guide 6.2 Invoking XREF-86 XREF-86 also lists the value of each symbol, as determined by RASM-86 and placed in the Symbol Table file, .SYM. When you invoke XREF-86, you can include an optional drive specification with the filename. When you invoke XREF-86 with a drivename preceding the , it searches for the input files and creates the output file on the specified drive. Otherwise, XREF-86 associates the files with the default drive. XREF-86 also allows you to direct the output file to the default list device instead of to .XRF. To redirect the output, add the string $p to the command line. For example, A>xref86 bios $p End of Section 6 6-2 Section 7 LINK-86 7.1 Introduction LINK-86 is the Digital Research linkage editor that combines relocatable object files into a file that runs under DOS. The object files can be produced by Digital Research's 8086 language translators such as RASM-86, PL/I-86 TM . and CB86 TM I or by other translators that produce object files using a compatible subset of the Intel 8086 object module format. LINK-86 accepts two types of object files. The first type is an object file containing a single object module. This type generally has the filetype OBJ, and is produced by a language translator. The second type is a library file which is an indexed library of object modules. A library file has a filetype L86, and is generated by the library manager, LIB-86, in the Intel 8086 object module format. LINK-86 can search such a library file and select only those modules needed by the other programs being linked. LINK-86 produces three files: * A Run (EXE) File * A Symbol Table (SYM) File * A Map (MAP) File The EXE file contains a memory image of the program that runs directly under DOS. The SYM file contains a list of symbols from the object files, and their offsets, and is suitable for use with a symbolic instruction debugger. The MAP file contains information about the layout of the EXE file. LINK-86 displays any unresolved symbols at the console. Unresolved symbols are those that have been referenced but not defined in the files being linked. These symbols must be resolved before the program will run properly. Upon completion of processing, LINK-86 displays the size of each of the sections of the EXE f ile, and the Use Factor, which is a decimal percentage indicating the amount of available memory used by LINK-86. Figure 7-1 illustrates LINK-86 operation. 7-1 Programmer's Utilities Guide 7.1 Introduction OBJ 1 (OBJECT FILE) . EXE (RUN FILE) OBJ n (OBJECT FILE) OR OVR (OVERLAY FILE) L86 1 (LIBRARY FILE) . LINK-86 SYM . (SYMBOL TABLE FILE) L86 n (LIBRARY FILE) INP MAP (MAP FILE) (INPUT COMMAND FILE) Figure 7-1. LINK-86 Operation 7.2 Invoking LINK-86 You invoke LINK-86 with a command of the form: LINK86 afile = file1,file2,...,filen If you enter a filename to the left of the equal sign, LINK-86 creates the output files with that name and the appropriate filetypes. For example, the command A>Link86 myfile = parta,partb,partc creates MYFILE.EXE and MYFILE.SYM. If you omit the new filename, LINK-86 creates the output files using the first filename in the command line. For example, the command A>link86 parta,partb,partc creates the files PARTA.EXE and PARTA.SYM. 7-2 Programmer's Utilities Guide 7.2 Invoking LINK-86 You can also instruct LINK-86 to read its command line from a file, thus making it possible to store long or commonly used link commands on the disk (see Section 7.10). 7.3 Definitions This section uses the following terms to describe how LINK-86 processes object files and creates the EXE file. Table 7-1. LINK-86 Definitions Term Description Segment A Segment is a collection of code or data bytes whose length is less than 64K. A segment is the smallest unit that LINK-86 manipulates when creating the EXE file. Segment name* A Segment name can be any valid RASM-86 identifier. LINK-86 combines all segments with the same segment name from separate object files. Class name* A Class name can be any valid RASM-86 identifier. LINK-86 uses the class name to position the segment in the correct section of the run file. * The indicates on what type of boundary the segment is to begin. The Align types are byte, word, and paragraph. LINK-86 uses the align type in two ways: first, when it combines parts of segments from separate files, and second, when it combines segments into groups or sections of the EXE file. * The determines how LINK 86 can combine parts of segments with the same name from different files. The Combine types are: public and common. Section A section is one of up to four logical parts of an EXE file. A section can be any length but the total length of all sections must be less than or equal to one megabyte. Programmer's Utilities Guide 7.3 Definitions Table 7-1. (continued) Term Description Group* A Group is a collection of segments whose total length is less than 64K, and thus is addressable from a single segment register. Groups allow you to break up a program into segments, while still allowing the segments to be addressed without changing the contents of a segment register. This technique results in shorter and faster code than addressing segments with 32-bit pointers. If you program in a high-level language, the compiler automatically assigns the Segment name, Class name, Group, Align type, and Combine type. If you program in assembly language, refer to Section 3 for a description of how to assign these attributes. 7.4 The Link Process The link process involves two distinct phases: collecting the segments in the object files, and then positioning them in the EXE file. 7.4.1 Phase I - Collection In Phase 1, LINK-86 first collects segments having the same Segment name and Class name from the separate files being linked, and then combines the segments according to the align and combine attributes. For example, suppose there are three object files, FILEA.OBJ, FILEB.OBJ, and FILEC.OBJ, and each file defines a segment named Dataseg with the statement: dataseg dseg Figure 7-2 illustrates how LINK-86 combines this segment using the Public Combine type. DATASEG(C) DATASEG(B) 450H DATASEG(A) I Figure 7-2. Combining Segments with the Public Combine Type 7-4 Programmer's Utilities Guide 7.4 The Link Process LINK-86 combines these segments by concatenating the parts of the segments found in the separate object files with the appropriate space between the parts indicated by the Align type (see below) . Public is the most common Combine type, and RASM-86, as well as most high-level language compilers, produces it as a default. Figure 7-3 illustrates the Common Combine type. Suppose the three files FILEA.OBJ, FILEB.OBJ, and FILEC.OBJ each contain a segment named Dataseg defined with the statement: dataseg dseg common LINK-86 combines these segments so that all parts of the segments from the separate files being linked have the same low address in memory. Note that this corresponds to a common block in high-level languages. DATASEG (A, B, C) 200H Figure 7-3. Combining Segments with the Common Combine Type The Align type indicates on what type of boundary the segment begins, and thus determines the amount of space LINK-86 leaves between parts of segments of the same name. For example, suppose the three files FILEA.OBJ, FILEB.OBJ, and FILEC.OBJ each contain a segment named Dataseg. Figure 7-4 illustrates how LINK-86 uses the Align type to combine these segments. 7-5 Programmer's Utilities Guide 7.4 The Link Process DATASEG(C) 0-15 .......... BYTES DATASEG(B) 0-15 BYTES DATASEG(A) Figure 7-4. Combining Segments using the Align Type In Figure 7-4, the gap between the segments is determined by the Align type, and can be up to 15 bytes in length. For example, there is no gap if the Align type is byte. This produces the most compact code. If the Align type is word, LINK-86 adds a one-byte gap, if necessary, to ensure that the next part of the segment begins on a word boundary. Word is the default Align type for Data segments, since the 8086 processor performs faster memory accesses for word aligned data. The gap required for paragraph-aligned segments can be up to 15 bytes. Figure 7-5 illustrates a specific example. Suppose the segment Dataseg has the paragraph Align type. Suppose also that Dataseg has a length of 129H in FILEA, 10EH in FILEB, and 13AH in FILEC. As shown, LINK-86 combines the segments to ensure that each segment begins on a paragraph boundary. 7-6 Programmer's Utilities Guide 7.4 The Link Process 379H DATASEG(C) 40H 2 BYTES ;e~jutl DATASEG(B) 1 0 Figure 7-5. Paragraph Alignment 7.4.2 Phase 2 - Positioning In Phase 2, LINK-86 combines segments that are members of groups, again using the Align type to determine intersegment gaps. Figure 7-6 illustrates how LINK-86 combines segments into groups. I--- Programmer's Utilities Guide 7.4 The Link Process N+45:0FFFFH N:0FFFFH DATASEG3 (200H) VAR: 50H DATASEG3 VAR: 500H N+45:0 N:450 N+10:34F N:44F DATASEG2 (350H) DATASEG2 N+10:0 N:100 DATASEG1 (100H) N:FF DATASEG1 N:FF N:0 N:0 7-6a.Segments Without Groups 7-6b. Segments Within A Group Figure 7-6. The Effect of Grouping Segments In Figure 7-6, N:0 is the base address where the segments are loaded at run-time (paragraph N, offset 0) . Figure 7-6a shows that each segment not contained in a group begins at offset zero, and thus can be up to 64K long. The offset of any given location, in this case the variable VAR, is relative to the base of the segment. Thus, in order to access the variable, VAR, at run-time, the program must load a segment register with the base of the segment Dataseg3 because LINK-86 assigns VAR an offset of 50H. In Figure 7-6b, the same Segments are combined in a group. The offsets of the segments are now cumulative and thus cannot extend past FFFFH. The offset of VAR is 500H relative to the base of the group. At run-time, the program does not need to change a segment register to point to Dataseg3, but can access VAR directly using the segment register that points to the base of the group. After combining segments into groups, LINK-86 assigns each segment to one of up to four logical sections of the EXE file as follows: 1) Segments belonging to the group CGROUP are placed in the CODE section of the EXE file. 7-8 Programmer's Utilities Guide 7.4 The Link Process 2) Segments belonging to the group DGROUP are placed in the DATA section of the EXE file. Note that the group names CGROUP and DGROUP are automatically generated by PL/1-86, CB86, and other high-level language compilers. 3) If there are any segments that have not been processed according to (1) and (2), LINK-86 places them in the EXE file according to their class name, as shown in Table 7-1. This table also shows the RASM-86 segment directives that produce the class names as defaults. 4) Segments that have not been processed by any of the above means are omitted from the EXE file because LINK-86 does not have sufficient information to position them. You can override the way LINK-86 positions segments by using command line options, as described in Section 7.7. Table 7-2. LINK-86 Usage of Class Names Class Name EXE File Section Segment Directive (RASM-86) CODE CODE CSEG DATA DATA DSEG EXTRA EXTRA ESEG STACK STACK SSEG 7.5 LINK-86 Command options When you invoke LINK-86, you can specify command line options that control the link operation. Each command option falls into one of several categories, depending on the type of file it affects. The first category of command options affects the contents of the EXE file, and therefore applies to the entire link operation. The second category of options affects the SYM and MAP files. These options act as toggles that turn on and off as LINK-86 processes the command line from left to right. The third category of options affects the Library and Input files, and therefore applies only to one file in the command line. Table 7-3 shows the LINK-86 command options including the abbreviation for each. 7-9 Programmer's Utilities Guide 7.5 LINK-86 Command Options Table 7-3. LINK-86 Comand Options Option Abbr meaning CODE C controls contents of CODE section of EXE file DATA D controls contents of DATA section of EXE file EXTRA E controls contents of EXTRA section of EXE file STACK ST controls contents of STACK section of EXE file FILL F zero fill an include uninitialized data in EXE file NOFILL NOF do not include uninitialized data in EXE file NOPREFIX NOP do not generate prefix code at beginning of EXE file INPUT I read command line from disk file MAP M create a MAP file LIBSYMS LI include symbols from library files in SYM file NOLIBSYMS NOLI do not include symbols from library files in SYM file LOCALS LO include local symbols in SYM file NOLOCALS NOLO do not include local symbols in SYM file SEARCH S search library and only link modules referenced You enclose command options in square brackets immediately following a filename. For example, A>link86 test1 [map], test2 [nolocals] You can use spaces to improve the readability of the command line, and you can put more than one option in square brackets by separating them with commas. For example, A>link86 test1 [map, nolocals], test2 [locals] The following subsections describe the function and syntax for each of the command options. 7-10 Programmer's Utilities Guide 7.6 EXE File Options 7.6 EXE File Options The following command options affect the contents of the EXE file that LINK-86 creates: CODE DATA STACK EXTRA FILL NOFILL NOPREFIX Note that these options can appear after any filename in the command line. The first four options control the way LINK-86 places segments in the EXE file, and the contents of the EXE file header. The FILL and NOFILL options tell LINK-86 what to do with uninitialized data that can occur at the end of a section of the EXE file. When you link object modules created by a Digital Research compiler such as CB86, or PL/1-86, the linkage editor generates some prefix code at the beginning of the EXE file. If you are linking RASM-86 modules only, you can use the NOPREFIX option and cause LINK-86 to suppress generation of this prefix code. Each of the options that affect the EXE file sections must be followed by one or more parameters enclosed in square brackets. Table 7-4 shows the parameters, their abbreviations, and meanings. Table 7-4. EXE File Option Parameters Parameter Abbr] Meaning ADDITIONAL AD additional memory allocation for the EXE file section MAXIMUM M maximum memory allocation for EXE file section 7.6.1 ADDITIONAL, MAXIMUM The ADDITIONAL and MAXIMUM parameters tell LINK-86 the values to place in the EXE file header. These parameters override the default values that LINK-86 usually uses. Each parameter is a hexadecimal number enclosed in square brackets. Table 7-5 shows the default values. I Programmer's Utilities Guide 7.6 EXE File Options The ADDITIONAL parameter indicates the amount of additional memory, in paragraphs, required by the indicated section of the EXE file. The program could use this memory for Symbol Table space or 1/0 buffers that are needed at run-time, but are not included in the source program, and thus are not in the OBJ file. The MAXIMUM parameter indicates the maximum amount of memory needed by the indicated section of the EXE file. For example, the command A>Iink86 test [data [add [100],max [1000]]] creates the file TEST.EXE whose header contains the following information: • The DATA section requires at least 100H paragraphs in addition to the data in the EXE file. • The DATA section can use up to 1000H paragraphs of memory. Table 7-5 summarizes the default values for each of the command options and parameters. Table 7-5. Default Values for EXE File Options and Parameters OPTION GROUP CLASS SEGMENT ADDITIONAL MAXIMUM ORIGIN CODE CGROUP CODE CODE 0 0 0 DATA DGROUP DATA DATA 0 1000H* 100H STACK - STACK STACK 0 0 0 EXTRA - EXTRA EXTRA 0 0 0 *If there is a DGROUP; otherwise 0. 7.6.2 FILL/NOFILL The FILL and NOFILL options tell LINK-86 what to do with uninitialized data that can occur at the end of a section of the EXE file. The FILL option directs LINK-86 to include this uninitialized data in the EXE file, and fill it with zeros. The NOFILL option directs LINK-86 to omit the uninitialized data from the EXE file. The FILL option usually results in a larger EXE file, but the LINK-86 operation is usually faster when FILL is enabled. The default is FILL. Note that these options apply only to uninitialized data at the end of a section of the EXE file. Uninitialized data which is not at the end of a section is always zero filled and included in the EXE file. Programmer's Utilities Guide 7.7 SYM File Options 7.7 SYM File Options The following command options affect the contents of the SYM file that LINK-86 creates: LOCALS LIBSYMS NOLOCALS NOLIBSYMS These options must appear in the command line after the specific file or files to which they apply. These options remain in effect until you change them, as LINK-86 processes the command line from left to right. 7.7.1 LOCALS/NOLOCALS The LOCALS option directs LINK-86 to include local symbols in the SYM file if they are present in the object files being linked. The NOLOCALS option directs LINK-86 to ignore local symbols in the object files. The default option is LOCALS. For example, the command A>link86 testl [nolocals], test2 [locals], test3 creates a SYM file containing local symbols from TEST2.OBJ and TEST3.OBJ, but not from TEST1.OBJ. 7.7.2 LIBSYKS/NOLIBSYNS The LIBSYMS option directs LINK-86 to include in the SYM file any symbols that come from a library that is searched during the link operation. The NOLIBSYMS option directs LINK-86 not to include those symbols in the SYM file. Typically, such a library search involves the Run-time Subroutine Library of a high-level language such as PL/1-86. Because the symbols in such a library are usually of no interest to the programmer, the default is NOLIBSYMS. 7.8 MAP File Options The MAP option directs LINK-86 to create a MAP file that contains information about the segments in the EXE file. The amount of information that LINK-86 puts into the MAP file is controlled by the optional parameters: OBJMAP NOOBJMAP L86MAP NOL86MAP ALL that are enclosed in brackets following the MAP option. The OBJMAP parameter directs LINK-86 to put segment information about OBJ files into the MAP file. The NOOBJMAP parameter suppresses this 7-13 Programmer's Utilities Guide 7.8 MAP File Options information. Similarly, the L86MAP switch directs LINK-86 to put segment information from L86 files into the MAP file. The NOL86MAP parameter suppresses this information. The ALL parameter directs LINK-86 to put all the information into the MAP file. Once you instruct LINK-86 to create a MAP file, you can change the parameters to the MAP option at different points in the command line. For example, A>LINK86 FINANCE [MAP[ALL]],SCREEN,GRAPH.L86[S,MAP[NOL86MAP]] If you specify the MAP option with no parameters, LINK-86 uses OBJMAP and NOL86MAP as defaults. 7.9 L86 File Options The SEARCH option directs LINK-86 to search the preceding file and include in the EXE file only those modules which satisfy external references from other modules. Note that LINK-86 does not search L86 files automatically. If you do not use the SEARCH option after a library file name, LINK-86 includes all the modules in the library file when creating the EXE file. For example, the command A>link86 test1, test2, math.l86 [search] creates the file TEST1.EXE by combining the object files TEST1.OBJ, TEST2.OBJ, and any modules from MATH.L86 that: are referenced in TEST1.OBJ or TEST2.OBJ. The modules in the library file do not have to be in any special order. LINK-86 makes multiple passes through the library index when attempting to resolve references from other modules. 7.10 Input File Options The INPUT option directs LINK-86 to obtain further command line input from the indicated file. Other files can appear in the command line before the input file, but the input file must be the last filename on the command line. LINK-86 stops scanning the command line, entered from the console, when it encounters this option. Note that you cannot nest command input files. That is, a command input file cannot contain the input option. The input file consists of filenames and options just like a command line entered from the console. For example, the file TEST.INP might include the lines MEMTEST=TEST1,TEST2,TEST3, IOLIB.L86[S],MATH.L82[S], TEST4,TEST5[LOCALS] 7-14 Programmer's Utilities Guide 7.10 Command Input File Options To direct LINK-86 to use this file for input, enter the command A>LINK86 TEST[INPUT] If no file type is specified for an input file, LINK-86 assumes INP. 7.11 1/0 Options The $ option controls the source and destination devices under LINK-86. The general form of the $ option is $td where t is a type and d is a drive specifier. LINK-86 recognizes five types: • C - Command File (EXE or OVR) • L - Library File (L86) • M - Map File (MAP) • O - Object File (OBJ or L86) • S - Symbol File (SYM) The drive specifier can be a letter in the range A thru P corresponding to one of sixteen logical drives, or one of the following special characters: • X - Console • Y - Printer • Z - Byte bucket When you use the $ option, you cannot separate the td character pair with commas. However, you must use a comma to set off any $ options from other options. For example, the three command lines shown below are equivalent: A>Iink86 part1[$sz,$od,$lb],part2 A>link86 part1[$szodlb],part2 A>link86 part1[$sz od lb],part2 The value of a $ option remains in effect until it is changed as LINK-86 processes the command line from left to right. 7-15 Programmer's Utilities Guide 7.11 1/0 Options 7.11.1 $Cd - Command LINK-86 usually generates the EXE file on the same drive as the first object file in the command line. The $C option instructs LINK-86 to place the EXE file on the drive specified by the character following the $C, or to suppress the generation of a command file if you specify $CZ. 7.11.2 $Ld - Library LINK-86 usually searches on the default drive for Run-time Subroutine Libraries that are linked autornatically. The $L option directs LINK-86 to search the specified drive for these library files. 7.11.3 $Md - Map LINK-86 usually generates the Map file on the same drive as the EXE file. The $M option instructs LINK-86 to place the Map file on the drive specified by the character following the $M. Specify $MX to send the Map file to the console. 7.11.4 $Od - Object LINK-86 usually searches for the OBJ or L86 files that you specify in the command line on the default drive, unless such files have explicit drive prefixes. The $O option allows you to specify the drive location of multiple OBJ or L86 files without adding an explicit drive prefix to each filename. For example, the command A>Iink86 pf$odl,q,r,s,t,u.186,b:v tells LINK-86 that all the object files except the last one are located on drive D. Note that this does not apply to files that are searched automatically (see Section 7.11.2). 7.11.5 $Sd - Symbol LINK-86 usually generates a Symbol file on the same drive as the EXE file. The $S option directs LINK-86 to place the Symbol file on the drive specified by the character following the $S, or to suppress the generation of a symbol file if you specify $SZ. 7-16 Programmer's Utilities Guide 7.12 Command Line Errors 7.12 Command Line Errors If LINK-86 detects any kind of command line error, it prints the message SYNTAX ERROR echoes the command tail up to the point where the error occurs, and follows it with a question mark. For example, A>Iink86 a, b, c; d SYNTAX ERROR A, B, C;? A>Iink86 longfilename SYNTAX ERROR LONGFILEN? End of Section 7 1~ 7-17 I lol%. I Section 8 LIB-86 LIB-86 is a utility program for creating and maintaining library files that contain 8086 object modules. These modules can be produced by Digital Research's 8086 language translators such as RASM-86, PL/1-86, and CB86, or by any other translators that produce modules in Intel's 8086 object module format. You can use LIB-86 to create libraries, as well as append, replace, select, or delete modules from an existing library. You can also use LIB-86 to obtain information about the contents of library files. 8.1 LIB-86 Operation When you invoke LIB-86, it reads the indicated files and produces a Library file, a Cross-reference file, or a Module map file as indicated by the command line. When LIB-86 finishes processing, it displays the Use Factor, which is a decimal number indicating the percent of the available memory that LIB-86 used during processing. Figure 8-1 shows the operation of LIB-86. OBJ 1 (OBJECT FILE) . OBJ n (OBJECT FILE) L86 (LIBRARY FILE) L86 1 (LIBRARY FILE) . . LIB-86 MAP (MODULE MAP FILE) . L86 n (LIBRARY FILE) XRF (CROSS-REFERENCE FILE) Figure 8-1. LIB-86 Operation 8-1 Programmer's Utilities Guide 8.1 LIB-86 operation Table 8-1 shows the filetypes that LIB-86 recognizes. Table 8-1. LIB-86 Filetypes Type Usage INP Input Command File L86 Library File MAP Module Map File OBJ object File XRF Cross-reference File 8.2 LIB-86 Command options When you invoke LIB-86, you can specify optional parameters in the command line that control the operation. Table 8-2 shows the LIB-86 command options. You can abbreviate each option keyword by truncating on the right, as long as you include anough characters to prevent ambiguity. Thus, EXTERNALS can be abbreviated EXTERN, EXT, EX, or simply E. The following sub-sections dE~scribe the function of each command option. Table 8-2. LIB-86 Command Line Options Option Purpose I Abbreviation DELETE Delete a Module from a Library file D EXTERNALS Show EXTERNALS in a Library file E INPUT Read commands from Input file I MAP Create a Module Map MA MODULES Show Modules in a Library file MO NOALPHA Show Modules in order of occurrence N PUBLICS Show PUBLICS in a Library file P REPLACE Replace a Module in a Library file R SEGMENTS Show Segments in a Module SEG SELECT Select a Module from a Library file SEL XREF Create a Cross-reference file X 8-2 Programmer's Utilities Guide 8.3 Creating/Updating Libraries 8-3 Creating and Updating Libraries You can create or update libraries using a command line of the general form: LIB86 = [options], , .... LIB-86 creates a Library file with the filename given by . If you omit the filetype, LIB-86 creates the Library file with filetype L86. LIB-86 reads the files specified by through and produces the library file. If through do not have a specified filetype, LIB-86 assumes a default filetype of OBJ. The files to be included can contain one or more modules; that is, they can be OBJ or L86 files, or a combination of the two. Modules in a library need not be in any particular order, because LINK-86 searches the library as many times as necessary to resolve references. However, LINK-86 runs much faster if the order of modules in the library is optimized. To do this, remove as many backward references as possible (modules which reference public symbols that are declared in earlier modules in the library) so that LINK-86 can search the library in a single pass. Module names are assigned by language translators. The method for assigning module names varies from translator to translator, but is generally either the filename or the name of the main procedure. 8.3.1 Creating a New Library To create a new library, enter the name of the library, then an equal sign followed by the list of the files you want to include, separated by commas. For example, A>Iib86 newlib = a,b,c A>lib86 newlib.l86 = a.obj,b.obj,c.obj A>Iib86 math = add,sub,mul,div The first two examples are equivalent. 8.3.2 Adding to a Library To add a module or modules to an existing library, specify the library name on both sides of the equal sign in the command line. The library name appears on the left of the equal sign as the name of the library you are creating. The name also appears on the right of the equal sign, with the names of the other file or files to be appended. For example, 8-3 Programmer's Utilities Guide 8.3 Creating/Updating Libraries A>lib86 math = math.l86,sin,cos,tan A>lib86 math = sqrt,math.l86 8.3.3 Replacing a Module LIB-86 allows you to replace one or more modules without rebuilding the entire library from the individual