Please consider a donation to the Higher Intellect project. See or the Donate to Higher Intellect page for more info.

X86 Assembly Language FAQ

From Higher Intellect Vintage Wiki
Jump to navigation Jump to search
Subject: 1. Introduction and Intent

This is the x86 Assembly Language FAQ for the comp.lang.asm.x86 and
alt.lang.asm newsgroups.  This FAQ is posted monthly on or about the 21st
of the month on both newsgroups and news.answers, alt.answers and
comp.answers.  It also is archived at the normal FAQ archival sites and the
SimTel mirror sites in the msdos/info directory.  Lastly, the current
version is available from my web page as:
Currently, this FAQ is broken into six sections.  The following are the
section filenames and the scope of each section of the FAQ.

assembly-language/x86/general/part1 - This is the basic portion of the FAQ
    that contains information of interest to all assembly language
    programmers.  In general, the information contained in this portion of
    the FAQ is not specific to any particular assembler.

assembly-language/x86/general/part2 - This is a continuation of the above

assembly-language/x86/general/part3 - This is a continuation of the above

assembly-language/x86/microsoft - This portion of the FAQ contains
    information specific for the Microsoft MASM.

assembly-language/x86/borland - This portion of the FAQ contains
    information specific for the Borland TASM.

assembly-language/x86/a86 - This portion of the FAQ contains information
    specific for the Shareware A86 Assembler and D86 Debugger.

The scope and content of this FAQ is to go beyond just answering the
frequently asked questions.  I am including pointers to assembly language
treasure troves that are hidden out on the internet.  I believe that this
will enhance the FAQ's value not only to the novices but also to the old

Any subject listed as "OPEN" means that this topic as been requested but no
one has come forth and volunteered to write this section.  Volunteers
please indicate your intentions to the author listed below either by
posting to either newsgroup or by sending e-mail to the author at the below

The general guidelines for submission are:
 *  accuracy and conciseness;
 *  pointers to where on the internet more detailed information is
    available; and
 *  any code submitted will be generic so that most assemblers can assemble

Any subject listed as "UNDER CONSTRUCTION" has a volunteer currently
writing that subject.  If you desire to assist or have some information
that you believe would be of help in writing that particular subject,
contact the contributor of that subject or post to both newsgroups.  Once a
subject is submitted to me, I will post it on both newsgroups for comment. 
After any changes that may be necessary are made, I will include it in the
next posting of the FAQ.

For the ease of determining what has changed since the last FAQ, the Table
of Contents will have "REVISED" at the end of the subject line for all
revised subjects.  If more than one FAQ revision has been missed, the "Last
Changed:" entry at the end of each subject can be used to determine which
subjects have been revised during the intervening time frame.

The information in this FAQ is free for all to use as long as you
acknowledge the source.  This FAQ can be reproduced in part or in its
entirety as long as the copyright is included.  This FAQ can be made
available on public servers, like ftp, gopher or WWW servers.  Please do
not modify the file, such as converting it into some other format, without
prior permission of the author.

All references to files and locations are in Uniform Resource Locators
(URLs) format.  Some web browser will be able to use these URLs directly as
hot links.  If the format is not clear to you, get RFC 1738.  It is
available from: 

Suggestions for changes and comments are always welcome.  They can be
posted to either newsgroup or e-mailed directly to the me.

Author: Raymond Moon, [email protected]
Copyright 1996 - Raymond Moon
Last Changed: 17 Feb 96


Subject: 2. Table of Contents

Part I

1.  Introduction and Intent
2.  Table of Contents                                   REVISED
3.  Charters For comp.lang.asm.x86 and alt.lang.asm Newsgroups
4.  What is Assembly Language
5.  List of x86 OpCodes
6.  What is HELPPC and Where It Is Available
7.  How To Truncate a File
8.  How Can STDERR Be Redirected To a File
9.  How To Determine the CPU Type
10. IRQ Assignments
11. Ralf Brown's Interrupt List
12. Using VGA Mode 13h for Fast Graphics
13. Real Mode/Protected Mode
14. Shareware ASM Libraries

Part II

15. How To Determine If a Problem Pentium Is Present
16. Accessing 4 Gegs of Memory in Real Mode
17. Interrupts and Exceptions
18. What Is Available at
19. ASM Books Available
20. ASM Code Available on Internet
21. How To Commit a File
22. Using Extended Memory Manager
23. EXE2BIN Replacement
24. ASM Tutorials Available

Part III

25. Shareware Assemblers                                REVISED
26. WWW Assembly HomePages                              REVISED
27. Undocumented OpCodes
28. Common Reason Why Memory Allocation Fails
29. Volume Serial Numbers
30. .obj File Format
31. Rebooting from Software
32. Other FAQs
33. Acknowledgments


Subject: 3. Charters For comp.lang.asm.x86 and alt.lang.asm Newsgroups

To know whether or not these newsgroups will meet your needs, the purpose
for which they were created are given below.


comp.lang.asm.x86 was created based upon voting on a Request for Discussion
(RFD).  The RFD for this newsgroup is:

The unmoderated newsgroup comp.lang.asm.x86 is open to discussions on all
topics related to assembly language and low-level programming on IBM
machines with '86 processors.  Appropriate topics would include, but not be
limited to:

    Assembly language tips and tricks (code techniques)
    MASM, TASM, and other commercial assemblers
    Graphics, sound, and other hardware programming
    Assembly language code
    Assembly language related share/freeware
    Linking assembly language with other languages

Topics that are discouraged are:

    Flames about "{Language X} is {better/worse} than ASM"
    Flames like "{Assembler 1} is {better/worse} than {Assembler 2}"
    High-level language code, except when used for hardware programming


Alt newsgroups are initiated with a Proposal posting to the alt.config
newsgroup.  The proposal for alt.lang.asm is:

alt.lang.asm will address the problems of machine language programmers out
there in InterNet land.  It will be a forum for discussion of coding
techniques and efficiency problems related to machine language.  The scope
will be broad.  We will not discriminate by machine architecture, race or

Contributors: Michael Averbuch, [email protected]
              Raymond Moon, [email protected]
Last changed: 28 Dec 94 


Subject: 4. What Is Assembly Language


Although programmers tend to use C or C++ or Pascal these days, the
language closest to the PC hardware is machine language.  Not one second
during a PC's powered on lifetime passes where the computer is not
executing machine language.


To word this simply, you can say that say that assembly language is a
human-readable text, and machine language is machine-readable binary code.
When you program in assembly language, you are programming on the machine
language level.

To program directly in machine language is teadious, so you use assembly
language instead, and use an assembler to produce the actual machine code.


I personally think that except as a learning exercise it's a waste of time
writing something in asm that can be written acceptably fast in a
high-level language.

Assembly language fits for the following:

 *  Low level control.  When you need to change the flags, or the control
    registers of the processor, as when entering protected mode.

 *  Speed.  Programs written in machine language execute fast!  It can
    execute 10-100 times the speed of BASIC, and about twice as fast as a
    program written in C or Pascal.

 *  Time Critical Code.  Critical sections of programs written in higher
    level languages, can be written in assembly to speed up sections.

 *  Small program size.  When you write a TSR for example this is very
    useful. Writing interrupt handlers is where assembly language shines.

Assembly language is very flexible and powerful, anything that the hardware
of the computer is capable of doing can be done in assembly.

Contributor: Patrik Ohman, [email protected]
Last changed: 10 Jan 95


Subject: 5. List Of x86 OpCodes

To obtain a full listing of the instruction set, opcodes and instruction
timing of the Intel processors, the book

Pentium<tm> Family, User's Manual
Volume 3: Architecture and Programming Manual
ISBN 1-55512-227-12

is the best source of information.

This book is available directly from Intel by calling or writing: 
Intel Literature Sales
P.O. Box 7641
Mt. Prospect, IL 60056-7641
(800) 548-4725

