COHERENT manpages
This page displays the COHERENT manpage for as [i80386 assembler].
List of available manpages
Index
as -- Command
i80386 assembler
as [-o outfile] [-bfglnpwxX] infile
The 80386 version of as, the COHERENT assembler, assembles programs written
in any of several different dialects of assembly language into object
modules in COFF format, which can be linked with objects written by the
COHERENT C compiler. This version of as contains numerous features not
available with the COHERENT 286 assembler:
-> It serves as a flexible base for writing programs in native 80386
assembly language.
-> It assembles programs written in older flavors of COHERENT assembly
language.
-> It assembles programs written in UNIX assembly language.
-> Unlike the old COHERENT assembler and the UNIX assembler, 80386 as comes
with full macro faculities.
-> It is also designed to detect many of the common errors made by
assembly-language programmers.
The COHERENT system also includes the command asfix, which updates files
written in the COHERENT 286 assembler. asfix changes local and character
symbols to the new format.
Invoking the Assembler
as permits file names and options to be interspersed upon the command line.
It recognizes the following command-line options:
-Dname=string
Initialize string variable name to string. For example, the option
-Dname=some_string
is equivalent to:
name .define some_string
-Ename=value
Initialize variable name to value. For example, the option
-Ename=17
is equivalent to:
name .equ 17
-a Set alignment for data objects. For example, when this option is used
the express
.long 5
is automatically aligned to a four-byte boundary, but is left
unaligned without it.
-b Reverse bracket sense; that is, use () for expressions and [] for
code. For example:
movl $[2 * 5], (%eax)/ without -b
movl $(2 * 5), [%eax]/ with -b
-f Reverse the order of the operands, from UNIX-assembler form to that of
the Intel documentation or the 80286 version of as.
-g Make undefined symbols .globl.
-l Generate an output listing.
-n This option turns off the as mechanism for handling bugs in the 80386
chip. as tries to cope with known 80386 bugs by changing code at
appropriate points in its output. If these changes create problems
with your code, you can turn off the as bug-handler mechanism by using
the -n option to as.
-o outfile.o
Write the output into outfile.o. Note that the suffix .o must appear
in the output file's name, or the assembler will exit with an error
message. The default output file is infile.o.
-p Don't use `%' on register names; e.g., use ax, not %ax.
-Q Quiet: Suppress all error messages, no matter how awful an error they
indicate.
-w Disable warning messages.
-x Remove all non-global symbols from the common symbol output.
-X Remove all non-global symbols starting with .L from the common symbol
output.
as reads the environmental variables ASHEAD and ASTAIL and appends them to,
respectively, the beginning and the end of its command line. By setting
these variables, you can ensure that as always executes with the switches
that you want. For example, to ensure that as always executes with the -g
switch set, insert the following into your .profile:
export ASHEAD=-g
Lexography
A symbol consists of from one to 256 characters. The assembler defines a
character as being an alphabetic character, question mark, period, percent
sign, or underscore. Xyz, .20, and hi_there are legal symbols; whereas 85i
is not.
Like C, the as assembly language is case sensitive.
Local symbols begin with a question mark. These are recognizable (or
visible) only between nonlocal symbols. For example:
/ ?loop invisible here
abc mov $10, %cx
?loop add $1, %bx/ ?loop visible here
jcxz xyz
jmp ?loop
xyz:
/ ?loop invisible here
An octal number is defined just as in the C language: it consists of an
initial 0 plus two other numerals between 0 and 7. For example, 077 is a
legal octal number.
A hexadecimal number consists of an initial 0x or 0X plus two other
numerals: 0 through 9, a through f, or A through F. For example, 0x0F and
0Xa3 are legal hexadecimal numbers.
A binary number consists of an intial 0b or 0B followed by an indefinite
number 0's and 1's. For example, 0b01001010 is a legal binary number.
A decimal number begins with a numeral other than 0, followed by an
indefinite number of numerals between 0 and 9. For example, 109 is a legal
decimal number.
A floating-point number begins is a string of numerals, 0 through 9, with a
period or e within or at the end of it. It is like a C floating-point
number, except that it cannot begin with a period because a symbol may
begin with a period. For example, 123.456, 123456., and 17e26 are legal
floating-point numbers, but .123456 is not.
A character constant is enclosed between apostrophes, as in C. as
recognizes the same escape sequences as C. See the Lexicon article C
language for a table of these constants.
String constants are enclosed between quotation marks, as in the C
language, and use the same escape sequences as C. See the Lexicon article
C language for a table of these sequences.
Pseudo-Opcodes
as recognizes a rich set of pseudo-opcodes. These are not true assembly-
language opcodes, but are interpreted by the assembler; they are designed
to help make your life easier. The following briefly summarizes the
pseudo-opcodes.
.16............16-bit mode
.2byte.........Make unaligned short variables
.32............32-bit mode
.4byte.........Make unaligned long variables
.align.........Increment location counter to two- or four-byte aligned spot
.alignoff......Turn alignment off
.alignon.......Turn alignment on
.blkb..........Set tag in .data
.bracketnorm...Normal bracket sense -- see -b option
.brcketrev.....Reverse bracket sense -- see -b option
.bss...........Set tag in .bss
.bssd..........Set tag in .bss
.byte..........Make byte variables
.comm..........Set label as common
.data..........Change segment to .data
.def...........Reserved to set auxiliary symbol entries in a later release
.define........Define string constant
.dim...........Reserved to set auxiliary symbol entries in a later release
.double........Make double variables
.eject.........Force a page break
.else..........Connected to .if
.endef.........Reserved to set auxiliary symbol entries in a later release
.endi..........End .if
.endm..........End .macro definition
.endw..........End .while
.equ...........Define numeric constant
.errataoff.....Turn off chip errata fixes
.errataon......Turn on chip errata fixes
.even..........Increment location counter to byte-aligned spot
.fail..........Print error message
.file..........Reserved to set auxiliary symbol entries in a later release
.float.........Make float variables
.globl.........Declare names as visible to linker
.ident..........ident string
.if............Compile-time conditional
.include.......Include a file
.intelorder....Intel operand order -- see -f option
.lcomm.........Set name up as common
.line..........Reserved to set auxiliary symbol entries in a later release
.list..........Turn on listing (assumes -l option)
.llen..........Set print line length
.ln............Reserved to set auxiliary symbol entries in a later release
.long..........Make long variables
.macro.........Define a macro name
.mexit.........Exit current macro expansion
.mlist.........Toggle listing of macro expansion
.nolist........Turn off listing (assumes -l option)
.nopage........Turn off page breaks and titles
.number........Convert a string to a number.
.org...........Change location counter
.page..........Turn on page breaks and titles
.plen..........Set page length
.prvd..........Change segment to .data
.prvi..........Change segment to .text
.scl...........Reserved to set auxiliary symbol entries in a later release
.set...........Makes name equal to expr
.shift.........Shift macro parameters
.shrd..........Change segment to .data
.shri..........Change segment to .text
.size..........Reserved to set auxiliary symbol entries in a later release
.string........Convert a floating-point expression to a string
.strn..........Change segment to .data
.tag...........Reserved to set auxiliary symbol entries in a later release
.text..........Change segment to .text
.ttl...........Set page titles
.type..........Reserved to set auxiliary symbol entries in a later release
.undef.........Free string, numeric constant, or opcode
.unixorder.....Return normal order of operands; undoes .intelorder
.val...........Reserved to set auxiliary symbol entries in a later release
.value.........Make short variables
.version.......Comment string
.warn..........Print a warning message
.warnoff.......Turn off warning messages
.warnon........Turn on warning messages
.while.........Compile-time loop control
.word..........Make short variables
.zero..........Create zero-filled memory
Each pseudo-opcode is described in the following sections.
Input Format
An assembly-language program consists of a series of lines with the
following format:
[#][label] [opcode] [operands] [/ comment]
The optional `#' at the beginning of the line tells as not to replace any
.define symbols within the line. (These are described below.) Normally,
the assembler replaces all .define symbols in a line before it parses that
line. Without this option, a series of .defines could lead to awkward
results.
For example, the code
#%ecx .define xx
#xx .define (%ecx)
mov $3, %ecx
results in:
mov $3, (%ecx)
Like the C compiler, as will not go into an infinite loop if two .define
statements mirror each other.
A comment begins with a slash `/' and may include the entire line. Blank
lines are also legal.
Extra operands are not assumed to be comments. This is to tighten up error
checking for the convenience of new and part-time assembly-language
programmers.
Expression Format
The as macro assembler has mostly the same operators and precedence as the
C preprocessor. The exceptions are ?:, &&, ||, :, and `,' (which
are missing), `/' (which is spelled .div), and `%' (which is spelled .rem).
In addition, the macro assembler includes the following directives:
.defined, .sizeof, .segment, .parmct, .location, .string, .number, and
.float.
Expression bracketing is normally done by [], because () is used by the
operand format. This may be reversed by the -b option, described above.
The unary operators have the following priority:
.float .number .stringConversion
.defined .sizeof
.location .segmentInquiry
- Negation
! Logical negation
The binary operators have the following priority:
[]
* .div .rem Multiply, divide, remainder
+ - Add, subtract.
>> << Left shift , right shift
< > <= >= == !=Comparison
& AND
^ Exclusive OR
| OR
# Repeat
Most binary operators should be familiar to C programmers; the exception is
the #, which repeats an instruction N times. For example, the expression
.byte 5 # 3
produces five copies of byte 3, whereas the expression
.long 7 # 4
produces seven copies of the long `4'. Note that this operator has the
lowest precedence of all binary operators.
You can use an expression wherever you can use a number. This includes
address displacements, constants, and .if and .while statements. Integers
are internally 32 bits, floats are internally C doubles.
Like C, comparison operators return one for true and zero for false.
In addition, as provides string operators. Like C, the first element of a
string is indexed as zero. Unlike C, however, attempts to access past the
end of a string gives all zeroes. The following summarizes the as suite of
string operators:
string + string
Concatenate two strings. For example, "12" + "34" yields "1234".
string [ expr1, expr2 ]
Address a substring from expr1 to expr2. For example, "1234567"[1,3]
yields "234"; and "123"[1,10] yields "23".
string [ expr ]
Address a substring from expr to the end of the string. For example
"1234567"[5] yields "67".
.string expr
Convert a numeric expression to a string. For example, .string 123
gives "123".
.string float
Convert a floating-point expression to a string. For example, .string
0.5 * 3 gives "1.5"
.float string
Convert a string to a floating-point number.
.float expr
Convert a numeric expression to a floating-point number.
.number string
Convert a string to a number.
.number float
Convert a floating-point number to a number.
.string ( expr )
Return character at position expr as a number. For example, "123"(1)
gives two.
string1 @ string2
Return the position at which string2 begins within string1. For
example, "12345" @ "23" returns one; and "123" @ "jj" gives -1
(because ``jj'' does not appear within ``123'').
The unary operator : creates a label equal to the current location. It is
generally not needed. For example, the expression
connected .long 5
builds an aligned long, initializes it to five, and gives it the label
connected. However, the expression
unconnected: .long 5
builds the label unconnected at the current location, then builds an
aligned long with a value of five. Note that the label connected will be
on the five, whereas the label unconnected may be somewhere else if there
was alignment. For example, the expression
.align 4
lab1: lab2: lab3: .long 5
puts lab1, lab2, and lab3 on the long because it is already aligned.
Macros and Conditional Compilation
The as directive .macro lets you declare a macro that you can use through a
program. The directive .endm marks the end of a macro declaration.
A macro has the following form:
name .macro params
body of macro
.endm
The following example creates and uses the macro store:
store .macro xy,xz/ declare "store" with two parms: xy and xz
movl xy,%ecx
movl %ecx,(%eax)
movl xz,%ecx
movl %ecx,4(%eax)
.endm / end of macro
store 5,10/ moves 5 and 10 to where %eax points.
Macros can contain .if statements, and can even define other macros. For
example:
def .macro .name, to/ macro for defining other macros
name .macro
movl from, to
.endm
.endm
def frog, %eax, %ebx/ define the macro frog
frog / movel%eax, %ebx
as increments a count every time you expand any macro, and associates that
number with the macro. When the keyword .macno is used within a macro, as
translates it into that number. Thus, .macno is a unique number within
each macro expansion. This allows the generation of unique labels internal
to macros. For example:
stradd .macro str
.data
L\.macno .byte str, 0 / create a data item
.text
movl L\.macno, %eax / put its address into %eax
.endm
L\.macno becomes something like L51. Note that a `\' before any defined
symbol or macro name vanishes in the expansion pass.
To permit macros with indefinite parameter counts, the assembler offers the
reserved word .parmct and the command .shift. The former holds the number
of parameters passed to a macro, and the latter shifts the parameters one
position to the left. For example:
kall .macro fun, parm
.while .parmct > 1/ while more than one parm remains
push parm
.shift / parm 3 becomes parm 2, parm 4 parm 3 etc
call fun
.endm
The operators .if, .else, and .endi allow a program to implement compile-
time decisions. These may be inside or outside of macros. When a macro
exits, the assembler automatically closes all .if statments that had been
started within it. For example:
defy .macro
.if .defined y / if y has been defined true
.mexit / exits closing any if statements
.else
y .equ 1 / define y as 1
/ For UNIX compatibility
/ .set y, 1
/ produces the same result
.endm
When used with a label, the operator .defined is true if that label had
been defined in this pass. If the label is defined later, .defined can
still be used with it, but causes a phase error, as occurs in some
assemblers.
The operator .fail permits the flagging of errors. For example:
.if ! .defined y
.fail y is not defined
.endi
The operator .include permits the inclusion of files. For example:
.include somefile.h
Undefining Symbols or Opcodes
as Some software (e.g., the GNU C compiler) requires that opcodes be
recognized on column one and that opcodes be replacable by macros. The
command .undef un-defines all macros and opcodes. Once you have un-defined
an identifier, you can re-use it to name a macro or other data item. For
example, to use mov (which names an opcode) to name a macro, do the
following:
.undef mov
mov .macro foo, bar
movl foo, bar
.endm
Data-Definition Operators
The following describes the data-definition operators that as supports.
.byte expr
Define expr as an array of single bytes. expr can take any number of
forms, as shown by the following examples:
.byte 5, 2/ defines 2 bytes 0x05 and 0x02
.byte "Hello World", 0/ a zero-terminated Hello World
.byte 10 # 1/ 10 repetitions of 0x01
.word expr
Define expr as a word, that is, as a two-byte integer. For example:
.word .sizeof xx/ a short the size of xx
.word 50 * 50/ a short of 100
/ For UNIX compatability
/ .value 50 * 10
/ produces the same result.
.long expr
Define expr as a long (four-byte) integer. For example:
.long 10/ a long of 10
.comm name, length
Define a common variable named name, that is length bytes long. (See
the entry for .lcomm, below, for a discussion of what segment the
variable is stored.) If name is linked with another module that also
declares name but sets it to another length, the linker creates one
such variable and gives it the greater length of the two.
The linker deduces the alignment of a common variable from its length:
if the length of a common is divisible by four, it is aligned on a
four-byte boundary; if it is divisible by two, it is aligned on a two-
byte boundary. Otherwise, it is assumed to be unaligned. The linker
supports only three classes of alignment: four-byte, two-byte, and
unaligned.
A common variable is aligned according to its most strongly aligned
contributor. For example, if one module contributes a common variable
named xyz whose length is four bytes, and another contributes an xyz
whose length is five bytes, the resulting xyz is given a length of
eight bytes to satisfy the length requirement (at least five) and the
alignment requirement (four-byte boundary).
After the first linker pass, all common variables are placed at the
end of the .bss segment: first the four-byte-aligned variables, then
the two-byte-aligned, then the unaligned.
By default, as does not align its data objects. The command-line
option -a instructs as to align all data objects automatically.
.lcomm label, length
Same as comm, described above.
Please note that on a COFF-based system, it is not possible to put
common data into the .data section, even though the UNIX assembler
documentation claims that .comm does this. Both .comm and .lcomm
place data into the .bss.
The problem is that COFF format for common variables leaves no place
for information about alignment or segment. This creates two
problems. First, the lack of information about alignment forces COFF
to adopt the complex strategy of deducing alignment from length.
Second, the lack of information about segment compels COFF to store
all common variables in one segment, .bss being chosen.
.float expr
Define expr as a single-precision floating-point number. For example:
.float 1.5/ a float of 1.5
.double expr
Define expr as a double-precision floating-point number. For example:
.double 3.0 * 0.5 / a double of 1.5
Resetting the Location Counter
The instructions .org and .align reset the location counter. For example:
.org .+5 / Location counter to here plus 5
.org / Location counter to top of current section
.align 2/ Up to nearest two-byte boundary
The pseudo-opcodes .alignon and .alignoff respectively turn aligning on and
off.
As noted above, the command-line option -a instructs as to align all data
objects automatically.
The instructions .text, .data, and .bss reset the location counter to the
corresponding sections. Instructions are placed in the .text section,
initialized data in the .data section, and the .bss is reserved for
unitialized data. Placing information into the .bss results in an error.
Dynamic Linking
The Intel Binary Compatibility Standard dictates the way that as computes
addresses, to permit dynamic linking of objects.
In object files, all .data addresses must follow all .text addresses, and
all .bss address must follow all .data addresses. This allows dynamic
linking of object files, in which the object file is mapped, not read in
pieces.
In the as assembly language, .data and .text addresses are started from 0
for each module. At the end of assembly, during the output phase, as fixes
these addresses to make .data follow .text, and so on.
For example, if you have a conditional like
.if some_data_address > 0x300
as calculates the address for the .if statement from the beginning of its
segment; and the address is only corrected in the final output. Such
statements may appear to be working incorrectly.
Listing Commands
as prints a listing if you use its -l option. The following commands
modify the form of this listing.
.ttl string
Print string as the title to the command page. For example:
.ttl This is a page title
If you do not use this command, the assembler uses the file name for
the title. The first .ttl encountered in the assembly pass 0 is used
to set the first title. Subsequent .ttl commands reset the title
before printing.
.nopage
Turn off page breaks and titles.
.page
Turn on page breaks and titles.
.eject
Force a page break.
.nolist
Turn off the listing.
.list
Turn the listing back on.
.mlist off
Turn off the listing of macro expansions.
.mlist on
Turn on the listing of macro expansions.
Addressing Modes
as recognizes two modes of addressing: 16-bit mode and 32-bit mode. In 16-
bit mode, the address type and operand mode default to 16 bits; in 32-bit
mode they default to 32 bits. For example:
.16
movw %ax, (%si)# Is generated without escapes.
movl %eax, (%esi)# Has two escapes, address and operand
.32
movw %ax, (%si)# Has two escapes, address and operand
movl %eax, (%esi)# Is generated without escapes.
In 16-bit mode, the 16-bit addressing forms in table 17-2 of the Intel 386
Programmer's Manual are generated where they fit; otherwise, an address
escape is built and the 32-bit forms in tables 17-3 and 17-4 are used. In
32 bit mode, this is reversed.
as uses the following grammar in its addressing modes:
Eight-bit registers
r8 : %al | %cl | %dl | %bl | %ah | %ch | %dh | %bh;
16-bit registers
r16 : %ax | %cx | %dx | %bx | %sp | %bp | %si | %di;
32-bit registers
r32 : %eax | %ecx | %edx | %ebx | %esp | %ebp | %esi | %edi;
Segment registers
sreg : %es | %cs | %ss | %ds | %fs | %gs;
Control registers
ctlreg : %cr0 | %cr2 | %cr3;
Debug registers
dbreg : %dr0 | %dr1 | %dr2 | %dr3 | %dr6 | %dr7;
Test registers
testreg : %tr6 | %tr7;
m16 These addresses can have a segment prefix:
m16 : m16b | sreg ':' m16b;
m32 These addresses can have a segment prefix:
m32 : m32b | sreg ':' m32b;
rm16 These addresses can have a segment prefix or may be r16:
rm16 : rm16b | sreg ':' rm16b;
rm32 These addresses can have a segment prefix or may be r32:
rm32 : r32 | rm32b | sreg ':' rm32b;
rm8 These addresses can be rm32, rm16, or r8:
rm8 : r8 | rm16b | sreg ':' rm16b | rm32b | sreg ':' rm32b;
rm16b
displacement | (vx, vy) | displacement(vx, vy) |
displacement(vw) | (vz);
vx : %bx | %si;
vy : %si | %di;
vz : %si | %di | %bx;
rm32b
(va) | displacement(vb) | (, vb, scale) | (vb, scale)
| displacement(vb, scale) | (vb, vb, scale)
| displacement(vb, vb, scale);
va : %eax | %ecx | %edx | %ebx | %esi | %edi;
vb : %eax | %ecx | %edx | %ebx | %ebp | %esi | %edi;
vb : %eax | %ecx | %edx | %ebx | %ebp | %esp | %esi | %edi;
scale : 0 | 1 | 2 | 4 | 8;
mem32
A 32-bit memory address.
mem16
A 16-bit memory address.
reli Expand to eight-, 16-, or 32-bit relative addresses.
rel8 Eight-bit relative addresses.
rel16
Sixteen- or 32-bit relative addresses.
Using as To Create Debug Information
Some UNIX languages, such as gcc and gc++, produce assembly language rather
than object code. The following documents how to use as with such
compilers. Note that error checking is minimal, and that bad debug
information can corrupt the generated COFF output. This section must be
read with a listing of the header file coff.h for reference; or see the
Lexicon article coff.h.
The compiler starts with type and line information in a format much like
that of the desired COFF output files. It must break this down into lines
to ship through the assembler, and the assembler then must rebuild the
information into COFF format for output.
.file filename
This connects the object file to the original source file. If used,
this should be the first statement in the file. It produces a SYMENT
of n_sclass = C_FILE and an AUXENT with ae_fname = filename.
.def symbolName
This instruction initializes SYMENT with n_name = symbolName. If
there is a symbol by that name on the assembler's internal symbol
table, it is marked to prevent output to the symbol table. Any RELOC
references point to this table entry, so its n_value must be correct.
Because we assume that code of this kind is result of a compiler, we
assume it is correct. The following commands up to and including
.endef refer to this SYMENT.
.type number
This sets this SYMENT's n_type number. If number indicates a function,
DT_FCN, a LINENO record is built pointing at this SYMENT.
.val [symbol] [number]
This sets this SYMENT's n_value. If it is a symbol, it sets n_scnum to
the symbol's section number.
.scl number
This sets this SYMENT's n_sclass to number.
.dim number [, number [, number [, number]]]
This sets up to four entries in an AUXENT's ae_dimen. It describes
multidimensioned arrays to COFF. This command supports only four
dimensions because the COFF specifications are reliable only though
four dimensions.
.size n
This sets this AUXENT ae_size to n.
.tag name
This scans backwards on the SYMENTs for a matching n_name. It points
this ae_tagndx to that name's symbol number and that ae_endndx to the
next symbol number.
A good example is a struct: It would start with a SYMENT of type
T_STRUCT, then then have SYMENTs for its members. At the end, there
would be a C_EOS (end of structure) with a tag that gets us back to
the symbol's name. .tag connects the forward and backward pointers.
.line n
This sets the AUXENT's ae_lnno to n.
.endef
This marks the end of a SYMENT started by .def. If the n_sclass ==
C_EFCN (end of function), it builds the functions ae_fsize and
ae_endndx and does not output this SYMENT. If any AUXENT fields were
set, an AUXENT record follows this SYMENT.
.ln number
This builds a LINENO record with l_lnno = n and l_addr.l_paddr = the
current location.
Instructions
In matching instructions, as first looks up the name of the instruction. A
number of actual instructions will match that name. For example, btsw
matches 0xab and 0x0fab /5, and bts matches anything that matches btsw and
btsl.
as attempts to match operands to the instruction until a form is found that
will accept all the operands. If no form matches all the operands, as
prints the error message
Illegal combination of opcode and operands
The assembler at that point cannot say which operand is wrong because of
the nature of the 80386 instruction set.
If you see a great number of these messages, as's command-line option -f
may be in the wrong sense: although the opcode is valid and the operands
are valid, there is no form of this opcode that takes these operands in
this order.
as first attempts to match opcodes that do not require an operand-mode
escape: that is, in 80386 mode it attempts to match long-mode instructions
first, then short-mode instructions.
Register Usage
The COHERENT C compiler uses the following save/restore sequence for a
function, to set the frame pointer when the function contains no automatic
variables:
push %ebp
movl %ebp, %esp
If n bytes of autos are required, then it uses the following sequence:
enter $n, $0
It then executes the code
push %esi
push %edi
push %ebx
to preserve register variables as required: they are not saved/restored if
the function does not touch them. (This is why they are saved after the
frame adjust, not before). To restore register variables, it executes
pop %ebx
pop %edi
pop %esi
as required, followed by
leave
ret
Routines written in assembly language must preserve registers ebp, esi,
edi, and ebx; they may overwrite eax, ecx, and edx.
Absolute Symbols
as can create what COFF calls ``absolute symbols.'' For example
.globl x
x .equ 10
x .equ x * x / The last value of x in the module
leaves on the symbol table an absolute symbol for x of 100. For internal
reason, the .globl must preceed any .equ.
Opcodes
The following gives a table of the opcodes recognized by as. Note that the
opcode is sometimes followed by a slash and a number, or a letter. For
example,
D0 /4 salb con1, rm8
means opcode is 0xD0 place 4 in the register/opcode field of the modr/m
byte.
58 +r popl r32
means add the register number to 0x58.
Opcode Instruction OperandsDescription
37 aaa Adjust after addition
D5 0A aad Adjust AX before division
D4 0A aam Adjust AX after multiply
3F aas Adjust AL after subtraction
adc Add with carry
83 /2 adcl imm8s,rm32
83 /2 adcw imm8s,rm16
14 adcb imm8,al
15 adcw imm16,ax
15 adcl imm32,eax
15 adcl imm32
80 /2 adcb imm8,rm8
81 /2 adcw imm16,rm16
81 /2 adcl imm32,rm32
12 /r adcb rm8,r8
13 /r adcw rm16,r16
13 /r adcl rm32,r32
10 /r adcb r8,rm8
11 /r adcw r16,rm16
11 /r adcl r32,rm32
add Add
83 /0 addl imm8s,rm32
83 /0 addw imm8s,rm16
04 addb imm8,al
05 addw imm16,ax
05 addl imm32,eax
05 addl imm32
80 /0 addb imm8,rm8
81 /0 addw imm16,rm16
81 /0 addl imm32,rm32
02 /r addb rm8,r8
03 /r addw rm16,r16
03 /r addl rm32,r32
00 /r addb r8,rm8
01 /r addw r16,rm16
01 /r addl r32,rm32
and Logical AND
83 /4 andl imm8s,rm32
83 /4 andw imm8s,rm16
24 andb imm8,al
25 andw imm16,ax
25 andl imm32,eax
25 andl imm32
80 /4 andb imm8,rm8
81 /4 andw imm16,rm16
81 /4 andl imm32,rm32
22 /r andb rm8,r8
23 /r andw rm16,r16
23 /r andl rm32,r32
20 /r andb r8,rm8
21 /r andw r16,rm16
21 /r andl r32,rm32
63 /r arpl r16,rm16 Adjust RPL field of selector
bound Check if register is within bounds
62 /r boundw m16,r16
62 /r boundl m32,r32
bsf Bit scan forward
0F BC bsfw rm16,r16
0F BC bsfl rm32,r32
bsr Bit scan reverse
0F BD bsrw rm16,r16
0F BD bsrl rm32,r32
bt Save bit in carry flag
0F A3 btw r16,rm16
0F A3 btl r32,rm32
0F BA /4 btw imm8,rm16
0F BA /4 btl imm8,rm32
btc Bit test and complement
0F BB btcw r16,rm16
0F BB btcl r32,rm32
0F BA /7 btcw imm8,rm16
0F BA /7 btcl imm8,rm32
btr Bit test and reset
0F B3 btrw r16,rm16
0F B3 btrl r32,rm32
0F BA /6 btrw imm8,rm16
0F BA /6 btrl imm8,rm32
bts Bit test and set
0F AB btsw r16,rm16
0F AB btsl r32,rm32
0F BA /5 btsw imm8,rm16
0F BA /5 btsl imm8,rm32
E8 call reli Call Procedure
98 cbtw Sign extend AL
98 cbw Sign extend AL
99 cdq Double word to quad word
F8 clc Clear carry
FC cld Clear direction Flag
FA cli Clear interrupt Flag
99 cltd Double word to quad word
0F 06 clts Clear task-switched flag in CR0
F5 cmc Complement carry flag
cmp Compare
83 /7 cmpl imm8s,rm32
83 /7 cmpw imm8s,rm16
3C cmpb imm8,al
3D cmpw imm16,ax
3D cmpl imm32,eax
3D cmpl imm32
80 /7 cmpb imm8,rm8
81 /7 cmpw imm16,rm16
81 /7 cmpl imm32,rm32
3A /r cmpb rm8,r8
3B /r cmpw rm16,r16
3B /r cmpl rm32,r32
38 /r cmpb r8,rm8
39 /r cmpw r16,rm16
39 /r cmpl r32,rm32
A6 cmpsb Compare bytes
A7 cmpsl Compare long
A7 cmpsw Compare words
99 cwd Word to double word
98 cwde Sign extend AX
99 cwtd Word to double word
98 cwtl Sign extend AX
27 daa Decimal adjust after addition
2F das Decimal adjust after subtraction
dec Decrement by 1
48 +r decw r16
48 +r decl r32
FE /1 decb rm8
FF /1 decw rm16
FF /1 decl rm32
div Unsigned divide
F6 /6 divb rm8,al
F6 /6 divb rm8
F7 /6 divw rm16,ax
F7 /6 divw rm16
F7 /6 divl rm32,eax
F7 /6 divl rm32
C8 enter imm8,imm16Make stack frame for procedure
D9 F0 f2xm1 ST = 2 ** ST - 1
D9 E1 fabs ST = abs(ST)
fadd Floating add
D8 /0 fadds m32
DC /0 faddl m64
D8 C0 +r fadd fpreg,st0
D8 C0 +r fadd fpreg
DE C1 fadd
DC C0 +r fadd st0,fpreg
faddp Floating add and pop
DE C0 +r faddp st0,fpreg
DE C0 +r faddp fpreg
DE C1 faddp
DF /4 fbld m80 Load Binary Coded Decimal
DF /6 fbstp m80 Store Binary Coded Decimal and Pop
D9 E0 fchs Change Floating Sign
9B DB E2 fclex Clear floating point exception flags
fcom Floating Compare
D8 /2 fcoms m32
DC /2 fcoml m64
D8 D0 +r fcom fpreg,st0
D8 D0 +r fcom fpreg
D8 D1 fcom
fcomp Floating Compare and Pop
D8 /3 fcomps m32
DC /3 fcompl m64
D8 D8 +r fcomp fpreg
D8 D9 fcomp
DE D9 fcompp Floating Compare and pop twice
D9 FF fcos Cosine
D9 F6 fdecstp Decrement Stack Top Pointer
fdiv Floating divide
D8 /6 fdivs m32
DC /6 fdivl m64
D8 F0 +r fdiv fpreg,st0
D8 F0 +r fdiv fpreg
DE F1 fdiv
DC F0 +r fdiv st0,fpreg
fdivp Floating divide and pop
DE F0 +r fdivp st0,fpreg
DE F0 +r fdivp fpreg
DE F1 fdivp
fdivr Reverse floating divide
D8 /7 fdivrs m32
DC /7 fdivrl m64
D8 F8 +r fdivr fpreg,st0
D8 F8 +r fdivr fpreg
DE F9 fdivr
DC F8 +r fdivr st0,fpreg
fdivrp Reverse floating divide and pop
DE F8 +r fdivrp st0,fpreg
DE F8 +r fdivrp fpreg
DE F9 fdivrp
DD C0 +r ffree fpreg Free Floating Point Register
fiadd Add integer to float
DA /0 fiaddl m32
DE /0 fiadds m16
ficom Compare float to integer
DA /2 ficoml m32
DE /2 ficoms m16
ficomp Compare float to integer and pop
DA /3 ficompl m32
DE /3 ficomps m16
fidiv Divide float by integer
DA /6 fidivl m32
DE /6 fidivs m16
fidivr Reverse divide integer by float
DA /7 fidivrl m32
DE /7 fidivrs m16
fild Load integer
DB /0 fildl m32
DF /0 filds m16
DF /5 fildll m64
fimul Multiply integer to float
DA /1 fimull m32
DE /1 fimuls m16
D9 F7 fincstp Increment Stack Top Pointer
9B DB E3 finit Initialize Floating Point Unit
fist Store integer
DB /2 fistl m32
DF /2 fists m16
fistp Store integer and pop
DB /3 fistpl m32
DF /3 fistps m16
DF /7 fistpll m32
fisub Subtract integer from float
DA /4 fisubl m32
DE /4 fisubs m16
fisubr Reverse subtract integer from float
DA /5 fisubrl m32
DE /5 fisubrs m16
fld Load Real
D9 C0 +r fld fpreg
D9 /0 flds m32
DD /0 fldl m32
DB /5 fldt m64
D9 E8 fld1 Load Constant 1
D9 /5 fldcw m32 Load Floating Point Control Word
D9 /4 fldenv m32 Load FPU Environment
D9 EA fldl2e Load Constant log(e) base 2
D9 E9 fldl2t Load Constant log(10) base 2
D9 EC fldlg2 Load Constant log(2) base 10
D9 ED fldln2 Load Constant log(2) base e
D9 EB fldpi Load Constant pi
D9 EE fldz Load Constant 0.0
fmul Floating multiply
D8 /1 fmuls m32
DC /1 fmull m64
D8 C8 +r fmul fpreg,st0
D8 C8 +r fmul fpreg
DE C9 fmul
DC C8 +r fmul st0,fpreg
fmulp Floating multiply and pop
DE C8 +r fmulp st0,fpreg
DE C8 +r fmulp fpreg
DE C9 fmulp
DB E2 fnclex Clear floating point exception flags no wait
DB E3 fninit Initialize Floating Point Unit no wait
D9 D0 fnop No Operation
DD /6 fnsave m32 Store FPU State no wait
D9 /7 fnstcw m32 Store Control Word no wait
D9 /6 fnstenv m32 Store FPU Environment no wait
fnstsw Store Status Word no wait
DD /7 fnstsw m16
DF E0 fnstsw ax
D9 F3 fpatan Partial Arctangent
D9 F8 fprem Partial Remainder toward 0
D9 F5 fprem1 Partial Remainder < 1/2 modulus
D9 F2 fptan Partial Tangent
D9 FC frndint Round To Integer
DD /4 frstor m32 Resore FPU State
DB F4 frstpm set 287XL real mode (nop for 387/486)
9B DD /6 fsave m32 Store FPU State
D9 FD fscale Scale
DB E4 fsetpm set 287 protected mode (nop for 387/486)
D9 FE fsin Sine
D9 FB fsincos Sine and Cosine
D9 FA fsqrt Square Root
fst Store Real
DD D0 +r fst fpreg
D9 /2 fsts m32
DD /2 fstl m64
9B D9 /7 fstcw m32 Store Control Word
9B D9 /6 fstenv m32 Store FPU Environment
fstp Store Real and pop
DD D8 +r fstp fpreg
D9 /3 fstps m32
DD /3 fstpl m64
DB /7 fstpt m80
fstsw Store Status Word
9B DD /7 fstsw m16
9B DF E0 fstsw ax
fsub Floating subtract
D8 /4 fsubs m32
DC /4 fsubl m64
D8 E0 +r fsub fpreg,st0
D8 E0 +r fsub fpreg
DE E1 fsub
DC E0 +r fsub st0,fpreg
fsubp Floating subtract and pop
DE E0 +r fsubp st0,fpreg
DE E0 +r fsubp fpreg
DE E1 fsubp
fsubr Reverse floating subtract
D8 /5 fsubrs m32
DC /5 fsubrl m64
D8 E8 +r fsubr fpreg,st0
D8 E8 +r fsubr fpreg
DE E9 fsubr
DC E8 +r fsubr st0,fpreg
fsubrp Reverse floating subtract and pop
DE E8 +r fsubrp st0,fpreg
DE E8 +r fsubrp fpreg
DE E9 fsubrp
D9 E4 ftst Test
fucom Unordered compare real
DD E0 +r fucom st0,fpreg
DD E0 +r fucom fpreg
DD E1 fucom
fucomp Unordered compare real and pop
DD E8 +r fucomp st0,fpreg
DD E8 +r fucomp fpreg
DD E9 fucomp
DA E9 fucompp Unordered compare %st %st1 and pop twice
9B fwait Wait for coprocessor
D9 E5 fxam Examine
fxch Floating exchange
D9 C8 +r fxch st0,fpreg
D9 C8 +r fxch fpreg,st0
D9 C8 +r fxch fpreg
D9 C9 fxch
D9 F4 fxtract Extract Exponent and Significand
D9 F1 fyl2x %st1 * log(%st) base 2
D9 F9 fyl2xp1 %st1 * log(%st + 1.0) base 2
F4 hlt Halt
FF /2 icall rm32 Call indirect
idiv Signed divide
F6 /7 idivb rm8,al
F6 /7 idivb rm8
F7 /7 idivw rm16,ax
F7 /7 idivw rm16
F7 /7 idivl rm32,eax
F7 /7 idivl rm32
FF /4 ijmp rm32 Jump indirect
FF /3 ilcall m32 Long call indirect
FF /5 iljmp m32 Long jump indirect
imul Signed multiply
F6 /5 imulb rm8,al
F6 /5 imulb rm8
F7 /5 imulw rm16,ax
F7 /5 imulw rm16
F7 /5 imull rm32,eax
F7 /5 imull rm32
0F AF /r imulw rm16,r16
0F AF /r imull rm32,r32
6B imulw imm8s,rm16,r16
6B imull imm8s,rm32,r32
6B /r imulw imm8s,r16
6B /r imull imm8s,r32
69 imulw imm16,rm16,r16
69 imull imm32,rm32,r32
69 /r imulw imm16,r16
69 /r imull imm32,r32
in Input from port
E4 inb imm8
E5 inw imm8
E5 inl imm8
EC inb (dx)
ED inw (dx)
ED inl (dx)
inc Increment by one
40 +r incw r16
40 +r incl r32
FE /0 incb rm8
FF /0 incw rm16
FF /0 incl rm32
6C insb Input byte from port into ES:(E)DI
6C insb (dx) Input byte from port into ES:(E)DI
6D insl Input long from port into ES:(E)DI
6D insl (dx) Input long from port into ES:(E)DI
6D insw Input word from port into ES:(E)DI
6D insw (dx) Input word from port into ES:(E)DI
CC int con3 Interrupt 3
CD int imm8 Interrupt
CE into Int 4 if overflow is 1
CF iret Interrupt return
CF iretd Different mode different opcode ?
07 ja reli Jump if above
03 jae reli Jump if above or equal
02 jb reli Jump if below
06 jbe reli Jump if below or equal
02 jc reli Jump if carry
E3 jcxz rel8 Jump if CX is zero
04 je reli Jump if equal
E3 jecxz rel8 Jump if CX is zero
0F jg reli Jump if greater
0D jge reli Jump if greater or equal
0C jl reli Jump if less
0E jle reli Jump if less or equal
E9 jmp reli Jump absolute
06 jna reli Jump if not above
02 jnae reli Jump if not above or equal
03 jnb reli Jump if not below
07 jnbe reli Jump if not below or equal
03 jnc reli Jump if no carry
05 jne reli Jump if not equal
0E jng reli Jump if not greater
0C jnge reli Jump if not greater or equal
0D jnl reli Jump if not less
0F jnle reli Jump if not less or equal
01 jno reli Jump if not overflow
0B jnp reli Jump if not parity
09 jns reli Jump if not sign
05 jnz reli Jump if not zero
00 jo reli Jump if overflow
0A jp reli Jump if parity
0A jpe reli Jump if parity even
0B jpo reli Jump if parity odd
08 js reli Jump if sign
04 jz reli Jump if zero
04 jz reli Jump if zero
9F lahf Load flags into AH register
lar Load access rights byte
0F 02 /r larw rm16,r16
0F 02 /r larl rm32,r32
9A lcall imm16x,imm32Long call
lds load full pointer DS:r16
C5 /r ldsw m16,r16
C5 /r ldsl m32,r32
lea Load effective address
8D /r leaw m16,r16
8D /r leal m32,r32
C9 leave High level procedure exit
les Load full pointer ES:r16
C4 /r lesw m16,r16
C4 /r lesl m32,r32
lfs Load full pointer FS:r16
0F B4 /r lfsw m16,r16
0F B4 /r lfsl m32,r32
lgdt Load m into DGTR
0F 01 /2 lgdtw m16
0F 01 /2 lgdtl m32
lgs Load full pointer GS:r16
0F B5 /r lgsw m16,r16
0F B5 /r lgsl m32,r32
lidt Load m into IDTR
0F 01 /3 lidtw m16
0F 01 /3 lidtl m32
EA ljmp imm16x,imm32Long jump
0F 00 /2 lldt rm16 Load local descriptor table register
0F 01 /6 lmsw rm16 Load machine status word
F0 lock Assert lock signal for next instruction
AC lodsb Load string operand byte
AD lodsl Load string operand long
AD lodsw Load string operand word
E2 loop rel8 Dec count jmp if count <> 0
E1 loope rel8 Dec count jmp if count <> 0 and ZF = 1
E0 loopne rel8 Dec count jmp if count <> 0 and ZF = 0
E0 loopnz rel8 Dec count jmp if count <> 0 and ZF = 0
E1 loopz rel8 Dec count jmp if count <> 0 and ZF = 1
CB lret Far return
CA lret imm16 Far return pop imm16 bytes of parms
lsl Load segment limit
0F 03 /r lslw rm16,r16
0F 03 /r lsll rm32,r32
lss Load full pointer SS:r16
0F B2 /r lssw m16,r16
0F B2 /r lssl m32,r32
0F 00 /3 ltr rm16 Load task register
mov Move data
A0 movb moffs,al
A1 movw moffs,ax
A1 movl moffs,eax
A2 movb al,moffs
A3 movw ax,moffs
A3 movl eax,moffs
8A /r movb rm8,r8
8B /r movw rm16,r16
8B /r movl rm32,r32
88 /r movb r8,rm8
89 /r movw r16,rm16
89 /r movl r32,rm32
8C /r movw sreg,rm16
8E /r movw rm16,sreg
B0 +r movb imm8,r8
B8 +r movw imm16,r16
B8 +r movl imm32,r32
C6 movb imm8,rm8
C7 movw imm16,rm16
C7 movl imm32,rm32
0F 20 /r movl ctlreg,r32
0F 22 /r movl r32,ctlreg
0F 21 /r movl dbreg,r32
0F 23 /r movl r32,dbreg
0F 24 /r movl treg,r32
0F 26 /r movl r32,treg
A4 movsb Move bytes
A5 movsl Move longs
A5 movsw Move words
movsx Move with sign extend
0F BE /r movsxb rm8,r16
0F BE /r movsxb rm8,r32
0F BF /r movsxw rm16,r32
0F BE /r movsbw rm8,r16
0F BE /r movsbl rm8,r32
0F BF /r movswl rm16,r32
movzx Move with zero extend
0F B6 /r movzxb rm8,r16
0F B6 /r movzxb rm8,r32
0F B7 /r movzxw rm16,r32
0F B6 /r movzbw rm8,r16
0F B6 /r movzbl rm8,r32
0F B7 /r movzwl rm16,r32
mul Unsigned multiply
F6 /4 mulb rm8,al
F6 /4 mulb rm8
F7 /4 mulw rm16,ax
F7 /4 mulw rm16
F7 /4 mull rm32,eax
F7 /4 mull rm32
neg Negate
F6 /3 negb rm8
F7 /3 negw rm16
F7 /3 negl rm32
90 nop No operation
not Invert bits
F6 /2 notb rm8
F7 /2 notw rm16
F7 /2 notl rm32
or Logical inclusive OR
83 /1 orl imm8s,rm32
83 /1 orw imm8s,rm16
0C orb imm8,al
0D orw imm16,ax
0D orl imm32,eax
0D orl imm32
80 /1 orb imm8,rm8
81 /1 orw imm16,rm16
81 /1 orl imm32,rm32
0A /r orb rm8,r8
0B /r orw rm16,r16
0B /r orl rm32,r32
08 /r orb r8,rm8
09 /r orw r16,rm16
09 /r orl r32,rm32
out Output from port
E6 outb imm8
E7 outw imm8
E7 outl imm8
EE outb (dx)
EF outw (dx)
EF outl (dx)
6E outsb Output byte to port into ES:(E)DI
6F outsl Output long to port into ES:(E)DI
6F outsw Output word to port into ES:(E)DI
pop Pop a word from the stack
58 +r popw r16
58 +r popl r32
1F popw ds
07 popw es
17 popw ss
0F A1 popw fs
0F A9 popw gs
8F /0 popw m16
8F /0 popl m32
popa Pop all
61 popaw
61 popal
popf Pop stack into flags
9D popfw
9D popfl
push Push a word on the stack
50 +r pushw r16
50 +r pushl r32
6A pushb imm8s
68 pushw imm16
68 pushl imm32
0E pushw cs
1E pushw ds
06 pushw es
16 pushw ss
0F A0 pushw fs
0F A8 pushw gs
FF /6 pushw m16
FF /6 pushl m32
pusha Push all
60 pushaw
60 pushal
pushf Push flags
9C pushfw
9C pushfl
rcl Rotate carry left
D0 /2 rclb con1,rm8
D0 /2 rclb rm8
D2 /2 rclb cl,rm8
C0 /2 rclb imm8,rm8
D1 /2 rclw con1,rm16
D1 /2 rclw rm16
D3 /2 rclw cl,rm16
C1 /2 rclw imm8,rm16
D1 /2 rcll con1,rm32
D1 /2 rcll rm32
D3 /2 rcll cl,rm32
C1 /2 rcll imm8,rm32
rcr Rotate carry right
D0 /3 rcrb con1,rm8
D0 /3 rcrb rm8
D2 /3 rcrb cl,rm8
C0 /3 rcrb imm8,rm8
D1 /3 rcrw con1,rm16
D1 /3 rcrw rm16
D3 /3 rcrw cl,rm16
C1 /3 rcrw imm8,rm16
D1 /3 rcrl con1,rm32
D1 /3 rcrl rm32
D3 /3 rcrl cl,rm32
C1 /3 rcrl imm8,rm32
F3 rep rep following instruction CX times
F3 repe repe following instruction CX times or eq
F2 repne repne following instruction CX times or ne
F2 repnz alternate name for repnz
F3 repz alternate name for repe
C3 ret Return
C2 ret imm16 Return pop imm16 bytes of parms
rol Rotate left
D0 /0 rolb con1,rm8
D0 /0 rolb rm8
D2 /0 rolb cl,rm8
C0 /0 rolb imm8,rm8
D1 /0 rolw con1,rm16
D1 /0 rolw rm16
D3 /0 rolw cl,rm16
C1 /0 rolw imm8,rm16
D1 /0 roll con1,rm32
D1 /0 roll rm32
D3 /0 roll cl,rm32
C1 /0 roll imm8,rm32
ror Rotate right
D0 /1 rorb con1,rm8
D0 /1 rorb rm8
D2 /1 rorb cl,rm8
C0 /1 rorb imm8,rm8
D1 /1 rorw con1,rm16
D1 /1 rorw rm16
D3 /1 rorw cl,rm16
C1 /1 rorw imm8,rm16
D1 /1 rorl con1,rm32
D1 /1 rorl rm32
D3 /1 rorl cl,rm32
C1 /1 rorl imm8,rm32
9E sahf Store AH into flags
sal Shift arithmetic left
D0 /4 salb con1,rm8
D0 /4 salb rm8
D2 /4 salb cl,rm8
C0 /4 salb imm8,rm8
D1 /4 salw con1,rm16
D1 /4 salw rm16
D3 /4 salw cl,rm16
C1 /4 salw imm8,rm16
D1 /4 sall con1,rm32
D1 /4 sall rm32
D3 /4 sall cl,rm32
C1 /4 sall imm8,rm32
sar Shift arithmetic right
D0 /7 sarb con1,rm8
D0 /7 sarb rm8
D2 /7 sarb cl,rm8
C0 /7 sarb imm8,rm8
D1 /7 sarw con1,rm16
D1 /7 sarw rm16
D3 /7 sarw cl,rm16
C1 /7 sarw imm8,rm16
D1 /7 sarl con1,rm32
D1 /7 sarl rm32
D3 /7 sarl cl,rm32
C1 /7 sarl imm8,rm32
sbb Subtract with borrow
83 /3 sbbl imm8s,rm32
83 /3 sbbw imm8s,rm16
1C sbbb imm8,al
1D sbbw imm16,ax
1D sbbl imm32,eax
1D sbbl imm32
80 /3 sbbb imm8,rm8
81 /3 sbbw imm16,rm16
81 /3 sbbl imm32,rm32
1A /r sbbb rm8,r8
1B /r sbbw rm16,r16
1B /r sbbl rm32,r32
18 /r sbbb r8,rm8
19 /r sbbw r16,rm16
19 /r sbbl r32,rm32
AE scasb Compare string bytes
AF scasl Compare string longs
AF scasw Compare string words
0F 97 seta rm8 Set byte if above
0F 93 setae rm8 Set byte if above or equal
0F 92 setb rm8 Set byte if below
0F 96 setbe rm8 Set byte if below or equal
0F 92 setc rm8 Set byte if carry
0F 94 sete rm8 Set byte if equal
0F 9F setg rm8 Set byte if greater
0F 9D setge rm8 Set byte if greater or equal
0F 9C setl rm8 Set byte if less
0F 9E setle rm8 Set byte if less or equal
0F 96 setna rm8 Set byte if not above
0F 92 setnae rm8 Set byte if not above or equal
0F 93 setnb rm8 Set byte if not below
0F 97 setnbe rm8 Set byte if not below or equal
0F 93 setnc rm8 Set byte if no carry
0F 95 setne rm8 Set byte if not equal
0F 9E setng rm8 Set byte if not greater
0F 9C setnge rm8 Set byte if not greater or equal
0F 9D setnl rm8 Set byte if not less
0F 9F setnle rm8 Set byte if not less or equal
0F 91 setno rm8 Set byte if not overflow
0F 9B setnp rm8 Set byte if not parity
0F 99 setns rm8 Set byte if not sign
0F 95 setnz rm8 Set byte if not zero
0F 90 seto rm8 Set byte if overflow
0F 9A setp rm8 Set byte if parity
0F 9A setpe rm8 Set byte if parity even
0F 9B setpo rm8 Set byte if parity odd
0F 98 sets rm8 Set byte if sign
0F 94 setz rm8 Set byte if zero
0F 94 setz rm8 Set byte if zero
0F 01 /0 sgdt mem32 Store gdtr
shl Shift arithmetic left
D0 /4 shlb con1,rm8
D0 /4 shlb rm8
D2 /4 shlb cl,rm8
C0 /4 shlb imm8,rm8
D1 /4 shlw con1,rm16
D1 /4 shlw rm16
D3 /4 shlw cl,rm16
C1 /4 shlw imm8,rm16
D1 /4 shll con1,rm32
D1 /4 shll rm32
D3 /4 shll cl,rm32
C1 /4 shll imm8,rm32
shld Shift double precision left
0F A4 shldw imm8,r16,rm16
0F A4 shldl imm8,r32,rm32
0F A5 shldw cl,r16,rm16
0F A5 shldl cl,r32,rm32
shr Shift right
D0 /5 shrb con1,rm8
D0 /5 shrb rm8
D2 /5 shrb cl,rm8
C0 /5 shrb imm8,rm8
D1 /5 shrw con1,rm16
D1 /5 shrw rm16
D3 /5 shrw cl,rm16
C1 /5 shrw imm8,rm16
D1 /5 shrl con1,rm32
D1 /5 shrl rm32
D3 /5 shrl cl,rm32
C1 /5 shrl imm8,rm32
shrd Shift double precision right
0F AC shrdw imm8,r16,rm16
0F AC shrdl imm8,r32,rm32
0F AD shrdw cl,r16,rm16
0F AD shrdl cl,r32,rm32
0F AD shrdw r16,rm16
0F AD shrdl r32,rm32
0F 01 /1 sidt mem32 Store idtr
0F 00 /0 sldt rm16 Store ldtr to EA word
0F 01 /4 smsw rm16 Store machine status to EA word
F9 stc Set carry flag
FD std Clear direction flag
FB sti Set interrupt flag
AA stosb Store string byte
AB stosl Store string long
AB stosw Store string word
0F 00 /1 str Store task register
sub Subtract
83 /5 subl imm8s,rm32
83 /5 subw imm8s,rm16
2C subb imm8,al
2D subw imm16,ax
2D subl imm32,eax
2D subl imm32
80 /5 subb imm8,rm8
81 /5 subw imm16,rm16
81 /5 subl imm32,rm32
2A /r subb rm8,r8
2B /r subw rm16,r16
2B /r subl rm32,r32
28 /r subb r8,rm8
29 /r subw r16,rm16
29 /r subl r32,rm32
test Logical compare
A8 testb imm8,al
A9 testw imm16,ax
A9 testl imm32,eax
A9 testl imm32
F6 /0 testb imm8,rm8
F7 /0 testw imm16,rm16
F7 /0 testl imm32,rm32
84 /r testb r8,rm8
85 /r testw r16,rm16
85 /r testl r32,rm32
0F 00 /4 verr rm16 Verify segment for read
0F 00 /5 verw rm16 Verify segment for write
9B wait Wait for coprocessor
xchg Exchange register
90 +r xchgw r16,ax
90 +r xchgw ax,r16
90 +r xchgl r32,eax
90 +r xchgl r32
90 +r xchgl eax,r32
86 /r xchgb rm8,r8
87 /r xchgw rm16,r16
87 /r xchgl rm32,r32
86 /r xchgb r8,rm8
87 /r xchgw r16,rm16
87 /r xchgl r32,rm32
D7 xlat Table lookup translation
D7 xlatb Table lookup translation
xor Logical exclusive OR
83 /6 xorl imm8s,rm32
83 /6 xorw imm8s,rm16
34 xorb imm8,al
35 xorw imm16,ax
35 xorl imm32,eax
35 xorl imm32
80 /6 xorb imm8,rm8
81 /6 xorw imm16,rm16
81 /6 xorl imm32,rm32
32 /r xorb rm8,r8
33 /r xorw rm16,r16
33 /r xorl rm32,r32
30 /r xorb r8,rm8
31 /r xorw r16,rm16
31 /r xorl r32,rm32
Using C to Prototype Assembly Language
The COHERENT C compiler includes a switch, -S, that translates C code into
COHERENT assembly language. The assembly language it produces cannot be
directly assembled, but you can examine it to see just what the compiler
does under given circumstances; and you can use it to prototype a routine
in assembly language.
Suppose, for example, that you wish to write a function that takes two
parameters: an integer, which gives a port number to read from; and an
address where the data should go. Start by writing a C function with the
correct calling sequence. For example, the following function is in a file
called proto.c:
readstuff(addr, port)
register char *addr;
int port;
{
register int dx = port;
char *foo = addr;
}
Compile it with the following command line:
cc -S proto.c
This produces file proto.s, which contains the following:
/ module name foo
.alignoff
.text
.globl readstuff
readstuff:
push %ebp
movl %ebp, %esp
push %esi
push %edi
push %ebx
movl %ebx, 8(%ebp)
movl %esi, 12(%ebp)
movl %edi, %ebx
pop %ebx
pop %edi
pop %esi
leave
ret
.align 4
This is your prototype. You can easily modify it into what you want; for
example:
/ This will only work if you install it as a driver.
/ As the operating system will protect itself if
/ Ordinary users try to access ports. Ask about our
/ Device driver kits.
.text
.globl readstuff
readstuff:
push %ebp
movl %ebp, %esp
push %edi / Save the edi for the caller
movl %edx, 8(%ebp) / Get the port number
movl %edi, 12(%ebp) / Get the user address
insb / Read port (%dx) to %es:%edi
pop %edi / See 386 calling conventions
leave
ret
Example
The following example echoes strings onto your screen.
/ sstatic void foo(i) { printf("Parm is %d\n", i); }
.text
.L2: .byte "Parm is %d0, 0
foo:
push %ebp / set up stack frame
movl %ebp, %esp
push 8(%ebp) / push parms from right to left
push $.L2
call printf
leave / %esp <- %ebp; pop %ebp
ret
/ main() { foo(5); }
.globl main
main:
push %ebp
movl %ebp, %esp
push $5
call foo
leave
ret
See Also
asfix,
calling conventions,
cc,
cdmp,
commands
Intel Corporation: 386 DX Programmer's Reference Manual. Santa Clara, CA:
Intel Corporation, 1990. Highly recommended.
Diagnostics
The following gives the error messages returned by as. The messages are in
alphabetical order. Each message is marked as to its degree of severity: A
fatal message usually indicates a condition that caused the assembler to
terminate execution. Often, they indicate internal problems in the
assembler. An error message points to a condition in the source code that
the assembler cannot resolve. This almost always occurs when the program
does something illegal. A warning message points out code that is
compilable, but may produce trouble when the program is executed.
.align must be 1, 2 or 4 (error)
.align must work after the link. These are the only values for which
this can be true.
Ambiguous operand length, n bytes selected (warning)
The assembler cannot tell the operand length by looking at the opcode
and the operands. You may want to do something like change mov to
movl.
Arithmetic between addresses on different segments (error)
You may only add or subtract addresses if they are in the same
segment.
Bad scale (error)
Address scale must be 0, 1, 2, 4, or 8.
16 bit addressing mode used in 32 bit code (warning)
You probably don't want to do this. For example, you may want to say
(%esi), not (%si).
32 bit addressing mode used in 16 bit code (warning)
You probably don't want to do this. For example, you may want to say
(%si), not (%esi).
Cannot fopen(string, string) (fatal)
Cannot insert \0 in string (error)
NUL (\0) terminates strings. Instead of
.byte "hello\n\0"
use:
.byte "hello\n", 0
Character constant n long (error)
Character constants must be one byte long.
.comm must have tag (error)
The format of .comm is .comm name, size.
Command option 'c' missing its argument (fatal)
Data defined in .bss (error)
The .bss segment is uninitialized data. You cannot place actual
values there.
.define must have a label (error)
Duplicate symbol 'string' (error)
symbol is defined on two different lines.
.else detected logic type n (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
End of line after backslash reading parm (error)
Macro parmeters may not be broken up with backslash.
End of line after backslash (error)
End of line detected in character constant (error)
End of line detected in string (error)
End of macro building .while (error)
A .macro ended while reading in a .while loop.
.endi detected logic type n (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
Error in binary number (error)
Error in octal number (error)
Found n parms expected n (error)
Illegal combination of opcode and operands (error)
Although the opcode is valid and the operands are valid, there is no
form of this opcode which takes this combination of operands in this
order.
Illegal use of local symbol (error)
Illegal use of of predefined symbol string. (error)
Improper instruction following lock (warning)
Only a few instructions are valid after a lock instruction. See your
machine documentation for details.
Improper instruction following rep (warning)
Only a few instructions are valid after a rep instruction. See your
machine documentation for details.
Indirect mode on invalid instruction (error)
Indirection is only allowed on call and jump near instructions.
Internal error relative branch logic (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
Invalid .mlist option must be on or off (error)
Invalid character 'c' string at position n (error)
Invalid character 0x0xn string at position n (error)
Invalid data type, must be symbol (error)
Invalid floating point register number (error)
Invalid opcode: 'string' (error)
The string in the opcode position is not one of our opcodes or one of
your macros.
Invalid operand type (error)
string is an improper register in this context (error)
Label ignored (error)
This statement cannot take a label.
Label on invalid operator (error)
Label required (error)
Length n string range exceeded (error)
Strings may not exceed 32 kilobytes.
Logic error in macro def 'string' n (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
Logic error in umark (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
Macro definition must have a label (error)
.mexit not in macro (error)
Missing .endi (error)
Input ended leaving .if open.
Missing .endm (error)
Input ended leaving .macro open.
Missing .endw (error)
Input ended leaving .while open.
Mixed 386/286 addressing modes (error)
No opcode allows mixed 286 and 386 addressing modes.
Mixed 386/286 data modes (error)
No 386 opcode allows mixed 286 and 386 data modes.
Mixed length addressing registers (error)
Addressing registers must both be the same length.
more than one file to process (fatal)
The assembler will only process one file at a time.
Name required (error)
The format of set is .set name, value
no work (fatal)
There were no files listed on the command line.
NULL address in relative branch (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
Octal number n truncated to char (error)
An octal number in a string was too big.
Optype n in lex (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
Org to invalid value (error)
You may not .org to doubles or strings.
Org to wrong segment (error)
You must .org to the current segment.
Out of space (fatal)
A call to malloc() failed. The typical large consumers of RAM are
macros and .defines; symbols consume less. Can you break your
assembly into smaller pieces? Could you be in some sort of endless
recursion or loop?
Parm n not found (error)
An attempt to .shift too far has been made.
.parmct not in macro (error)
.parmct returns the number of parameters in the current macro.
Phase error 'string' (error)
A symbol is defined one way in one phase of the assembly and another
way in the next phase.
Redefinition of 'string' (error)
An assembler internal symbol is being redefined.
Seek error on object file (fatal)
Seek error on object file (fatal)
.shift not in macro (error)
.shift shifts macro parameters. It has no meaning outside a macro.
String must be on .byte (error)
For example:
.byte "This is how we place a string", 0
Symbol may not be double (error)
You may not convert a symbol to a floating-point value.
Symbol may not be float (error)
You may not convert a symbol to a floating-point value.
Syntax error (error)
The syntax of this statement makes no sense to the parser. This can
be a variety of problems.
Table error kind 0xn detected (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
This code may not work the same way on all chips (warning)
Some chips may not execute this code as expected.
Too many operands (error)
No 386 opcode has more than three operands.
Undefined symbol 'string' (error)
A symbol was used without defining it or using a -g option. You must
define local symbols.
Unexpected .else statement (error)
Unexpected .endi statement (error)
Unexpected .endm ignored (error)
Unexpected .endw (error)
Unexpected return from parser (fatal)
Logic error in assembler. Please report this problem to Mark Williams
technical support.
Unknown command option c (fatal)
Unlikely output file 'string' (fatal)
Output file-names should have .o suffixes. Because this is generally
a typographical error, as aborts to avoid overwriting an important
file.
Unmatched 'c' (error)
A delimeter, [, (, ), or ] is unmatched in this command.
Unmatched bracket in parmeter (error)
Line ended leaving an open bracket or parenthesis.
Write error on object file (fatal)
as could not write the object module. This error can have any of
several causes; the most common is that you lack permission to write
into the current directory, or you lack permission to overwrite an
existing file of the same name.
Notes
We have designed as to ease porting of programs written in other dialects
of UNIX 386 assembly language, as well as to be a powerful tool for
development of new programs. We think you will find the features and
documentation of our assembler considerably more complete than are
available anywhere else. However, we have chosen not to duplicate behavior
of other assemblers that leads to inefficient or incorrect output, or that
generates code without warning when given questionable input. We have also
chosen to support operator precedence rather than perpetuating antiquated
left-to-right evaluation schemes seen elsewhere. Caveat utilitor.
In the course of writing this assembler, we have discovered that the UNIX
implementation of fdiv, fdivr, fsub, and fsubr differs from that described
in the Intel documents. The COHERENT assembler conforms to the UNIX
standard by default. You should be very careful with the order of operands
to these instructions. Once again, caveat utilitor.

















