Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ () — Coherent 3.1.0

Media Vault

Software Library

Restoration Projects

Artifacts Sought


as                           Command                           as




i8086 assembler

as [-glx] [ -ofile ] file ...

as is  the Mark Williams assembler.  It  is a multipass assembler
that  turns files  of assembly  language into  relocatable object
modules  similar  to  those  produced  by  the compiler.   as  is
designed   for  writing   small  assembly-language   subroutines.
Because it  is not intended  to be used  for full-scale assembly-
language  programming,  it  lacks  many  of  the  more  elaborate
facilities of full-fledged assemblers.  For example, there are no
facilities  for conditional  compilation or  user-defined macros.
However,  it does optimize  span-dependent instructions  (for ex-
ample, branches).

***** Features *****

as includes the following features:

*   It  automatically  compiles  jump  instructions  into  either
   regular   (three-byte)  jumps   or  short   (two-byte)  jumps,
   whichever is  required.  There is  no explicit short  jump in-
   struction.

*  The assembler  supports temporary labels, which conserves sym-
   bol table space and relieves  the you of having to invent many
   unique labels.

*  Program modules are relocatable.  They can be linked with each
   other and with C program modules produced by the COHERENT com-
   piler.  All  assembled modules must be  linked before they can
   be executed.

*  The  assembler does not  support file inclusion,  but multiple
   source files  can be  concatenated and assembled  by including
   their names in the command line to run the assembler.

*  The  assembler generates SMALL  model objects in  the COHERENT
   l.out object format.

***** Usage *****

Normally, the assembler is invoked via the cc command, which will
automatically assemble and link  any file of source code that has
the  suffix .s.   If you  wish, however, you  can invoke  the as-
sembler  as a  separate program, by  using the  following command
line:


             as [-glx] [ -o file ] file ...


The named files are concatenated and the resulting object code is
written to the file specified by  the -o option, or to file l.out


COHERENT Lexicon                                           Page 1



as                           Command                           as



if no -o option is given.

The option -g causes all symbols that are undefined at the end of
the first pass to be given the type undefined external, as though
they had been declared with a .globl directive.

The  option -l  tells the  assembler to  generate a  listing.  It
writes the listing to the standard output, normally the terminal;
it may  be easily  redirected to  a file or  printer using  the >
operator.

The option  -x strips from the symbol table  of the object module
all non-global  symbols that begin with  the character `L'.  This
speeds  up the  loading of  files by  removing compiler-generated
labels from the symbol table.

***** Register Names *****

The  following lists  the  identifiers that  represent the  i8086
machine registers, which are predefined:


        AX      SP      AL      AH      CS
        BX      BP      BL      BH      DS
        CX      SI      CL      CH      ES
        DX      DI      DL      DH      SS


***** Lexical Conventions *****

Assembler  tokens consist  of identifiers  (also known  as ``sym-
bols'' or ``names''), constants, and operators.

An identifier is a sequence of alphanumeric characters (including
the period `.' and the underscore `_').  The first character must
not be  numeric.  Only  the first 16  characters of the  name are
significant; it throws  away the remainder.  Upper case and lower
case  are different.  The  machine instructions,  assembly direc-
tives, and built-in symbols that are used frequently are in lower
case.

Numeric constants are defined  by the assembler by using the same
syntax as the C compiler: a sequence of digits that begins with a
zero  `0' is  an  octal constant;  a  sequence of  digits with  a
leading `0x' is a  hexadecimal constant (`A' through `F' have the
decimal values 10 through 15);  and any strings of digits that do
not begin with `0' are interpreted as decimal constants.

A  character constant  consists of an  apostrophe followed  by an
ASCII character.  The constant's  value is the ASCII code for the
character, right-justified in  the machine word.  For example, an
instruction to  move the letter `A' to the  register  al could be
expressed in either of two equivalent ways:




COHERENT Lexicon                                           Page 2



as                           Command                           as




        mov     al,$0x41
        mov     al,$'A


The dollar sign indicates an immediate operand.

A blank space can be  represented either 0x20 (its ASCII value in
hexadecimal), or as an apostrophe followed by a space (' ), which
on paper looks like just an apostrophe alone.

The following gives the multi-character escape sequences that can
be used in a character constant to represent special characters:


          \b   Backspace    (0010)
          \f   Formfeed     (0014)
          \n   Newline      (0012)
          \r   Carriage return(0015)
          \t   Tab          (0011)
          \v   Vertical tab (0013)
          \nnn Octal value  (0nnn)


A blank space can be  represented either as 0x20 (its ASCII value
in  hexadecimal), or as  an apostrophe  followed by a space (' ),
which on the page would look like just an apostrophe.

***** Blanks and Tabs *****

Blanks and tab characters  may be used freely between tokens, but
not within  identifiers.  A blank  or a tabulation  character  is
required  to separate  adjacent tokens  not  otherwise separated,
e.g., between an instruction opcode and its first operand.

***** Comments *****

Comments are  introduced by a slash (`/')  and continue until the
end of  the line.  All characters in comments  are ignored by the
assembler.

***** Program Sections *****