Another source of information on the instruction set is the program HelpPC,
see obtaining HELPPC elsewhere in this document.

Contributor: Patrik Ohman, [email protected]
Last changed: 10 Jan 95


Subject: 6. What Is HELPPC and Where Is It Available

HELPPC is a Quick Reference Utility for the intermediate to advanced
programmer.  It is a shareware program written by David Jurgens.  The
latest version is 2.10

The topics distributed in an easy database format are:
    BIOS interrupts;
    DOS interrupts and DOS functions;
    EMS and Mouse functions;
    BIOS and DOS data structures;
    diagnostic codes;
    DOS commands;
    80x86 assembler instructions;
    standard and vendor specific C functions; and
    various hardware specifications.

HELPPC is customizable by users.  The documentation describes how users can
incorporate their own information into the help file format.  These user
help files then can be incorporated into the database and accessed via
HELPPC application.

HELPPC comes in two versions.  The first is a DOS command line program. 
The second is a TSR.  The TSR supports context sensitive help within many
editors.  Only 32K is taken by the TSR version.

HELPPC requires:
    DOS 2.0 or greater;
    64K of RAM for DOS Command Line or 32K for TSR; and
    hard disk recommended.

HELPPC is available specifically from:

HELPPC also is available from any site that mirrors the SimTel directory.

Contributor:  Raymond Moon, [email protected]
Last changed: 28 Dec 94


Subject: 7. How To Truncate A File

There is not any single DOS Int 21h function that performs this operation. 
A file can be truncated using two functions.  The procedure is:

1.  Use Int 21h function 42h, Move File Pointer, to move the file pointer
    to the position where you want the file to be truncated.
2.  Use Int 21h function 40h, Write File or Device, to write zero bytes to
    the file.

Execution of the last DOS function will update the directory to the new
file length.

Contributor: Raymond Moon, [email protected]
Last changed: 28 Dec 94


Subject: 8. How Can STDERR Be Redirected To A File

I understand that 4DOS has this capability at its command line.  If you are
looking in the assembly language FAQ for this information, an assembly
language answer probably is desired.  Here it is.

You will need to write a short program that performs the STDERR redirection
before loading and executing the desired program.  This loader program
relies upon the fact that a child program inherits all open files of the
parent program unless the parent program opens a file with the inheritance
flag set to no.

Because the full code for such a program is too large for this FAQ, I will
give are the salient specifications for such a program.

1.  The loader program accepts three command line arguments:
    a.  The full path and filename of the file into which STDERR is to be
    b.  The full path and filename of the program to be executed.
    c.  The command line for the program to be executed (should be
        delimited by double quotes to allow multiple arguments).  This
        argument is optional.
2.  Release all memory above the program using Int 21 function 4ah so that
    there will be room enough to load and execute the designated program. 
3.  Open the file from step 1.a above into which STDERR is to be written.
4.  Duplicate STDERR filehandle, which is 2, using Int 21h function 45h.
5.  Using Int 21h function 46h, force STDERR filehandle, again 2, to have
    the filehandle of the opened file from step 2.
6.  Use Int 21h function 4b00h to load and execute the program from step
    1.a.  Use the default environment and the command line from step 1.c
7.  Upon return from the function 4b00h, close the file opened in step 2.
8.  To restore STDERR, use Int 21h function 46h to force STDERR, again 2,
    to point to the filehandle saved from step 3 above.

This same technique can be applied to any of the standard devices.

I have written a full featured demonstration program.  I believe that asm
programmers will find the source code useful even if they do not want to
redirect stderr to a file.  The URL to the file is:

Contributor: Raymond Moon, [email protected]
Last changed: 3 Jun 95


Subject: 9. How To Determine The CPU Type


The type of processor and math coprocessor can be determined using two
functions that have been provided by Intel.  The source code to these
functions can be obtained from Intel by:

Three source files are included in this .zip file.
    cpuid3a.asm - This source code file contains two assembly language
        functions.  One determines the type of cpu from 8088/8086 to
        Pentium.  The second detects and identifies, if present, the type
        of math coprocessor.
    cpuid3b.c - a c program that calls the above two functions and displays
        the results.
    cpuid3c.asm - this is an assembly program equivalent to cpuid3b.c.


On some 486 and all Pentium processors, Intel has included an undocumented
CPUID instruction.  More information on this instruction and how to tell if
a processor supports this instruction, see Ralf Brown's OPCODE.LST, Subject

You also can get the word directly from Intel

    The file in the .zip file describes the CPUID instruction, explains the
evolution of CPU detections strategies and includes the source code for the
CPUID program.  UNFORTUNATELY, the format for the file is a postscript
print file.  To get a human readable copy, it must be sent to a postscript
viewer or printer!

9.3  Robert Collins' CPUID.ASM

Robert Collins has posted a his version of cpuid which will detect the P6
or Pentium Pro.  To date, checking the above Intel site, I could not find
an updated Intel routine.

Contributor: Raymond Moon, [email protected]
Last changed: 11 Nov 95  


Subject: 10. IRQ Assignments

A list of IRQ assignments are available in David Jurgens' HELPPC database. 
See Subject #6 for details on how to obtain this program.

Contributor: Raymond Moon, [email protected]
Last changed: 28 Dec 94  


Subject: 11. Ralf Brown's Interrupt List


The latest version of Ralf Brown's Interrupt List is 4.9.  The files are
available directly from his home page, from SimTel, or Garbo:

The files are:    Comprehensive listing of interrupt calls, 1 of 4    Comprehensive listing of interrupt calls, 2 of 4    Comprehensive listing of interrupt calls, 3 of 4    Comprehensive listing of interrupt calls, 4 of 4    Hypertext/utility programs for interrupt list    WinHelp conversion programs for interrupt list    HC31/HCP phrases file for interrupt list    WINHELP hypertext 


This interrupt list is an extensive listing of functions available through
interrupt and FAR calls.  Both documented and undocumented calls are
included.  Also available are maps of CMOS and BIOS memory and I/O ports. 
The current release contains 7,800 entries and over 3,100 tables.


Version 4.7:
HP 100LX/200LX calls, some Windows95, XMZ, LAN Manager data structures,
Linux DOSEMU, NetWare printing and VLMs, HugeRealMode Server, GO! Directory
locator, XDF.  Plus, a significantly expanded PORTS.LST and a reformatted

Version 4.8:
380K of new information (400 new calls), including Pentium Local APIC,
ATA-2/ATA-3 IDE specs, Bootable CD-ROM specification, Enhanced Disk Drive
Spec v1.1, PCI BIOS v2.1, EPP BIOS v7, Multiprocessor Specification, Smart
Battery protocol, additional Plug-and Play info, Atari Portfolio, HP Hornet
chipset, MODAL PC, K3PLUS updates, WinDOS, many additional NetWare
functions, many additional I/O ports.  Updated OPCODES.LST, new file
TABLES.LST containing pointers to selected tables, new list viewer IVIEW.

Version 4.9:
Zfax v4, BSC/SDLC ports, Q87 v4, I1541, CauseWay v1.3 DOS extender,
additional I/O ports, and updated OPCODES.LST.


Ralf Brown has included quite a few viewers.  They are included as embedded
.zip files.  I would unzip them into separate files and determine which one
best fits your needs.


OVERVIEW.LST - A brief description of each of the 256 interrupts.
86BUGS.LST - A list of undocumented and buggy instructions with
    descriptions of the x86 Intel processor and compatible processors.  And
    you thought that the Intel FDIV was the first bug in a processor!
CMOS.LST - a CMOS memory map.
OPCODE.LST - A list of undocumented instructions and documented
    instructions of any last processor.
PORTS.LST - I/O port addressed for XT, AT and PS/2 computers.
GLOSSARY.LST - glossary of PC terms.
MEMORY.LST - The format for various memory locations, such as the BIOS Data
    Segment, Interrupt Vector Table, and much, much more.
