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.