The assembler permits  you to divide programs into sections, each
corresponding  (roughly)  to a  functional  area  of the  address
space.  Each program  section has its own location counter during
assembly.   There  are eight  program  sections, subdivided  into
three groups containing code, data and tables:


         code:   shri    Shared instruction
                 bssi    Uninitialized instruction
                 prvi    Private instruction
         data:   prvd    Private data
                 shrd    Shared data


COHERENT Lexicon                                           Page 3



as                           Command                           as



                 bssd    Uninitialized data
                 strn    Strings
         tables: symt    Symbol table


All Mark Williams assemblers  use the same set of sections.  This
increases the portability  of programs between operating systems.
Not all  the sections are  distinct under COHERENT,  however; the
meanings of  the sections under (including hints as  to how the C
compiler uses them) are as follows:

shri (shared  instruction) is the same  as prvi (private instruc-
tion);  the adjective  shared refers to  the sharing  of physical
memory between  two or more  concurrent processes.  prvi  is used
for all code generated by the C compiler.

Similarly, there  is no distinction  between shrd and  prvd.  The
compiler uses  the latter for  all external and  static data that
are explicitly initialized in a C program.

Uninitialized  sections are actually  initialized to  zeros.  The
reason is that the  C compiler uses the bssd (uninitialized data)
section for  external or static data that  are not explicitly in-
itialized: the C language  guarantees that these data are in fact
initialized to zeros.   The bssi (uninitialized instruction) sec-
tion is not used by the compiler.

The strn (strings) section is actually a special part of the data
section, used by the C compiler to store string constants.  It is
synonymous with prvd under COHERENT.

The symt (symbol table) section contains the symbol table used by
the linker.  Both the  C compiler and the assembler generate sym-
bol tables that go in this section.

In most  cases, you need  not worry about what  all these program
sections are,  and can simply write code  under the keyword .prvi
or .shri,  and write data under the keyword  .prvd or .shrd.  You
are advised not to place items  in the symt section, as this sec-
tion is used for internal communication among the C compiler, the
assembler, and the linker.

At  the end  of  assembly, the  sections  of a  program are  con-
catenated so that in  the assembly listing the program looks like
a monolithic block of code  and data.  All code sections are com-
bined into the i8086 code segment, and all data sections into the
i8086  data segment.   The symbol  table is  not linked  when the
program is executed, and so is not assigned to any i8086 segment.

***** The Current Location *****

