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