INTERRUP.PRI - iAPX 86 Interrupt Primer

Contributor: Raymond Moon, [email protected]
Last changed: 17 Feb 96 


Subject: 12. Using VGA Mode 13h for Fast Graphics


Mode 13h is so widely used for graphics applications in DOS because it is
very easy to use.  The screen is constantly being redrawn by the video
card.  To affect what the card draws, it is necessary to write to the
screen buffer.  The screen buffer in mode 13h is always at segment:offset =
A000:0000.  Thus, to set up drawing directly to the video buffer, this is
what you'd most often first do:

  ;Change the video mode to 13h
    xor  ah, ah         ;VIDEO Function 00h: Change screen
    mov  al, 13h        ;Put the desired graphics mode into AL
    int  10h            ;Call VIDEO
  ;Prepare for writing to the video buffer
    mov  di, 0a000h     ;Put the video segment into DI
    mov  es, di         ; so it can easily be put into ES
    xor  di, di         ;Start writing at coordinates (0,0)


Why is Mode 13h so popular?  To understand, you must know a few basic
facts.  In Mode 13h, the screen is 320 by 200, or 320 pixels across and 200
pixels down.  In each pixel, there's a possibility of 256 colors, which can
be fit into one byte.  Thus, 320*200*1 = 64000 bytes, about the size of one
segment.  Think of the screen as an array of colors.  The first row takes
up addresses A000:0000 to A000:013F (decimal 319), the second row takes up
addresses A000:0140 to A000:027F (decimal 639), and so on.  To plot a
pixel, assuming ES=A000:

  ;Plot a pixel in video mode 13h, where
  ;PixelAddress = (320 * Y) + X
    mov  ax, 320        ; Prepare for the multiplication  
    mul  [Y]            ; Assuming that Y is defined in the data segment
                        ;   earlier in the program
    mov  di, ax         ; Put in into the pointer to the offset of ES
    add  di, [X]        ; Assuming that X is defined in the data segment
                        ;   earlier in the program
    mov  al, [Color]    ; Assuming that Color is defined in the data
                        ;   segment earlier in the program
    stosb               ; Write it to the screen!

See how easy that was?  Something to remember is that it is zero-based. 
The upper-left corner is (0,0), and the lower-right is (319,199).  A
complete TASM Ideal mode procedure might look something like this (it
assumes that the video card is already set to mode 13h):
PROC WritePixel BASIC   ; Or whatever language you might want to link
                        ;  it to
    USES es, di         ; It's always a good idea to preserve ES and DI
    ARG  X:word, Y:word, Color:BYTE
    mov  di, 0a000h     ; Put the video segment into DI
    mov  es, di         ;   so it can easily be put into ES
    mov  ax, 320        ; Prepare for the multiplication
    mul  [Y]            ; Offset pointer by the Y value passed in
    mov  di, ax         ; Put in into pointer to the offset of ES
    add  di, [X]        ; Offset the pointer by the X value passed in
    mov  al, [Color]    ; Put color to be written to the screen in AL
    stosb               ; Write it to the screen!
ENDP WritePixel

To write a horizontal line, just put the length in CX, and replace the
STOSB with a REP STOSB.  Writing a vertical line is only a little more
tricky.  Observe the following TASM Ideal mode procedure:

PROC VerticalLine BASIC ; Or whatever language you might want to link
                        ;  it to
    USES es, di         ; It's always a good idea to preserve ES and
                        ;  DI
    ARG  X:word, Y:word, Color:BYTE, Length:word
    mov  di, 0a000h     ; Put the video segment into DI
    mov  es, di         ; so it can easily be put into ES
    mov  ax, 320        ; Prepare for the multiplication  
    mul  [Y]            ; Offset the pointer by the Y value passed in
    mov  di, ax         ; Put in into the pointer to the offset of ES
    add  di, [X]        ; Offset the pointer by the X value passed in
    mov  al, [Color]    ; Put the color to be written to the screen
                        ; in AL
    mov  cx, [Length]   ; Prepare for the loop
    stosb               ; Write it to the screen!
    add  di, 319        ; Move down one row (DI has already advanced
                        ;  once because of the STOSB, thus the 319)
    loop YLoop
ENDP VerticleLine

Observe how there is a tight loop that moves DI down one row each

In short, the easiest way to write directly to the Mode 13h video buffer is
to think of the screen as just a 320 by 200 array of bytes, starting at

Author: Michael Averbuch ([email protected])
Last Change: 29 Dec 94


Subject: 13. Real Mode/Protected Mode


[Note:  because of a crash at zfja-gate, the below information of files on
zfja-gate may not be accurate.]

All the files below are available from:

The authors e-mail addresses are given below.

These files can be received by e-mail.  Send e-mail to:

    [email protected]