The special symbol `.'  (period) is a counter that represents the
current location.  The current  location can be changed by an as-
signment; for example:



COHERENT Lexicon                                           Page 4



as                           Command                           as




         . = .+START


The assignment must not cause  the value to decrease, and it must
not change the program section, i.e., the right-hand operand must
be defined in the same section as the current section.

***** Expressions *****

An expression is a sequence of symbols representing a value and a
program section.   Expressions are  made up of  identifiers, con-
stants, operators, and brackets.  All binary operators have equal
precedence and are  executed in a strict left-to-right order (un-
less altered by brackets).

Notice  that  square brackets,  `['  and  `]',  group  expression
elements, because  parentheses are used for  indexed register ad-
dressing.

***** Types *****

Every  expression has  a type  determined  by its  operands.  The
simplest  operands are  symbols.   The types  of  symbols are  as
follows:

Undefined A symbol is defined if  it is a constant or a label, or
          when  assigned a  defined value;  otherwise, it  is un-
          defined.  A  symbol may become  undefined if it  is as-
          signed the value  of an undefined expression.  It is an
          error to  assemble an  undefined expression in  pass 2.
          Pass  1 allows assembly  of undefined  expressions, but
          phase errors  may  be produced if undefined expressions
          are used  in certain  contexts, such  as in a  .blkw or
          .blkb.

Absolute   An absolute  symbol is one  defined ultimately  from a
          constant  or  from the  difference  of two  relocatable
          values.

Register  These are the machine registers.

Relocatable
          All other user  symbols are relocatable symbols in some
          program section.   Each program section  is a different
          relocatable type.

Each keyword  in the assembler has a  secret type that identifies
it internally;  however, all of these  secret types are converted
to absolute in expressions.  Thus,  any keyword may be used in an
expression to  obtain the  basic value  of the keyword.   This is
useful when  employing the keywords that  define machine instruc-
tions.  The basic value of a machine operation is usually the op-
code with any operand-specific bits set to zero.



COHERENT Lexicon                                           Page 5



as                           Command                           as



Notice that  the type of an expression does  not include such at-
tributes  as length  (word or  byte), so  the assembler  will not
remember whether  you defined a particular variable  to be a word
or a byte.  Addresses and constants have different types, but the
assembler does not treat  a constant as an immediate value unless
it is preceded by a dollar sign `$'.  If you use a constant where
an address  is expected, as  will treat the constant  like an ad-
dress (and  vice versa).  It is up to  you to distinguish between
variables and addresses or immediate values.

***** Operators *****

The  following  figure shows  various  characters interpreted  as
operators in expressions.


          +   Addition
          -   Subtraction
          *   Multiplication
          -   Unary negation
          ~   Unary complement
          ^   Type transfer
          |   Segment construction


You can  group expressions by means of  square brackets (`['  and
`]'); parentheses  are reserved for use  in address mode descrip-
tions.

***** Type Propagation *****

When operands are  combined in expressions, the resulting type is
a function  of both the  operator and the types  of the operands.
The operators  `*', `~', and  unary `-'  can  only manipulate ab-
solute operands and always yield an absolute result.

The operator `+'  signifies the addition of two absolute operands
to yield an absolute result, and the addition of an absolute to a
relocatable operand  to yield a result with the  same type as the
relocatable operand.

The binary operator `-' allows two operands of the same type, in-
cluding  relocatable,  to  be  subtracted  to yield  an  absolute
result.   It also  allows  an absolute  to be  subtracted from  a
relocatable, to yield a result with the same type as the relocat-
able operand.

The binary  operator `^'  yields a result  with the value  of its
left operand and  the type of its right operand.   It may be used
to create expressions (usually  intended to be used in an assign-
ment statement) with any desired type.

***** Statements *****

A  program consists  of  a sequence  of  statements separated  by


COHERENT Lexicon                                           Page 6



as                           Command                           as



newlines or  by semicolons.  There are  four kinds of statements:
null statements,  assignment statements, keyword  statements, and
machine instructions.

***** Labels *****

You can precede any statement by any number of labels.  There are
two kinds of labels: name labels and temporary labels.

A name  label consists of an identifier followed  by a colon (:).
The program section and value of the label are set to that of the
current  location counter.   It is  an error for  the value  of a
label to change during an assembly.  This most often happens when
an undefined symbol is used to control a location counter adjust-
ment.

A temporary  label consists of  a digit (0  to 9)  followed  by a
colon (:).   Such a label defines temporary  symbols of the  form
xf and xb, where x is  the digit of the label.  References of the
form xf  refer to the  first temporary label x:  forward from the
reference;  those of  the form  xb refer  to the  first temporary
label x: backward  from the reference.  Such labels conserve sym-
bol table space in the assembler.

***** Null Statements *****

A  null statement  is an  empty line, or  a line  containing only
labels or  a comment.  Null statements  can occur anywhere.  They
are ignored  by the assembler,  except that any  labels are given
the current value of the location counter.

***** Assignment Statements *****

An assignment statement  consists of an identifier followed by an
equal sign `=' and  an expression.  The value and program section
of the identifier are set  to that of the expression.  Any symbol
defined by  an assignment statement  may be redefined,  either by
another  assignment  statement  or  by  a label.   An  assignment
statement  is equivalent  to the equ  keyword statement  found in
many assemblers.

***** Assembler Directives *****

Assembler  directives give instructions  to the  assembler.  Each
directive keyword  begins with a period, and  in general they are
followed by operands.

The following  directives change  the current program  section to
the named section:








COHERENT Lexicon                                           Page 7



as                           Command                           as



             .bssd
             .bssi
             .prvd
             .prvi
             .shrd
             .shri
             .strn
             .symt


The current location counter is set to the highest previous value
of the location counter for the selected section.

The following describes the directives in detail.

.ascii string
     The first  non-white space character,  typically a quotation
     mark, after  the keyword  is taken  as a delimiter.   as as-
     sembles successive  characters from the  string into succes-
     sive  bytes until  it encounters the  next instance  of this
     delimiter.   To include  a quotation mark  in a  string, use
     some other character for the delimiter.

     It  is  an error  for  a newline  to  be encountered  before
     reaching the final delimiter.  You can use a multi-character
     constant  in  the string  to  represent  newlines and  other
     special characters.

.blkb expression
     Assemble a block of  bytes that are filled with zeroes.  The
     block is expression bytes long.

.blkw expression
     Assemble a block of  words that are filled with zeroes.  The
     block is expression words long.

.byte expression [, expression ]
     The expressions  in the list are truncated  to byte size and
     assembled  into successive bytes.   Expressions in  the list
     are separated by commas.

.even
     Force alignment by inserting  a null byte of data, if neces-
     sary, to set the location counter to the next even location.

.odd
     Force alignment by inserting  a null byte of data, if neces-
     sary, to set the location counter to the next odd location.

.globl identifier [, identifier ]
     The identifiers  in the  comma-separated list are  marked as
     global.  If  they are defined in  the current assembly, they
     may be  referenced by other object modules;  if they are un-
     defined, they  must be resolved by  the linker before execu-
     tion.


COHERENT Lexicon                                           Page 8



as                           Command                           as




.page
     Force the printed  listing of your assembly-language program
     to skip  to the top of  a new page by  inserting a form-feed
     character into the file.  The title is printed at the top of
     the page.

.title string
     Print string at the top  of every page in the listing.  This
     directive also causes the listing to skip to a new page.

.word expression [, expression ]
     Truncate expressions to  word length and assemble the resul-
     ting data  into successive  words.  Expressions in  the list
     are separated by commas.

***** Address Descriptors *****

The following  syntax is used for  general source and destination
address descriptors.  The symbol `r' refers to a register and the
symbol  `e'  to  an expression.   Please  refer to  the following
figure.


       Syntax                            Addressing Mode    Example

       r     Register                mov  ax, cx
       e     Direct address          mov  ax, 0800
       (r)   Indexing, no displacement    movax, (bx)
       e(r)  Indexing with displacement   movax, 2(bx)
       (r,r) Double indexing, no displacementmov ax, (bx, si)
       e(r,r)                        Double indexing with displacementmov ax, 2(bx, si)
       $e    Immediate               mov  ax, $0800


Note that the dollar sign is always used to indicate an immediate
value, even if the expression is a constant.

A direct  address is interpreted as either a  direct address or a
PC-relative  displacement, depending on  the requirements  of the
instruction.

If an address descriptor  indicates an indexing mode and the base
expression is  of type absolute, the  assembler uses the shortest
displacement length  (zero, one, or two bytes)  that can hold the
expression's value.   Relocatable base expressions,  whose values
cannot be completely  determined until the program is loaded, are
always assigned two-byte displacements.

Any  address  descriptor  may be  modified  by  a segment  escape
prefix.  A  segment escape prefix consists  of a segment register
name followed by a colon `:'.  The escape causes the assembler to
produce a segment override prefix that uses the specified segment
register as  an operand.  The assembler  does not produce segment
override prefixes unless explicitly required by an instruction.


COHERENT Lexicon                                           Page 9



as                           Command                           as




***** 8086 Instructions *****

The  following machine  instructions are  defined.   The examples
illustrate the general syntax of the operands.  Combinations that
are syntactically valid may be forbidden for semantic reasons.

The examples use the following references:


       a     General address
       al    AL register
       ax    AX register
       cl    CL register
       d     Direct address
       dx    DX register
       e     Expression
       $e    Immediate expression
       m     Memory address (not an immediate)
       p     Port address


as treats as ordinary one-byte machine operations some operations
that the Intel assembler ASM86 handles with special syntax; these
include the  lock and  repeat prefixes.   as makes no  attempt to
prevent  the generation  of incorrect  sequences of  these prefix
bytes.

Although every machine  operation has a type and value associated
with it, in most cases the value was chosen to help as format the
machine instructions.

For more  information on these instructions,  see the Intel ASM86
Assembly Language Reference Manual.

    aaa             ASCII adjust AL after addition
    aad             ASCII adjust AX before division
    aam             ASCII adjust AX after multiply
    aas             ASCII adjust AL after subtraction
    adcb    r, a    Add with carry, byte
    adc     r, a    Add with carry, word
    adcb    a, r    Add with carry, byte
    adc     a, r    Add with carry, word
    adcb    a, $e   Add with carry, byte
    adc     a, $e   Add with carry, word
    addb    r, a    Add, byte
    add     r, a    Add, word
    addb    a, r    Add, byte
    add     a, r    Add, word
    addb    a, $e   Add, byte
    add     a, $e   Add, word
    andb    r, a    Logical and, byte
    and     r, a    Logical and, word
    andb    a, r    Logical and, byte
    and     a, r    Logical and, word


COHERENT Lexicon                                          Page 10



as                           Command                           as



    andb    a, $e   Logical and, byte
    and     a, $e   Logical and, word
    call    d       Near call, PC-relative
    cbw             Convert byte into word
    clc             Clear carry flag
    cld             Clear direction flag
    cli             Clear interrupt flag
    cmc             Complement carry flag
    cmpb    r, a    Compare two operands, byte
    cmp     r, a    Compare two operands, word
    cmpb    a, r    Compare two operands, byte
    cmp     a, r    Compare two operands, word
    cmpb    a, $e   Compare two operands, byte
    cmp     a, $e   Compare two operands, word
    cmps            Compare string operands, bytes
    cmpsb           Compare string operands, bytes
    cmpsw           Compare string operands, words
    cwd             Convert word to double
    daa             Decimal adjust AL after addition
    das             Decimal adjust AL after subtraction
    decb    a       Decrement by one, byte
    dec     a       Decrement by one, word
    divb    m       Unsigned divide, byte
    div     m       Unsigned divide, word
    esc     a       Escape 0xD8
    hlt             Halt
    icall   a       Near call, absolute offset at EA word
    idivb   m       Signed divide, byte
    idiv    m       Signed divide, word
    ijmp    a       Jump short, absolute offset at EA word
    imulb   m       Signed multiply, byte
    imul    m       Signed multiply, word
    inb     al, p   Input, byte
    in      ax, p   Input, word
    inb     al, dx  Input, byte
    in      ax, dx  Input, word
    incb    a       Increment by one, byte
    inc     a       Increment by one, word
    int     e       Call to interrupt
    into            Call to interrupt, overflow
    iret            Interrupt return
    ja      d       Jump short if greater
    jae     d       Jump short if greater or equal
    jb      d       Jump short if less
    jbe     d       Jump short if less or equal
    jc      d       Jump short if carry
    jcxz    d       Jump short if CX equals zero
    je      d       Jump short if equal to
    jg      d       Jump short if greater
    jge     d       Jump short if greater or equal
    jl      d       Jump short if less
    jle     d       Jump short if less or equal
    jmp     d       Jump short, PC-relative word offset
    jmpb    d       Jump short, PC-relative byte offset
    jmpl    d       Jump long


COHERENT Lexicon                                          Page 11



as                           Command                           as



    jna     d       Jump short if not above
    jnae    d       Jump short if not above or equal
    jnb     d       Jump short if not below
    jnbe    d       Jump short if not below or equal
    jnc     d       Jump short if not carry
    jne     d       Jump short if not equal
    jng     d       Jump short if not greater
    jnge    d       Jump short if not greater or equal
    jnl     d       Jump short if not less
    jnle    d       Jump short if not less or equal
    jno     d       Jump short if not overflow
    jnp     d       Jump short if not parity
    jns     d       Jump short if not sign
    jnz     d       Jump short if not zero
    jo      d       Jump short if overflow
    jp      d       Jump short if parity
    jpe     d       Jump short if parity even
    jpo     d       Jump short if parity odd
    js      d       Jump short if sign
    jz      d       Jump short if zero
    lahf            Load flags into AH register
    lds     r, a    Load double pointer into DS
    lea     r, a    Load effective address offset
    les     r, a    Load double pointer into ES
    lock            Assert BUS LOCK signal
    lodsb           Load byte into AL
    lods            Load byte into AL
    lodsw           Load byte into AL
    loop    d       Loop; decrement CX, jump short
                    if CX less than zero
    loope   d       Loop; decrement CX, jump short
                    if CZ not zero and equal
    loopne  d       Loop; decrement CX, jump short
                    if CX not zero and not equal
    loopnz  d       Loop; decrement CX, jump short
                    if CZ not zero and ZF equals zero
    loopz   d       Loop; decrement CX, jump short
                    if CX not zero and zero
    movb    r, a    Move, byte
    mov     r, a    Move, word
    movb    a, r    Move, byte
    mov     a, r    Move, word
    movb    a, $e   Move, byte
    mov     a, $e   Move, word
    movb    a, s    Move, byte
    mov     a, s    Move, word
    movb    s, a    Move, byte
    mov     s, a    Move, word
    movsb           Move string byte-by-byte
    movs            Move string word-by-word
    movsw           Move string word-by-word
    mulb    m       Multiply, byte
    mul     m       Multiply, word
    negb    a       Two's complement negation, byte
    neg     a       Two's complement negation, word


COHERENT Lexicon                                          Page 12



as                           Command                           as



    nop             No operation
    notb    a       One's complement negation, byte
    not     a       One's complement negation, word
    orb     r, a    Logical inclusive OR, byte
    or      r, a    Logical inclusive OR, word
    orb     a, r    Logical inclusive OR, byte
    or      a, r    Logical inclusive OR, word
    orb     a, $e   Logical inclusive OR, byte
    or      a, $e   Logical inclusive OR, word
    outb    p, al   Output to port, byte
    out     p, ax   Output to port, word
    outb    dx, al  Output to port, byte
    out     dx, ax  Output to port, word
    pop     m       Pop a word from the stack
    pop     s       Pop a word from the stack
    popf            Pop from stack into flags register
    push    m       Push a word onto the stack
    push    s       Push a word onto the stack
    pushf           Push flags register onto the stack
    rclb    a, $1   Rotate left $1 times, byte
    rclb    a, cl   Rotate left CL times, byte
    rcl     a, $1   Rotate left $1 times, word
    rcl     a, cl   Rotate left CL times, word
    rcrb    a, $1   Rotate right $1 times, byte
    rcrb    a, cl   Rotate right CL times, byte
    rcr     a, $1   Rotate right $1 times, word
    rcr     a, cl   Rotate right CL times, word
    rep             Repeat following string operation
    repe            Find nonmatching bytes
    repne           Repeat, not equal
    repnz           Repeat, not equal
    repz            Repeat, equal
    ret             Return from procedure
    rolb    a, $1   Rotate left, byte
    rolb    a, cl   Rotate left, byte
    rol     a, $1   Rotate left, word
    rol     a, cl   Rotate left, word
    rorb    a, $1   Rotate right, byte
    rorb    a, cl   Rotate right, byte
    ror     a, $1   Rotate right, word
    ror     a, cl   Rotate right, word
    sahf            Store AH into flags
    salb    a, $1   Shift left, byte
    salb    a, cl   Shift left, byte
    sal     a, $1   Shift left, word
    sal     a, cl   Shift left, word
    sarb    a, $1   Shift right, byte
    sarb    a, cl   Shift right, byte
    sar     a, $1   Shift right, word
    sar     a, cl   Shift right, word
    sbbb    r, a    Integer subtract with borrow, byte
    sbb     r, a    Integer subtract with borrow, word
    sbbb    a, r    Integer subtract with borrow, byte
    sbb     a, r    Integer subtract with borrow, word
    sbbb    a, $e   Integer subtract with borrow, byte


COHERENT Lexicon                                          Page 13



as                           Command                           as



    sbb     a, $e   Integer subtract with borrow, word
    scasb           Compare string data, byte
    scas            Compare string data, word
    shlb    a, $1   Shift left, byte
    shlb    a, cl   Shift left, byte
    shl     a, $1   Shift left, word
    shl     a, cl   Shift left, word
    shrb    a, $1   Shift right, byte
    shrb    a, cl   Shift right, byte
    shr     a, $1   Shift right, word
    shr     a, cl   Shift right, word
    stc             Set carry flag
    std             Set direction flag
    sti             Set interrupt enable flag
    stosb           Store string data, byte
    stos            Store string data, byte or word
    stosw           Store string data, word
    subb    r, a    Integer subtraction, byte
    sub     r, a    Integer subtraction, word
    subb    a, r    Integer subtraction, byte
    sub     a, r    Integer subtraction, word
    subb    a, $e   Integer subtraction, byte
    sub     a, $e   Integer subtraction, word
    testb   r, a    Logical compare, byte
    test    r, a    Logical compare, word
    testb   a, r    Logical compare, byte
    test    a, r    Logical compare, word
    testb   a, $e   Logical compare, byte
    test    a, $e   Logical compare, word
    wait            Wait until BUSY pin is inactive
    xcall   d, d    Far call, immediate four-byte address
    xchgb   r, a    Exchange memory, byte
    xchg    r, a    Exchange memory, word
    xicall          Far call, address at EA double word
    xijmp           Jump far, address at memory double word
    xjmp    d, d    Jump far, immediate four-byte address
    xlat            Table look-up translation
    xorb    r, a    Logical exclusive OR, byte
    xor     r, a    Logical exclusive OR, word
    xorb    a, r    Logical exclusive OR, byte
    xor     a, r    Logical exclusive OR, word
    xorb    a, $e   Logical exclusive OR, byte
    xor     a, $e   Logical exclusive OR, word
    xret            Return, intersegment

***** 80286 Instructions *****

The  following  instructions  implement  80286-specific  actions.
Programs that use them cannot be run on 8086-based machines.

    pusha           Push all general registers
    popa            Pop all general registers

    insb            Input byte from port DX to ES:(DI)
    ins             Input word from port DX to ES:(DI)


COHERENT Lexicon                                          Page 14



as                           Command                           as



    outsb           Output byte from port DX from ES:(DI)
    outs            Output word from port DX from ES:(DI)

    enter   $e, $e  Make stack frame for procedure
    leave           Tear down stack frame for procedure

    bound   r, e    Check array index against bounds

    sldt    a       Store Local Descriptor Table Register
    str     a       Store Task Register
    lldt    a       Load Local Descriptor Table Register
    ltr     a       Load Task Register
    verr    a       Verify a segment for reading
    verw    a       Verify a segment for writing

    sgdt    m       Store Global Descriptor Table register
    sidt    m       Store Interrupt Descriptor Table register
    lgdt    m       Load Global Descriptor Table register
    lidt    m       Load Interrupt Descriptor Table register
    smsw    a       Store Machine Status Word
    lmsw    a       Load Machine Status Word

    lar     r,a     Load access rights byte
    lsl     r,a     Load segment limit

    clts            Clear Task Switched Flag
    arpl            Adjust RPL field of Selector

    push    $e      Push sign extended byte
Also the $1 forms become $e  on  rol, rolb, ror, rorb, sal, salb,
shrb, shr,  and shrb.  This is because 8086  task of shifting and
rotating by an immediate value could only take an immediate value
of 1; however, on the 80286 the immediate value may be up to 31.

***** i8087 Op Codes *****

The assembler  can also  generate object  files for use  with the
i8087 mathematics  co-processor.  The following  listing presents
the assembly  language op codes for  this feature.  st0 indicates
floating point  register 0 and  st1 indicates any  floating point
register but 0; d is the same as in the above listing.


          d  Direct address
          st0Floating point register 0
          st1Any floating point register except 0


The following lists the i8087 instructions:
    fabs            Absolute value
    fadd    st0, st1Add real
    fadd    st1, st0Add real
    ffadd   d       Add real, float
    fdadd   d       Add real, double
    faddp           Add real and pop


COHERENT Lexicon                                          Page 15



as                           Command                           as



    faddp   st, st0 Add real and pop
    fbld    d       Load packed decimal (BCD)
    fbstp   d       Store packed decimal (BCD) and pop
    fchs            Change sign
    fclex           Clear exception
    fnclex          Clear exception
    fcom            Compare real
    ffcom   d       Compare real, float
    fdcom   d       Compare real, double
    fcomp           Compare real and pop
    fcomp   st1     Compare real and pop
    ffcomp  d       Compare real and pop, float
    fdcomp  d       Compare real and pop, double
    fcompp          Compare real and pop twice
    fdecstp         Decrement stack pointer
    fdisi           Disable interrupts
    fndisi          Disable interrupts, no operands
    fdiv    st0, st1Divide real
    fdiv    st1, st0Divide real
    ffdiv   d       Divide real, float
    fddiv   d       Divide real, double
    fdivp           Divide real and pop
    fdivp   st1     Divide real and pop
    fdivr   st0, st1Divide real reversed
    fdivr   st1, st0Divide real reversed
    ffdivr  d       Divide real reversed, float
    fddivr  d       Divide real reversed, double
    fdivrp          Divide real reversed and pop
    fdivrp  st1     Divide real reversed and pop
    feni            Enable interrupts
    fneni           Enable interrupts, no operands
    ffree   st1     Free register
    fiadd   d       Integer add
    fladd   d       Integer add, long
    ficom   d       Integer compare
    flcom   d       Integer compare, long
    ficomp  d       Integer compare and pop
    flcomp  d       Integer compare and pop, long
    fidiv   d       Integer divide
    fldiv   d       Integer divide, long
    fidivr  d       Integer divide reversed
    fldivr  d       Integer divide, long reversed
    fild    d       Integer load
    flld    d       Integer load, long
    fqld    d       Integer load, quad
    fimul   d       Integer multiply
    flmul   d       Integer multiply, long
    fincstp         Increment stack pointer
    finit           Initialize processor
    fninit          Initialize processor
    fist    d       Integer store
    flst    d       Integer store, long
    fistp   d       Integer store and pop
    flstp   d       Integer store and pop, long
    fqstp   d       Integer store and pop, quad


COHERENT Lexicon                                          Page 16



as                           Command                           as



    fisub   d       Integer subtract
    flsub   d       Integer subtract, long
    fisubr  d       Integer subtract reversed
    flsubr  d       Integer subtract reversed, long
    fld     st1     Load real
    ffld    d       Load real, float
    fdld    d       Load real, double
    ftld    d       Load real, temp
    fldcw   d       Load control word
    fldenv  d       Load environment
    fldlg2          Load log(10)2
    fldln2          Load log(e)2
    fldl2e          Load log(2)e
    fldl2t          Load log(2)10
    fldpi           Load pi
    fldz            Load +0.0
    fld1            Load +1.0
    fmul            Multiply real
    fmul    st0, st1Multiply real
    ffmul   st1, st0Multiply real, float
    fdmul   d       Multiply real, double
    fmulp   d       Multiply real and pop
    fnop    st1     No operation
    fpatan          Partial arctangent
    fprem           Partial remainder
    fptan           Partial tangent
    frndint         Round to integer
    frstor  d       Restore saved state
    fsave   d       Save state
    fnsave  d       Save state
    fscale          Scale
    fsetpm          Set protected mode
    fsqrt           Square root
    fst     st1     Store real
    ffst    d       Store real, float
    fdst    d       Store real, double
    fstcw   d       Store control word
    fnstcw  d       Store control word
    fstenv  d       Store environment
    fnstenv d       Store environment
    fstp    st1     Store real and pop
    ffstp   d       Store real and pop, float
    fdstp   d       Store real and pop, double
    ftstp   d       Store real and pop, temp
    fstsw   d       Store status word
    fnstsw  d       Store status word
    fsub    st0, st1Subtract real
    fsub    st1, st0Subtract real
    ffsub   d       Subtract real, float
    fdsub   d       Subtract real, double
    fsubp           Subtract real and pop
    fsubp   st1     Subtract real and pop
    fsubr   d       Subtract real reversed
    ffsubr  d       Subtract real reversed, float
    fdsubr  d       Subtract real reversed, double


COHERENT Lexicon                                          Page 17



as                           Command                           as



    fsubrp          Subtract real reversed and pop
    fsubrp  st1     Subtract real reversed and pop
    ftst            Test stack top against +0.0
    fwait           Wait while 8087 is busy
    fxam            Examine stack top
    fxch    st1     Exchange registers
    fxch            Exchange registers
    fxtract         Extract exponent and significance
    fyl2x           Y*log(2)X
    fyl2xp1         Y*log(2)(X+1)

***** C Compiler Conventions *****

as is often used to  write small functions that perform tasks not
easily or efficiently done  in C.  Such functions are intended to
be called  from a  C program.  As  long as the  assembly language
source code  follows compiler conventions,  the assembler routine
will be fully compatible with C functions.  These conventions are
(1) the names of external variables and (2) calling functions.

***** Naming Conventions *****

The C  compiler appends an underline character `_'  to the end of
every external  declared in a  C source file.   When referring to
any external  variable or function  declared in a  C source file,
append  an underscore  to the  name.  In  a similar  manner, when
defining a  function or variable  in an assembly  language source
file that is  to be accessed from a C  source file, append an un-
derline character.

***** Function-Calling Conventions *****

Function-calling conventions  deal with how  arguments are passed
to functions,  how values are  returned, and which  registers are
used for special purposes and must be protected.

***** Arguments *****

Function arguments  are passed on the stack.   They are pushed by
the calling  function, which also  removes them when   the called
function returns.   Looking at  the declaration of  the function,
the order in  which they are pushed onto the  stack is from right
to  left; that  is, the  C compiler pushes  the argument  list in
reverse order  of declaration.  The  instruction call to  jump to
the function  also pushes  the return  address, so that  when the
called routine  gains control the first argument  is found at of-
fset 2 from the stack pointer.

Integer  and pointer  arguments  are word  size,  and are  simply
pushed with a  push instruction.  Characters, although byte size,
are  not passed  as  bytes.  The  C language  requires that  char
variables be  promoted to the type int  before being passed.  The
promotion is  signed or  unsigned, depending  on the type  of the
char variable.  longs are pushed  one word at a time; the higher-
address word is pushed first.  This ensures that the words of the


COHERENT Lexicon                                          Page 18



as                           Command                           as



long are  in the  correct order on  the stack, because  the stack
grows toward low-addressed memory.

Passing floats, doubles, or structure arguments is more involved.
C requires  floats to be  promoted to and passed  as doubles,  so
this conversion must  be performed first.  doubles and structures
are passed so that as they sit on the stack, all bytes are in the
correct order;  this is analogous to the  passing of longs.  This
means, for  example, that  doubles may  be pushed with  four push
word instructions,  beginning with the highest  addressed word in
the 64-bit double, and ending with the lowest addressed word.

If in doubt about how to  apply any of this, try writing a simple
C program that uses what you  need, and compile it with the -vasm
option  to the  cc command.   This produces  an assembly-language
version of  the C  program, which can  be studied to  see exactly
what the compiler does, and mimicked to good effect.

***** Return Values *****


Functions return  values in various registers  according to their
type.  ints and pointers  are returned in the ax register.  chars
are returned  by first promoting  them to ints  and returning the
result in the ax register; effectively, this means that chars are
returned in  the al  register.  longs  are returned in  the dx:ax
register pair, with  the most significant word (also the high-ad-
dress word) in the dx register, and the least significant word in
the ax register.

floats, doubles,  and structures are  returned in a  more complex
fashion.  C  requires floats be returned as  doubles, so they are
converted.  doubles  are returned  in a special  eight-byte array
named _fpac (of course, in assembly language the name is _fpac_).
This array is defined by the compiler.  In the event that a func-
tion returns a structure, the contents of the structure are saved
in memory,  and the function returns a  pointer to that structure
in the  ax register.  The  calling function then  moves the bytes
into the actual destination.

Again, if in doubt about how to do this in assembly language, try
compiling a function with assembly language output to see how the
compiler does it.

***** Important Registers *****

Every function must preserve  the value of the bp register, which
is the caller's stack frame pointer.  Also, the compiler uses the
si  and di  registers  for register  variables, so  they must  be
preserved.

***** Example of an Assembly Language Program *****

The following  assembly language file, strchar.s  defines a func-
tion strchar that returns  the number of occurrences of a charac-


COHERENT Lexicon                                          Page 19



as                           Command                           as



ter in a string.


FILE: strchar.s

    /
    /
    /  Count and return the occurrences
    /  of a character in a string.
    /
    /     int
    /     strchar(s, c)
    /     char *s;
    /     int c;
    /
    /



        .globl     strchar_   / Make the name known externally.

        strchar_:
             push    si         / Standard C function
             push    di         / linkage. Save the
             push    bp         / si, di, and bp registers
             mov     bp, sp     / and set up new frame pointer.



             mov     si, 8(bp)  / String ptr -> si.
             mov     bx, 10(bp) / Char -> bx (actually bl).
             sub     ax, ax     / Clear ax (count register).
             sub     cx, cx     / Clear cx.



        0:   movb    cl, (si)   / Get character from string.
             jcxz    2f         / End of string?
             cmpb    bl, cl     / No. Do chars match?
             jnz     1f         / No.
             inc     ax         / Yes. Increment count.



        1:   inc     si         / Bump string pointer
             jmp     0b         / and loop again.



        2:   pop     bp         / Standard C return
             pop     di         / linkage. Restore
             pop     si         / saved registers and
             ret                / go home.




COHERENT Lexicon                                          Page 20



as                           Command                           as




The following  C program, main.c  uses strchar The  assembly lan-
guage listing  that follows, main.s  was produced from  main.c by
the -vasm  option in cc.   The listing has been  edited, and com-
ments added, to illustrate what is happening.


FILE: main.c

        main()
        {
            int n;
            n = strchar("aardvark", 'a');
        }



FILE: main.s

              .shri                / ``code'' program section.

              .globl   main_



        main_:

              .strn                / ``string'' program section.



        L2:   .byte    0x61        / This is the string
              .byte    0x61        / ``aardvark''
              .byte    0x72
              .byte    0x64
              .byte    0x76
              .byte    0x61
              .byte    0x72
              .byte    0x6B
              .byte    0x00



              .shri                / Back to ``code''

              push  si             / Standard C function
              push  di             / linkage.  Save registers,
              push  bp             / set up new frame pointer (bp),
              mov   bp, sp         / and make room on stack
              sub   sp, $0x02      / for the auto int, ``n''







COHERENT Lexicon                                          Page 21



as                           Command                           as



              mov   ax, $0x61      / Push the
              push  ax             / character `a'.
              mov   ax, $L2        / Push the address
              push  ax             / of the string ``aardvark''
              call  strchar_       / Function call.
              add   sp, $0x04      / Remove args from stack.
              mov   -0x02(bp), ax  / Assign result to auto `n'.



              mov   sp, bp         / Standard C return
              pop   bp             / linkage.  Adjust stack
              pop   di             / pointer, then restore
              pop   si             / registers and
              ret                  / go home.


***** Diagnostics *****

All errors  detected by the assembler are  reported on the screen
as an error message that is tagged with a line number.  If a sym-
bol is associated with the  error message (for example, if a sym-
bol is undefined), then the symbol's name is also given.  If more
than one  input file appears on the  command line, error messages
are tagged with the name of the source file.

If a listing is generated,  errors are reported on the listing in
the same  format, with the  error flags at the  left margin.  The
total number of  errors is displayed on the screen  at the end of
the assembly.

For a full listing of as error messages, see the tutorial for the
C compiler, which appears earlier in this manual.

***** See Also *****

cc, commands




















COHERENT Lexicon                                          Page 22


Typewritten Software • bear@typewritten.org • Edmonds, WA 98026