with GET CPU/PROTECT.MOD/PMFAQ/* in the text.

A .zip file with all the latest files described below has been uploaded to
SimTel but as of 19 Dec has not been made available for download.  The URL
to this file when available should be: 

Watch this site or for the upload announcement in the newsgroups.


This file contains a preliminary protected mode FAQ by Jerzy Tarasiuk.


Till Gerken has written a Protected Mode Tutorial.  This tutorial contains
code and applicable function calls that comprise the Virtual Control
Program Interface (VCPI).  Till Gerken's tutorial is available:


Jerzy Tarasiuk has posted an example program switching to Protected Mode
and back to again to Real Mode.


Lastly Jerzy Tarasiuk has included some of his e-mail that covers real mode
IDT switching.

Contributors: Till Gerken <[email protected]> and 
              Jerzy Tarasiuk <[email protected]>
Last changed: 19 Dec 95


Subject: 14. Shareware ASM Libraries


Douglas Herr's shareware assembly language library.  This library is
available from SimTel.

The zip file contains only the medium model of the library.  There are 405
assembly subroutines in a .lib file and documentation.  Source code is
available with registration and extra fee.  The library covers the
following areas:
    string/integer data manipulation
    disk & file subroutines
    EMS and XMS subroutines
    floating-point subroutines
    keyboard input subroutines
    screen mode subroutines
    text-mode multi-window subroutines
    mathematical solutions
    subroutines which determine PC status
    text-mode video subroutines

asmlib37 also comes with an editor, E16, written entire with asmlib.


This is Thomas Hanlin's shareware assembly language library.  This library
is available from SimTel. 

This library comes with documentation and one .lib file that supports small
and tiny memory models.  Source code is available with registration. The
library covers the following areas:

    Base Conversions        Mouse Services
    Exception Handling      Sound and Music
    Delays and Countdowns   String Services
    File Handling           Telecommunications
    Filename Manipulation   Time and Date
    Keyboard Services       Video Services
    Long Integer Math       Miscellaneous Services
    Memory Services

14.3  UCR Standard Library for Assembly Language Programmers

This library is written by Randall Hyde and others.  This library is
available from SimTel.

Unlike the previous libraries, there is no registrations fees and the
included source code is released to the public domain.  The author does
request that if you use the library, you contribute at least one routine to
the library.

    Standard Input Routines     Character Set Routines
    Standard Output Routines    Memory Management Routines
    Conversion Routines         String Handling Routines
    Utility Routines

14.4  ALIB Version 3.0

ALIB is Jeff Ownens' shareware assembly language library.  This library is
available from SimTel.

Like the UCR library described above, registration fees are not requested. 
The library consists of 179 assembly source files covering the following

    compress    - data compression and expansion
    config      - program configuration, colors, paths, etc.
    compare     - compare strings
    convert     - hex/decimal/ascii conversions
    database    - simple database functions
    disk        - disk information, path changes, file searches
    display     - fast display functions, write to display memory
    error       - error handlers
    float       - simple floating point math package
    math        - dword math, crc, roots
    memory      - memory manager, extended, xms, ems, conventional
    menu        - menuing system
    message     - messages in windows on screen
    misc        - misc routines
    mouse/key   - mouse and keyboard functions
    parse       - extraction of parameters from command line
    random      - random number generators
    search      - search for character or string
    sort        - sort buffer or file
    sound       - sounds 
    string      - ascii string handling
    stdout      - characters, strings, spaces to stdout
    system      - system interrogation and setup
    time        - time and date conversions

Contributor: Raymond Moon, [email protected]
Last changed: 1 Jan 95

Subject: 15. How To Determine If A Pentium With The FDIV Problem Is Present

The following is a short assembly language program that can detect the FDIV
error: (It has been pointed out to me that the test against zero may lead
to a false positive.  On my 387, the result is exactly zero so that is why
I coded it that way.  PENERR has been tested on and identifies a Pentium
with the FDIV error.)

;   PENERR.ASM - Determines if Pentium FDIV error is present
;   Version 1.00
;   Copyright 1994 - Raymond Moon
;   This program is free for all to use.
x   dd      4195835
y   dd      3145727
OK  byte    'No Error$'
ERR byte    'Pentium Error Present', 7, '$'

    assume cs:DGROUP, ds:DGROUP
        org 100h
START:  finit
        fld x
        fld st
        fld y               ; 0 = y; 1 & 2 = x
        fdiv    st(2), st   ; 0 = y; 1 = x; 2 = x/y
        fmulp   st(2), st   ; 0 = x, 1 = (x/y)*y
        fsubp   st(1), st   ; 0 = (x/y)*y-x => should be zero
        fldz                ; 0 = 0; 1 = (x/y)*y-x
        fcomp   st(1)       ; Is it zero
        fstsw   ax          ; get control word
        ffree   st(1)
        ffree   st
        sahf                ; load flag register
        jz      EQUAL       ; If C3 not set, result = 0
        lea dx, ERR         ; DS:DX => ERR
         jmp OUTPUT
EQUAL:  lea dx, OK          ; DS:DX => OK
OUTPUT: mov ah, 9h          ; Display string
        int 21h
        int 20h             ; Terminate program
_TEXT   ends
        end START
================================================================= in uuencode for those who do not want to assemble the above
source code.
begin 644

Contributor: Raymond Moon, [email protected]
Last changed: 5 Jan 95


Subject: 16. Accessing 4 Gigs of Memory in Real Mode

Flat real mode is a popular name for a technique used to access up to 4 GB
of memory, while remaining in real mode.  This technique requires a 80386
or higher processor.  The address space really is not flat, actually, this
technique allows you treat one or more segments as large (32-bit) segments,
thereby accessing memory above 1 MB.

When the CPU accesses memory, the base address of the segment used is not
described by the value currently in the appropriate register.  The value is
stored internally in a structure known as the descriptor cache.  Changing
the value of a segment register results in that segment's entry in the
descriptor cache being recalculated according to the rules of the current
mode.  In real mode, the value of the segment register is shifted left four
bits to find the base address of the segment, and the size of the segment
is always 64k.  In protected mode, the value in the segment register is
used as an index into a descriptor table located in memory, and the base
address and size (which may be as small as 4 KB, or as large as 4 GB)from
the descriptor table are loaded into the descriptor cache.

When the processor changes modes, the contents of the processor's internal
descriptor cache are not changed.  The reason is because changing them
would result in (at the very least) the code segment being recalculated
according to the new mode's rules, most likely causing your program to
crash.  Thus the program must load the segment registers with sensible
values after the mode switch occurs.  Consider an example where real mode
code is located in segment 1000h.  If switching modes caused an immediate
recalculation of the descriptor cache, the processor would attempt to read
entry 1000h of the descriptor table immediately upon switching to protected
mode.  Even if this were a valid descriptor (unlikely), it would have to
have a base address identical to real mode segment 1000h (i.e., 10000h),
and a size limit of 64 KB to prevent a probable crash.  An invalid
descriptor would cause an immediate processor exception.

Normally, aside from preventing situations like that in the above example,
there is little to be said about this feature.  After all, as soon as you
reload new values into the segment register, the descriptor cache entry for
that segment will be reset according to the rules of the current mode. 
After switching from protected mode to real mode, however, when you load
the segment registers with their new values, the segment's base address is
recalculated according to real mode rules, but the size limit is not
changed.  After setting the 4 GB limit (which must be done in protected
mode), it will stay in place until changed by another protected mode
program, regardless of what values are loaded in the segment register in
real mode.

So, the steps to using this technique are as follows:
    1.  Set up a bare bones global descriptor table, with a null entry, and
a single entry for a 4 GB segment.  The base address of this segment is not
    2.  If you don't wish to define an interrupt descriptor table (IDT),
you must disable interrupts before switching to protected mode.  You do not
need a full-fledged protected mode environment for this, so it is easiest
just to disable interrupts and not worry about the IDT.
    3.  Switch to protected mode. 
    4.  Load the segment registers you wish to change with the selector for
the 4 GB segment.  I recommend using FS and/or GS for this purpose, for
reasons I'll describe below.
    5.  Return to real mode.
    6.  Re-enable interrupts.

After these steps, you can then load your segment registers with any value
you wish.  Keep in mind that the base address will be calculated according
to real mode rules.  Loading a value of 0 into a segment register will
result in a 4 GB segment beginning at physical address 0.  You can use any
of the usual 32-bit registers to generate offsets into this segment.

Some points to keep in mind:
    1.  Some software depends on 64 KB segment wrap-around.  While rare, it
is possible that you will encounter software that crashes if the older
segments (DS or ES) are 4 GB in size.  For that reason, I recommend only
using FS and/or GS for this purpose, as they are not used as widely as the
    2.  You should never change the limit of the code segment.  The
processor uses IP (not EIP) to generate offsets into the code segment in
real mode; any code beyond the 64 KB mark would be inaccessible, regardless
of the segment size.
    3.  You should never change the limit of the stack segment.  This is
similar to the above; the processor uses SP in real mode, rather than esp.
    4.  Because of the necessity of switching to protected mode, this
technique will not work in a virtual 8086 mode "DOS box" from Windows,
OS/2, or any other protected mode environment.  It only works when you
start from plain, real mode DOS.  Many memory managers also run DOS in V86
mode, and prevent the switch to protected mode.  It is possible to use VCPI
to work around this, but if you go to that length you will probably find
that you have implemented a complete protected mode environment, and would
not need to return to real mode anyway.
    5.  This technique will not work in the presence of any protected mode
software that changes segment size limits.  When that software returns
control to your real mode program, the limits will be the values to which
the protected mode code set them.  If these limits are different that what
your program used, problems can result.  At the very least, your program
will return incorrect results when accessing data stored in extended
memory.  At worst, your program will crash and burn.

The benefits of this technique are many.  Most importantly, you can access
extended memory without resorting to slow BIOS calls or having to implement
a complete DOS extender.  If your program uses interrupts extensively
(timer interrupts for animation or sound, for example), real mode is a
better choice because protected mode handles interrupts slower.  DOS itself
uses this technique in HIMEM.SYS as a fast, practical method of providing
access to extended memory.

Code demonstrating this technique is available in the file, 
This file is available using anonymous ftp from in the
directory, pub/msdos/programming/memory.

For further reading on this topic, I suggest "DOS Internals," by Geoff
Chappell.  It is published by Addison-Wesley as part of the Andrew Schulman
Programming Series.  The ISBN number is 0-201-60835-9.

Contributor: Sherm Pendley, [email protected]
Last changed: 15 Jan 95


Subject: 17. What Is Available at

To obtain a description of the files available at Intel:
    get libdir.txt

Most of the files are press releases, but there are some hidden jewels. 
Search for and read the files under the Intel386, Intel486 and Pentium
subdirectories.  Here are a sample of files that may be of interest (path
from IAL subdirectory is given):

Pentium/opt32.doc - Optimizations for Intel's 32-bit processors in MS Word
Pentium/pairng.txt - Instruction pairing optimization for Pentium processor
    - text format.
Pentium/p5cpui.txt - new official CPU identification scheme - text format.
Pentium/p5masm.mac - MASM macros for instructions new with Pentium
Tools_Utils_Demos/prot.txt - MASM code for entering protected mode - text
Intel486/ - C source for 8086-80486 16/32 bit disassembler -
    pkzip format.

Contributor: Raymond Moon, [email protected]
Last changed: 8 Jan 95


Subject: 18. Interrupts and Exceptions

    "(with interrupts) the processor doesn't waste its time looking for
    work - when there is something to be done, the work comes looking for
    the processor."
                                    - Peter Norton


Interrupts and exceptions both alter the program flow. The difference
between the two is that interrupts are used to handle external events
(serial ports, keyboard ) and exceptions are used to handle instruction
faults, (division by zero, undefined opcode).

Interrupts are handled by the processor after finishing the current
instruction. If it finds a signal on its interrupt pin, it will look up the
address of the interrupt handler in the interrupt table and pass that
routine control.  After returning from the interrupt handler routine it
will resume program execution at the instruction after the interrupted

Exceptions on the other hand are divided into three kinds.  These are
Faults, Traps and Aborts.  Faults are detected and serviced by the
processor before the faulting instructions.  Traps are serviced after the
instruction causing the trap. User defined interrupts goes into this
category and can be said to be traps, this includes the MS-DOS INT 21h
software interrupt for example.  Aborts are used only to signal severe
system problems, when operation is no longer possible.

See the below table for information on interrupt assignments in the Intel
386, 486 SX/DX processors, and the Pentium processor. Type specifies the
type of exception.

Vector number   Description
     0          Divide Error (Division by zero)
     1          Debug Interrupt (Single step)
     2          NMI Interrupt
     3          Breakpoint
     4          Interrupt on overflow
     5          BOUND range exceeded
     6          Invalid Opcode
     7          Device not available (1)
     8          Double fault
     9          Not used in DX models and Pentium (2)
    10          Invalid TSS
    11          Segment not present
    12          Stack exception
    13          General protection fault
    14          Page fault
    15          Reserved
    16          Floating point exception (3)
    17          Alignment check (4)
    18 - 31     Reserved on 3/486, See (5) for Pentium
    32 - 255    Maskable, user defined interrupts
(1) Exception 7 is used to signal that a floating point processor is not
    present in the SX model. Exception 7 is used for programs and OSes that
    have floating point emulation. Also the DX chips can be set to trap
    floating point instructions by setting bit 2 of CR0.
(2) Exception 9 is Reserved in the DX models and the Pentium, and is only
    used in the 3/486 SX models to signal Coprocessor segment overrun. This
    will cause an Abort type exception on the SX.
(3) In the SX models this exception is called 'Coprocessor error'.
(4) Alignment check is only defined in 486 and Pentiums. Reserved on any
    other Intel processor.
(5) For Pentiums Exception 18 is used to signal what is called an 'Machine
    check exception'.

The other interrupts, (32-255) are user defined. They differ in use from
one OS to another.

For a list of MS-DOS interrupts, see 'Obtaining HELPPC' (Subject #6) or
Ralf Browns Interrupt List (Subject #11)

Contributor: Patrik Ohman, [email protected]
Last changed: 10 Jan 95


Subject: 19. ASM Books Available

The format is Author, Title, Level, and short description

Ray Duncan
Advanced MSDOS Programming
Both a tutorial and a reference for MS-DOS capabilities and services,
including reference sections on DOS function calls, IBM ROM BIOS, mouse
driver and LAM. expanded memory. Excellent quality example programs

By Peter Norton and John Socha
Peter Norton's Assembly Language Book For the IBM PC
Good for an introduction to Assembly Language.  Plenty of programming
examples.  Older versions of this book used to have a sample disk.  And as
you read the book, you slowly add on code to what eventually is Disk Patch
- the book's version of Norton's commercially  Disk Edit.  Great for
complete beginners seeking novice rank.

***** WARNING -- Next two books may come with virus infected disk.  Use
your anti-virus software to check and clean, if necessary, these diskettes!

Maljugin, Izrailevich, Sopin, and Lavin
The Revolutionary Guide to Assembly Language
This is one of the best introductory texts I've ever seen  There are so
many authors since the topic is broken down into specific categories:
video, BIOS, keyboard, etc..  Most intro texts force you to follow a set
plan of learning assembly, but in this book you can turn to a specific
topic almost immediately.  It's so-so as a reference book, however - a few
tables of interrupts in the back. 

Maljugin, Izrailevich, Sopin, and Lavin
Master Class Assembly Language
Review: This is the sequel to The Revolutionary Guide To Assembly Language. 
Equally thick and massive, it covers many of the topics we see today -
hardware interfaces, sound cards, data compression, even protected mode
programming.  Brief review of assembly at the beginning, but moves very
quickly.  Read this if you're intermediate seeking expert status. 
Definitely not recommended for beginners.  If you are a beginner and you
think you like the topics covered in this book, buy the one before it too. 
Also comes with a disk of source code examples from the book (MASM highly
recommended, not TASM).

***** End of Possible Virus Alert

Alan Wyatt
Advanced Assembly Language
This book's best feature is it comprehensive guide on device drivers. 
There are good chapters on controlling the mouse, file access, using
memory, etc.

Ralf Brown and Jim Kyle
PC Interrupts - 2nd Edition
The definitive book on interrupt programming for PC's and compatibles. 
Based on the freeware Interrupt List by Ralf Brown

For an extensive book list without descriptions, point your web browser to
Sites with more books but no reviews are:

Contributors:  Antonio Alonso, Solomon Chang, Paul Gilbert, Dave Navarro,
Mike Schmit and James Vahn.
Last changed: 19 Dec 95


Subject: 20. ASM Code Available On The Internet


The SimTel has a directory devoted to assembly language.

20.2    80xxx Snippets

Fidonet's echo for 80xxx programming has a collection of code that is
maintained by Jim Vahn, [email protected]  The collection is
available via mail based archive server or Fidonet file requests to

To get a list of files available via e-mail, send an empty message to
[email protected]  The server will return a list of all files available
and instruction on how to retrieve them.

The assembly language snippets dated before Mar 93 are available in one zip
file at the above SimTel sites under the filename 80XXX393.ZIP.

The Snippets are now on the web.  In addition to downloading the snippets
there is an assembly language related book list.  The URL is:

20.3    X2FTP.OULU.FI

This ftp site,, has some asm source code not available at the
SIMTEL sites.  The following describes some directories and the type of
information that is available in them.

/pub/msdos/programming/pmode - protected mode utilities and some source
/pub/msdos/programming/source - some asm code
/pub/msdos/programming/prgsrc - some asm code

20.4  FTP.X86.ORG

This ftp site contains much of the code and information available from
Robert Collins' web site.


Omen has assembly language source available from its web site.  The address

Much of the code is archived in the .arj format.  You will need the
appropriate.  One is available:

20.6 JUMBO

JUMBO is the Official Web Shareware Site.  It has a directory devoted to
assembly language source code, libraries and utilities:


This FTP site has source code and information that I have not found else
where.  Unfortunately, many of the files are compressed using arj and lzh.


This encyclopedia is a collection of files related to game programming. 
Many of these files contain programming examples.  Topics included are ASM
tutorial, VGA and SVGA programming information, graphic algorithms, graphic
file formats, soundcard and other PC hardware programming information. 
This file is available from:

Contributor: Raymond Moon, [email protected]
Last changed: 8 Jan 96


Subject: 21. How To Commit A File

The easiest solution is to open or create the file to be committed using
Int 21h function 6ch, extended open/create.  The BX register contains the
desired Open Mode.  One option that can be or'ed into this register is what
Microsoft calls, OPEN_FLAGS_COMMIT, that has the value of 4000h.  Using
this option caused DOS to commit the file after each write.  This function
has been available (documented) since DOS 4.0.

If you do not want to commit the file at each write but only when certain
conditions are met, use Int 21h function 68h, commit file.  The functions
has been available (documented) since DOS 3.3.

If you need to support versions of DOS before 3.3, the following technique
will flush the all stored data without closing and opening the file.  It is
the opening of the file that is time consuming.
    1.  Use 21h function 45h to create a duplicate file handle to the file
        to be flushed.
    2.  Close that duplicate file handle.

This technique will work all the way back to DOS 2.0.

Contributor: Raymond Moon, [email protected]
Last changed: 30 Jan 95


Subject: 22. Using Extended Memory Manager


XMS usage - short recipe:
1.  Verify have at least 286 (pushf; pop AX; test AX,AX; js error).
2.  Verify vector 2Fh set (DOS 3+ sets it during boot).
3.  AX=4300h, int 2Fh, verify AL=80h (means XMS installed).
4.  AX=4310h, int 2Fh, save ES:BX as dword XmsDriverAddr.
5.  AH=8, call [XmsDriverAddr] - returns ax=largest free XMS memory block
    size in kB (0 if error).
6.  AH=9, DX=required size in kB, call [XmsDriverAddr] - allocates memory
    (returns handle in DX - save it).
7.  AH=0Bh, DS:SI->structure {
        dword size (in bytes and must be even),
        word source_handle,
        dword source_offset,
        word destination_handle,
        dword destination_offset }
    (if any handle is 0, the "offset" is Real Mode segment:offset)
8.  AH=0Fh, BX=new size in kB, DX=handle, call [XmsDriverAddr] - changes
    memory block size (without losing previous data).
9.  AH=0Ah, DX=handle, call [XmsDriverAddr] - free handle and memory.

Initially, should process #1-#6, then can use #7 to put data in/get
data from XMS memory, or #8 to change XMS memory block size.  On exit
use #9 to free allocated memory and handle.

Hint: handle cannot be 0, since zero is used as "no handle allocated"

Errors for XMS calls (except AH=7 - Query A20) are signaled by AX=0. Error
code returned in BL, few codes can check for are:
    80h - not implemented,
    81h - VDISK detected (and it leaves no memory for XMS),
    82h - A20 error (e.g. fail to enable address line A20),
    A0h - all allocated,
    A1h - all handles used,
    A2h - invalid handle,
    A3h/A4h - bad source handle/offset,
    A5h/A6h - bad destination handle/offset,
    A7h - bad length,
    A8h - overlap (of source and destination areas on copy),
    A9h - parity error (hardware error in memory),
    ABh - block is locked,
    00h - OK

For more info read INT 2Fh, AH=43h in Ralf Brown interrupt list.


When you lock mem block, XMS driver arranges memory governed by it in a way
the locked block forms one contiguous area in linear address space and
returns you starting address of the memory.  Linear address is base address
of segment + offset in segment, in Real Mode it is segment*16+offset, in
Protected Mode the base address is kept in LDT or GDT; note offset can be
32-bit on 386+.  If paging isn't enabled, linear address = physical
address.  You don't need the linear address unless you use 32-bit offsets
in Real Mode or you use Protected Mode (see previous answer for explanation
how you can access XMS memory).

Contributor: Jerzy Tarasiuk, [email protected]
Last Changed: 30 Jan 95


Subject: 24. EXE2BIN Replacement

A utility, EXE2BIN, used to be included in DOS.  This utility was needed to
convert the output of the linker from .EXE to .com format because the
linkers could not do this directly.  As linkers became more capable, the
need for this utility vanished, so EXE2BIN was dropped from DOS.  If you
still are using an older assembler and linker, you now have been left out
in the cold.  Well, not quite, as there are three shareware equivalent


EXECOM was written by Chris Dunford in C.  The .zip file contains the
executable, documentation and the .c source that Chris Dunford has released
into the public domain.  The current version is 1.04 with a 2 Mar 88 date.

23.2 BIN.ZIP

This replacement version was written by Bob Tevithick.  It is based upon
versions 1.00 of Chris Dunford's program.  The .zip file contains only the
executable and documentation.  No source is included.

23.3 X2B11.ZIP

X2B is written in 100% assembly language by Henry Nettles.  Again it is
based upon Chris Dunford's program.  The zip file contains the executable
and .asm source.  The documentation is in the source code.


All there .zip files are available at any SimTel Mirror site.  They are
found in the SimTel/msdos/asmutil directory.


If you need the real thing, EXE2BIN.EXE is available on the DOS
Supplemental Diskettes.  This disks can be downloaded from microsoft.

    DOS62SP.EXE     for MS DOS 6.2
    DOS6SUPP.EXE    for MS DOS 6.0
    SUP621.EXE      for MS DOS 6.21
    SUP622.EXE      for MS DOS 6.22

Contributor: Raymond Moon, [email protected]
Last changed: 8 Jan 96


Subject: 24. ASM Tutorials Available

There are several assembly language tutorials available on the internet.


From the SimTel Mirrors, e.g.,, there are two tutorials
available in the simtel/msdos/asmutil directory.

    The tutorial is by Joshua Averbach.  It is old as it is dated in Jun
1988.  It is designed for the 8088 processor.

    This tutorial is designed specifically for the cheap assembler (CHASM)
also available in this directory.


    A new tutorial has been written by Gavin Estey.  He has provided his
tutorial in ascii text and in Microsoft Word format.  They are available
using anonymous ftp from:
    get                 For ascii text
    get                For MS Word document

24.3 VLA's Assembly Language Tutorial

This tutorial is available directly or as part of the PC Games
Encyclopedia.  This file is available from:
or as part of the PC Games Encyclopedia:   

24.4 ASM Tutorial on University of Guadalajara Web Site

The on-line tutorial descibed below also is available as an ascii text.

24.5    Web Sites

Assembly Language Tutorials
        ASM Tutorial on University of Guadalajara Web Site
        Version 2.6 of on-line 386 assembly languager course.  Self tests,
        assignments, course notes, and software are included.
        Mike Babcock's ASM Tutorial
        Tutorial emphasises video and gaming techniques and C and assembly

Contributor: Raymond Moon, [email protected]
Last changed: 17 Feb 96

What is the quantification of the paraloid
sector if it has dimension of ST78302902635-9?

Subject: 25. Shareware Assemblers


All assemblers, unless otherwise noted, listed here are available from
SimTel in the SimTel/msdos/asmutil directory.  Specifically:

25.2  A86

This assembler is a very capable assembler for 89286 and earlier
processors.  Registration will get you a version capable of handling 80386
processor.  For more details, see the A86 section of this FAQ.


This assembler was the first shareware assembler available.  CHASM was
written Mr. David Whitman.  The current version available is version 4 and
dated in 1983.  This version supports only 8088 processor, and the output
only is:
    .com file (.exe is not supported)
    BLOADable - format for interpreted BASIC to load and execute
    External procedure for TurboPascal - TurboPascal version not given

The version available on the internet is annoyware and crippleware.  For
$40 registration fee, you will get the complete version without the
annoying banner page.  This version supports macros, conditional assembly,
include files, operand expressions and structures.

I do not recommend this assembler because of it limited capability and it
is very out of date.


This assembler is the public domain version of the Professional Arrowsoft
Assembler by Arrowsoft Systems, Inc.  The version is 1.00d and is dated in
1986.  This assembler is a MASM 3.0 compatible assembler and supports up to
80286 processor.  Compared to the Professional version, the public domain
version has one major limitation.  The file input size is limited to 64K

The file also includes a public domain linker, full screen editor and an
EXE2BIN clone program.

The above version 1.00d is available from SimTel.  Version 2.00c which has
only the assembler and documentation is available:
and the linker separately:
These are used in the freeDOS project.


This assembler was written by Mr. Eric Tauck.  The latest version is 2.02
and dates from 1987.  This assembler supports only the 8088 processor and
assembles directly into a .com file.  It supports a simplified syntax and
program structure so programs written for this assembler may not be
compatible with other assemblers.  Several source files for programs are
included with the .zip file.

25.6 MAGIC ASSEMBLER, ASM110.ZIP                                    REVISED

This assembler is the very new.  The version is 1.10 and dates from March
1995.  This assembler was written by Mr. Bert Greevenbosch.  The output is
either a .com file or a boot sector program.  The assembly commands are
standard except for the jump and call commands.  Again, the source code
will not be compatible with other assemblers.  Beware of version 1.04. 
That version had a bug that when executed without the print command, the
assembler terminated with a runtime error.  This is corrected in subsequent

Changes made in version 1.10 are:
    CALLF [] added, CALL [] corrected   Boot Indicator (55aa) added
    [BX][SI] now recognized as [BX+SI]  Calculations (*, /, -, +) added
    XCHG added                          Assembling Report added
    EQU bug corrected                   IN/OUT command improved


This assembler revision is 2.6a with a date, 4 Jan 96.  It is different
from all other x86 assemblers I have seen.  This assembler is based upon
Motorola's 68k mnemonics and logical structure.  All instuctions, Pentium
Pro and known undocumented are supported.  GEMA was designed especially for
32-bit porcessing.  The assembler will take only one source code file and
will output an .com or .exe file.  No linker is required.  DESA.EXE, a beta
GEMA disassembler is available in the GEMA package. ASM2GEMA.EXE, a TASM to
GEMA translator is no longer availabe as part of the GEMA package.  An
interactive real and protected-mode debugger is in progress.

This assembler is available from:  (symbolic link to latest
25.8 NASM 0.1, NASM.ZIP

The birth of this assembler started out of a thead that started on
comp.lang.asm.x86.  When you download this assembler, you get the source
code in ANSI C.  The web page devoted to this assembler is:

The assembler is available for downloading from this web page.

25.9 GAS, GNU Assembler

This assembler with many object-file utilities will run on 386 systems
running the following operating systems: AIX 386BSD, NetBSD, BSDI/386,
Linux, SCO, Unixware, DOS/DJGPP.  The below file is a gzipped tar file. 
You will not gzip and tar programs to uncompress and extract the files.
The assembler and utilities are part of the GNU binutils file.  This file,
a 3.86 Mbyte file, is available from:


This assembler is dated in Dec 93 and is a beta test.  The nice thing about
this assembler is that it comes with its own DOS-windowing IDE.  This
assembler was written by Internationa Systems development.  The instruction
set supported is 486 including protected mode instructions, but some holes
do exist.  This assembler has a unique way of supporting macros.  32-bit
supported.  On line help and debugger are available with registered

25.11 ENHANCED ASSEMBER, EASM.ZIP                                       NEW

This is version 1.0a of the above assembler.  This assembler supports all
standard commands (there was a small and not inclusive list of standard
commands in the documentation), as well as an enhanced command set - Very
non standard.  This assembler is available from:

The home page:

Contributor:  Raymond Moon, [email protected]
Last changed: 18 Mar 96


Subject: 26. WWW Assembly HomePages


All of the web sites listed here are maintained by individuals.  I will
strive to maintain this list current but do not be surprised if the
addresses no longer are current.


Assembly Language Resources

Assembly Language Tutorial
        Version 2.6 of on-line 386 assembly languager course.  Self tests, 
            assignments, course notes, and software are included.
        Mike Babcock's ASM Tutorial

Hardware Systems
        Good links to general asm information.  Links to iAPX386

Robert Collins' home pages (all of these are in the process of moving. 
These are then new addresses.  Everything may not be working yet.)
        Collins' home page
        Intel Secrets - undocumented OpCodes, links to Intel's on-line
            documentation, the infamous Appendix H, P6 OpCodes, and much,
            much more
        Shareware BIOS
        Growing list of on-line Intel documentation and magazine articles
            by Robert Collins and Ralf Brown
        Pentium Pro Information including New Opcodes, Paging Extension,
            CPUID and manuals.
        Protected Mode Basic - a tutorial on PM with souce code.

Christian Ludloff's 80x86.CPU home page                           REVISED
        This home page includes new information about many Intel processors
            and their clones.  This information is of interest to system
            software authors.

Jannes Faber's Assembly home page
        List of ASM Books with short reviews
        A few hints and tricks
        Complete source code to some of his programs
        A listing of EMS Professional Shareware products

Ray Rose's Html For Assembler home page
        An extensive list of ASM books without descriptions
        Links to alt.lang.asm, comp.lang.asm.x86, and alt.msdos.programmer
        Link to the Yahoo/Computers and Internet/Languages/Assembly page
            (see below)

NASM: The Netwide Assembler Project
        A group of programmers are writing a new assembler.  This home page
            describes the project and where to download the latest version.

Michael Babcock's 3/4/586 ASM Programming Home Page
        This home page has links to:
            Optimizing 803/4/586 ASM Programming
            ASM Tutorial

The Official Web Shareware Site
        This site appears to have a few asm files not on SimTel.

Hamarsoft 86BUGS list Online
        List contains many documented and undocumented errors in Intel
            microprocessors, as well as undocumented instructions.

Joe's Assembly Language Page
        Links to his own and other asm code.
        His own Assembly Language Search Engine

Bill Stapleton's Assembly Language Reference Page
        A collection of 80x86 assembly language references generating from
            teaching EE383 and EE384 courses at The University of Alabama.
Dr. ASM's Assembly Home Page
        Some answered questions and links to other assembly related sites.

80xxx Snippets - A file site for 80x86 Assembly Language enthusiasts
        Download snippets & Booklist

Arzie's Home Page - Many links to programming related pages and source code

CERA Research Assembly Language Hot Lists and Major Resources
        Links to FAQs and other web sites

Kip Irvine's Assembly Language Sources

Arzie's Programming Page                                                NEW

Gavin Estey's Home Page                                                 NEW
        His ASM tutorial and other ASM Links and FAQs

Contributor:  Raymond Moon, [email protected]
Last changed: 18 Mar 96


Subject: 27. Undocumented OpCodes


Robert Collins has make available an excellent article on Intel
Undocumented OpCodes.  Just set your web browser to:


Mr. Collins describes extended forms these two instructions.  AAM is ASCII
Adjust after Multiplication, and ADD is ASCII Adjust before Division. 
These instructions are knows as quick ways to divide and multiply by ten,
as these instructions normally assemble with 10 as the default operand. 
Using macros provided, any value from 0h to 0ffh can be substituted.  These
instructions are available on all x86 Intel processors.


Mr. Collins describes this instruction a c programmers dream instruction
for interfacing to assembly language procedures.  This instruction will set
the AL register to 00h or 0ffh depending on whether the carry flag is clear
or set, respectively.  This instruction is available on all x86 Intel


Mr. Collins describes several instructions that appear whose existence
makes debugging run-time code easier on the ICE debugger.  There are:
    ICEBP   - ICE Break Point
    UMOV    - User Move Data
    LOADALL - Loads the Entire CPU State
Contributor:  Raymond Moon, [email protected]
Last changed: 4 Nov 95


Subject: 28. Common Reason Why Memory Allocation Fails


A common error received when first learning to use Int 21h Function 48h,
allocate memory, is error code 8, insufficient memory available.  Usually,
the programmer then writes a small program that only allocates memory, and
the program still fails.  This situation is quite puzzling because there
should be hundreds of kilobytes of memory available but this function
reports that there is insufficient memory for a few hundred bytes.  The
reason is that DOS generally allocates all available memory above the
loaded program to that program.  Therefore, there is no more memory to
allocate, so the request fails.


Since a .com file does not contain any header information, the DOS loader
has no way of determining how much memory is required for a program beyond
the physical size of the program.  Even this number is deceptive because it
does not include a stack.  Therefore, DOS always allocates all available
memory above the program to the program.

To use the allocate memory function, the programmer must release that extra
memory using Int 21h Function 4ah, Set Memory Block Size.  Given that
generally, there is more that 64 Kbytes of memory, the DOS sets Stack Top
to just under that value, it is generally safe to release all memory above
64 Kbytes.


The amount of memory the DOS allocates to the loaded program depends upon a
value in the .exe header.  This value is called Maximum Allocation and is a
word starting at offset 12.  This value specifies the number of 16-byte
paragraphs beyond the image size wanted by the program to execute.  This
value must be equal or greater that the Minimum Allocation, which is the
number of 16-byte paragraphs beyond the image size required by the program
to execute.  This space generally contains uninitialized variables and the

The value of Maximum Allocation is set by the /CPARM Option for the
Microsoft Linker.  By default, the linker sets this value to 0ffffh which
will causes DOS to allocate the largest block of available memory.  This
memory can be used as a heap, print buffer, etc.


In the PSP, at offset 02h, DOS loads a word which is the segment address of
the next Memory Control Block or Arena.  Subtracting the PSP from that
value at offset 02h will be the number of memory paragraphs allocated to
the program.  The number of bytes can be calculate by shifting that number
to the left by 4 bits, multiplying by 16, the size of a memory paragraph.


If you want to load and execute another program, you must release memory to
make room for the program.  Also, since the largest chunk of memory is
allocated already to the program, all requests to allocate memory generally

Again, to use the allocate memory function, the programmer must release the
extra memory above the program use as for a .com file above.  The problem
here is where is the end of the program.  The answer is not as simple as
with the .com file.  There are two basic solutions.

1.  If you use the .dosseg option, the Microsoft Linker will define a
label, _end, at the end of the DGROUP.  Since the .dosseg option also
places any FAR data segments between the code and DGROUP segments, you can
release all memory above that label.

2.  If you do not want or are unable to use the first option, use an
include file which declares all segments used by your program.  Define in
the last segment, a label and use it as the _end label in the first

Contributor:  Raymond Moon, [email protected]
Last changed: 26 Dec 95


Subject: 29. Volume Serial Numbers


The volume serial number was introduced with DOS 4.0 as part of an extended
boot record and is created through you either FORMAT a disk or use DISKCOPY
to create another disk.  The serial number is a function of the time/date
of the formatting or the diskcopying.  Note that DISCOPY generates a new
volume serial number so a DISKCOPY is not an exact image of the source


For example, say a disk was formatted on 26 Dec 95 at 9:55 PM and 41.94
seconds.  DOS takes the date and time just before it writes it to the disk.

Low order word is calculated:               Volume Serial Number is:
    Month & Day         12/26   0c1ah
    Sec & Hundrenths    41:94   295eh               3578:1d02

High order word is calculated:
    Hours & Minutes     21:55   1537h
    Year                1995    07cbh

Note that DOS interrupt 21h Functions 2ah, Get DOS Date, and 2ch, Get DOS
Time, are particularily suited to getting the date and time for calculating
the Volume Serial Number. 

To read the Volume Serial Number, use the IOCTL call, int 21h function
440dh Minor Code 66h, Get Media ID.  To write the Volume Serial Number, use
the IOCTL call, int 21h function 440dh Minor Code 46h, Set Media ID.

WARNING!  These IOCTL calls use a structure that also contain the volume
label and file system type.  So that you do not create errors with these
values, I recommend that you always Minor Code 66h to initialize the
structure before setting the Volume Serial Number to a new value and
writing it back to the disk. 

Contributor:  Raymond Moon, [email protected]
Last changed: 17 Feb 96


Subject: 30. .obj File Format

30.1 INTEL

There are two sources for this information.  The first is available from
Intel.  The Tools Interface Standards Committe has prepared the following 

The readme file in each .zip file states the the document is the
Relocatable Object Module Format Specification, V1.1.  

Unfortunately, both files unzip into documents formated for Postscript
printers.  Adobe's Acrobat can not display them, but Ghostscript can.  If
you need GhostScript, you can get it from the following site.  Read the 
        (keep trying as I found it difficult connecting to this site)


The second is from Microsoft.  This file is located at:

This file expands into ascii text files that are the Microsoft Product
Support Services Application Note: Relocatable Object Module Format.  These
files date from 1992.  Also include is the .lib file format and the
CodeView extensions. 

Contributor:  Raymond Moon, [email protected]
Last changed: 9 Jan 96


Subject: 31. Rebooting from Software


Within DOS, there are two types of rebooting.  There is the warm reboot
that is evoked by pressing the "Ctrl-Alt-Del" key combination.  During this
reboot, all Power On System Tests, POSTs, are performed with the exception
of the memory tests.  In addition to the POSTs, interrupt vectors are
reinitialized and system timers reinitialized.  In other words, the BIOS
code initializes the computer system to such a state that the computer
system is ready for loading the operating system.  The loading of the
operating system is done by issuing an interrupt 19h.

The second type of rebooting is a cold reboot that occurs when the system
is turned on.  The only difference between a cold reboot and a warm reboot
is the performing of the memory tests.


Whether a cold or warm reboot is performed depends upon the value if the
the reset flat in the ROM BIOS data area.  If this flag is set to 1234h, a
warm reset is performed.  An any other value results in a cold reboot. 
Usually a zero is loaded for the cold reboot.  Code snippets to do this

ROMBIOS_DATA    segment at 0400h
    org 72h
ResetFlag   dw  ?

ROMBIOS     segment at 0f000h
    org 0fff0h
Reset   label   far

In your code:

    mov ax, seg ROMBIOS_DATA
    mov ds, ax
    mov ResetFlag, 1234h        ; or 0 if cold reset is desired
    jmp Reset


Neither the warm or the cold boot flushes buffers, system, smartdrv, and
EMM386, or notifies TSRs.  This can lead to lost of data.


Using this interrupt alone will only reload the operating system onto a
computer system that may not be properly initialized for it.  The interrupt
vectors are not reset but the TSRs that have hooks into the interrupt table
may be overwritten.  Obviously, this can lead to the system hanging if one
of these hooked and overwritten interrupts is called.  Other problems can
be timers not reset or add-on cards not reinitialized properly.  So, do NOT
use int 19h to reboot the computer.


In the original IBM ROM BIOS, the instruction at f000:fff0 was a long jump
to f000:e05b.  Some programs skipped the jump at f000:fff0 and went
directly to the second address which is the start of the reset procedure in
ROM BIOS.  I check my 386 with non IBM BIOS, and the start of the reset
procedure is at the same address.  I believe that using the second address
is dangerous because there is not any guarantee that it will stay the same. 
Also, if you are rebooting the computer what is the reason in saving a few
cycles!  Stay with the address f000:fff0 as the jump there always will take
the execution path to the correct code. 

Contributor:  Raymond Moon, [email protected]
Last changed: 8 Jan 96


Subject: 32. Other FAQs


This excellent FAQ is posted every 20 days to comp.os.msdos.programmer,
comp.answers and news.answers newsgroup.

It is available from


The following websites contains many links to communication and hardware 
related FAQs, e.g., serial port, game port, keyboard, modem, and LANs. 
Most of these FAQs are not approved FAQs so are not found at
but that is not to say that these are not quality FAQs.  There is much good

Contributor:  Raymond Moon, [email protected]
Last changed: 17 Feb 96


Subject: 33. Acknowledgments

I would like to acknowledge all the people who have assisted me or any of the
contributors.  For their time and effort, this FAQ is a better product.

Barry Brey, Kris Heidenstrom, Alan Illeman, Chabad Lubavitch, Jeff Owens,
Russell Schulz, Rocky Seelbach, Janos Szamosfalvi and Cedric Ware