aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog2
-rw-r--r--gas/doc/c-i386.texi481
2 files changed, 483 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 4acb72b..589a49e 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,7 @@
Tue Jun 9 12:20:05 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
+ * doc/c-i386.texi: Update 16 bit documentation.
+
* config/tc-i386.h: Change Data16 to Size16, Data32 to Size32,
IgnoreDataSize to IgnoreSize as they are used for address size as
well as data size.
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
new file mode 100644
index 0000000..c10d904
--- /dev/null
+++ b/gas/doc/c-i386.texi
@@ -0,0 +1,481 @@
+@c Copyright (C) 1991, 92, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@ifset GENERIC
+@page
+@node i386-Dependent
+@chapter 80386 Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter 80386 Dependent Features
+@end ifclear
+
+@cindex i386 support
+@cindex i80306 support
+@menu
+* i386-Options:: Options
+* i386-Syntax:: AT&T Syntax versus Intel Syntax
+* i386-Opcodes:: Opcode Naming
+* i386-Regs:: Register Naming
+* i386-prefixes:: Opcode Prefixes
+* i386-Memory:: Memory References
+* i386-jumps:: Handling of Jump Instructions
+* i386-Float:: Floating Point
+* i386-16bit:: Writing 16-bit Code
+* i386-Bugs:: AT&T Syntax bugs
+* i386-Notes:: Notes
+@end menu
+
+@node i386-Options
+@section Options
+
+@cindex options for i386 (none)
+@cindex i386 options (none)
+The 80386 has no machine dependent options.
+
+@node i386-Syntax
+@section AT&T Syntax versus Intel Syntax
+
+@cindex i386 syntax compatibility
+@cindex syntax compatibility, i386
+In order to maintain compatibility with the output of @code{@value{GCC}},
+@code{@value{AS}} supports AT&T System V/386 assembler syntax. This is quite
+different from Intel syntax. We mention these differences because
+almost all 80386 documents use Intel syntax. Notable differences
+between the two syntaxes are:
+
+@cindex immediate operands, i386
+@cindex i386 immediate operands
+@cindex register operands, i386
+@cindex i386 register operands
+@cindex jump/call operands, i386
+@cindex i386 jump/call operands
+@cindex operand delimiters, i386
+@itemize @bullet
+@item
+AT&T immediate operands are preceded by @samp{$}; Intel immediate
+operands are undelimited (Intel @samp{push 4} is AT&T @samp{pushl $4}).
+AT&T register operands are preceded by @samp{%}; Intel register operands
+are undelimited. AT&T absolute (as opposed to PC relative) jump/call
+operands are prefixed by @samp{*}; they are undelimited in Intel syntax.
+
+@cindex i386 source, destination operands
+@cindex source, destination operands; i386
+@item
+AT&T and Intel syntax use the opposite order for source and destination
+operands. Intel @samp{add eax, 4} is @samp{addl $4, %eax}. The
+@samp{source, dest} convention is maintained for compatibility with
+previous Unix assemblers. Note that instructions with more than one
+source operand, such as the @samp{enter} instruction, do @emph{not} have
+reversed order. @ref{i386-Bugs}.
+
+@cindex opcode suffixes, i386
+@cindex sizes operands, i386
+@cindex i386 size suffixes
+@item
+In AT&T syntax the size of memory operands is determined from the last
+character of the opcode name. Opcode suffixes of @samp{b}, @samp{w},
+and @samp{l} specify byte (8-bit), word (16-bit), and long (32-bit)
+memory references. Intel syntax accomplishes this by prefixes memory
+operands (@emph{not} the opcodes themselves) with @samp{byte ptr},
+@samp{word ptr}, and @samp{dword ptr}. Thus, Intel @samp{mov al, byte
+ptr @var{foo}} is @samp{movb @var{foo}, %al} in AT&T syntax.
+
+@cindex return instructions, i386
+@cindex i386 jump, call, return
+@item
+Immediate form long jumps and calls are
+@samp{lcall/ljmp $@var{section}, $@var{offset}} in AT&T syntax; the
+Intel syntax is
+@samp{call/jmp far @var{section}:@var{offset}}. Also, the far return
+instruction
+is @samp{lret $@var{stack-adjust}} in AT&T syntax; Intel syntax is
+@samp{ret far @var{stack-adjust}}.
+
+@cindex sections, i386
+@cindex i386 sections
+@item
+The AT&T assembler does not provide support for multiple section
+programs. Unix style systems expect all programs to be single sections.
+@end itemize
+
+@node i386-Opcodes
+@section Opcode Naming
+
+@cindex i386 opcode naming
+@cindex opcode naming, i386
+Opcode names are suffixed with one character modifiers which specify the
+size of operands. The letters @samp{b}, @samp{w}, and @samp{l} specify
+byte, word, and long operands. If no suffix is specified by an
+instruction then @code{@value{AS}} tries to
+fill in the missing suffix based on the destination register operand
+(the last one by convention). Thus, @samp{mov %ax, %bx} is equivalent
+to @samp{movw %ax, %bx}; also, @samp{mov $1, %bx} is equivalent to
+@samp{movw $1, %bx}. Note that this is incompatible with the AT&T Unix
+assembler which assumes that a missing opcode suffix implies long
+operand size. (This incompatibility does not affect compiler output
+since compilers always explicitly specify the opcode suffix.)
+
+Almost all opcodes have the same names in AT&T and Intel format. There
+are a few exceptions. The sign extend and zero extend instructions need
+two sizes to specify them. They need a size to sign/zero extend
+@emph{from} and a size to zero extend @emph{to}. This is accomplished
+by using two opcode suffixes in AT&T syntax. Base names for sign extend
+and zero extend are @samp{movs@dots{}} and @samp{movz@dots{}} in AT&T
+syntax (@samp{movsx} and @samp{movzx} in Intel syntax). The opcode
+suffixes are tacked on to this base name, the @emph{from} suffix before
+the @emph{to} suffix. Thus, @samp{movsbl %al, %edx} is AT&T syntax for
+``move sign extend @emph{from} %al @emph{to} %edx.'' Possible suffixes,
+thus, are @samp{bl} (from byte to long), @samp{bw} (from byte to word),
+and @samp{wl} (from word to long).
+
+@cindex conversion instructions, i386
+@cindex i386 conversion instructions
+The Intel-syntax conversion instructions
+
+@itemize @bullet
+@item
+@samp{cbw} --- sign-extend byte in @samp{%al} to word in @samp{%ax},
+
+@item
+@samp{cwde} --- sign-extend word in @samp{%ax} to long in @samp{%eax},
+
+@item
+@samp{cwd} --- sign-extend word in @samp{%ax} to long in @samp{%dx:%ax},
+
+@item
+@samp{cdq} --- sign-extend dword in @samp{%eax} to quad in @samp{%edx:%eax},
+@end itemize
+
+@noindent
+are called @samp{cbtw}, @samp{cwtl}, @samp{cwtd}, and @samp{cltd} in
+AT&T naming. @code{@value{AS}} accepts either naming for these instructions.
+
+@cindex jump instructions, i386
+@cindex call instructions, i386
+Far call/jump instructions are @samp{lcall} and @samp{ljmp} in
+AT&T syntax, but are @samp{call far} and @samp{jump far} in Intel
+convention.
+
+@node i386-Regs
+@section Register Naming
+
+@cindex i386 registers
+@cindex registers, i386
+Register operands are always prefixed with @samp{%}. The 80386 registers
+consist of
+
+@itemize @bullet
+@item
+the 8 32-bit registers @samp{%eax} (the accumulator), @samp{%ebx},
+@samp{%ecx}, @samp{%edx}, @samp{%edi}, @samp{%esi}, @samp{%ebp} (the
+frame pointer), and @samp{%esp} (the stack pointer).
+
+@item
+the 8 16-bit low-ends of these: @samp{%ax}, @samp{%bx}, @samp{%cx},
+@samp{%dx}, @samp{%di}, @samp{%si}, @samp{%bp}, and @samp{%sp}.
+
+@item
+the 8 8-bit registers: @samp{%ah}, @samp{%al}, @samp{%bh},
+@samp{%bl}, @samp{%ch}, @samp{%cl}, @samp{%dh}, and @samp{%dl} (These
+are the high-bytes and low-bytes of @samp{%ax}, @samp{%bx},
+@samp{%cx}, and @samp{%dx})
+
+@item
+the 6 section registers @samp{%cs} (code section), @samp{%ds}
+(data section), @samp{%ss} (stack section), @samp{%es}, @samp{%fs},
+and @samp{%gs}.
+
+@item
+the 3 processor control registers @samp{%cr0}, @samp{%cr2}, and
+@samp{%cr3}.
+
+@item
+the 6 debug registers @samp{%db0}, @samp{%db1}, @samp{%db2},
+@samp{%db3}, @samp{%db6}, and @samp{%db7}.
+
+@item
+the 2 test registers @samp{%tr6} and @samp{%tr7}.
+
+@item
+the 8 floating point register stack @samp{%st} or equivalently
+@samp{%st(0)}, @samp{%st(1)}, @samp{%st(2)}, @samp{%st(3)},
+@samp{%st(4)}, @samp{%st(5)}, @samp{%st(6)}, and @samp{%st(7)}.
+@end itemize
+
+@node i386-prefixes
+@section Opcode Prefixes
+
+@cindex i386 opcode prefixes
+@cindex opcode prefixes, i386
+@cindex prefixes, i386
+Opcode prefixes are used to modify the following opcode. They are used
+to repeat string instructions, to provide section overrides, to perform
+bus lock operations, and to give operand and address size (16-bit
+operands are specified in an instruction by prefixing what would
+normally be 32-bit operands with a ``operand size'' opcode prefix).
+Opcode prefixes are usually given as single-line instructions with no
+operands, and must directly precede the instruction they act upon. For
+example, the @samp{scas} (scan string) instruction is repeated with:
+@smallexample
+ repne
+ scas
+@end smallexample
+@noindent
+or
+@smallexample
+ repne/scas
+@end smallexample
+
+Here is a list of opcode prefixes:
+
+@cindex section override prefixes, i386
+@itemize @bullet
+@item
+Section override prefixes @samp{cs}, @samp{ds}, @samp{ss}, @samp{es},
+@samp{fs}, @samp{gs}. These are automatically added by specifying
+using the @var{section}:@var{memory-operand} form for memory references.
+
+@cindex size prefixes, i386
+@item
+Operand/Address size prefixes @samp{data16} and @samp{addr16}
+change 32-bit operands/addresses into 16-bit operands/addresses,
+while @samp{data32} and @samp{addr32} change 16-bit ones (in a
+@code{.code16} section) into 32-bit operands/addresses.
+
+@cindex bus lock prefixes, i386
+@cindex inhibiting interrupts, i386
+@item
+The bus lock prefix @samp{lock} inhibits interrupts during
+execution of the instruction it precedes. (This is only valid with
+certain instructions; see a 80386 manual for details).
+
+@cindex coprocessor wait, i386
+@item
+The wait for coprocessor prefix @samp{wait} waits for the
+coprocessor to complete the current instruction. This should never be
+needed for the 80386/80387 combination.
+
+@cindex repeat prefixes, i386
+@item
+The @samp{rep}, @samp{repe}, and @samp{repne} prefixes are added
+to string instructions to make them repeat @samp{%ecx} times.
+@end itemize
+
+@node i386-Memory
+@section Memory References
+
+@cindex i386 memory references
+@cindex memory references, i386
+An Intel syntax indirect memory reference of the form
+
+@smallexample
+@var{section}:[@var{base} + @var{index}*@var{scale} + @var{disp}]
+@end smallexample
+
+@noindent
+is translated into the AT&T syntax
+
+@smallexample
+@var{section}:@var{disp}(@var{base}, @var{index}, @var{scale})
+@end smallexample
+
+@noindent
+where @var{base} and @var{index} are the optional 32-bit base and
+index registers, @var{disp} is the optional displacement, and
+@var{scale}, taking the values 1, 2, 4, and 8, multiplies @var{index}
+to calculate the address of the operand. If no @var{scale} is
+specified, @var{scale} is taken to be 1. @var{section} specifies the
+optional section register for the memory operand, and may override the
+default section register (see a 80386 manual for section register
+defaults). Note that section overrides in AT&T syntax @emph{must} have
+be preceded by a @samp{%}. If you specify a section override which
+coincides with the default section register, @code{@value{AS}} does @emph{not}
+output any section register override prefixes to assemble the given
+instruction. Thus, section overrides can be specified to emphasize which
+section register is used for a given memory operand.
+
+Here are some examples of Intel and AT&T style memory references:
+
+@table @asis
+@item AT&T: @samp{-4(%ebp)}, Intel: @samp{[ebp - 4]}
+@var{base} is @samp{%ebp}; @var{disp} is @samp{-4}. @var{section} is
+missing, and the default section is used (@samp{%ss} for addressing with
+@samp{%ebp} as the base register). @var{index}, @var{scale} are both missing.
+
+@item AT&T: @samp{foo(,%eax,4)}, Intel: @samp{[foo + eax*4]}
+@var{index} is @samp{%eax} (scaled by a @var{scale} 4); @var{disp} is
+@samp{foo}. All other fields are missing. The section register here
+defaults to @samp{%ds}.
+
+@item AT&T: @samp{foo(,1)}; Intel @samp{[foo]}
+This uses the value pointed to by @samp{foo} as a memory operand.
+Note that @var{base} and @var{index} are both missing, but there is only
+@emph{one} @samp{,}. This is a syntactic exception.
+
+@item AT&T: @samp{%gs:foo}; Intel @samp{gs:foo}
+This selects the contents of the variable @samp{foo} with section
+register @var{section} being @samp{%gs}.
+@end table
+
+Absolute (as opposed to PC relative) call and jump operands must be
+prefixed with @samp{*}. If no @samp{*} is specified, @code{@value{AS}}
+always chooses PC relative addressing for jump/call labels.
+
+Any instruction that has a memory operand, but no register operand,
+@emph{must} specify its size (byte, word, or long) with an opcode suffix
+(@samp{b}, @samp{w}, or @samp{l}, respectively).
+
+@node i386-jumps
+@section Handling of Jump Instructions
+
+@cindex jump optimization, i386
+@cindex i386 jump optimization
+Jump instructions are always optimized to use the smallest possible
+displacements. This is accomplished by using byte (8-bit) displacement
+jumps whenever the target is sufficiently close. If a byte displacement
+is insufficient a long (32-bit) displacement is used. We do not support
+word (16-bit) displacement jumps in 32-bit mode (i.e. prefixing the jump instruction
+with the @samp{data16} opcode prefix), since the 80386 insists upon masking
+@samp{%eip} to 16 bits after the word displacement is added.
+
+Note that the @samp{jcxz}, @samp{jecxz}, @samp{loop}, @samp{loopz},
+@samp{loope}, @samp{loopnz} and @samp{loopne} instructions only come in byte
+displacements, so that if you use these instructions (@code{@value{GCC}} does
+not use them) you may get an error message (and incorrect code). The AT&T
+80386 assembler tries to get around this problem by expanding @samp{jcxz foo}
+to
+
+@smallexample
+ jcxz cx_zero
+ jmp cx_nonzero
+cx_zero: jmp foo
+cx_nonzero:
+@end smallexample
+
+@node i386-Float
+@section Floating Point
+
+@cindex i386 floating point
+@cindex floating point, i386
+All 80387 floating point types except packed BCD are supported.
+(BCD support may be added without much difficulty). These data
+types are 16-, 32-, and 64- bit integers, and single (32-bit),
+double (64-bit), and extended (80-bit) precision floating point.
+Each supported type has an opcode suffix and a constructor
+associated with it. Opcode suffixes specify operand's data
+types. Constructors build these data types into memory.
+
+@cindex @code{float} directive, i386
+@cindex @code{single} directive, i386
+@cindex @code{double} directive, i386
+@cindex @code{tfloat} directive, i386
+@itemize @bullet
+@item
+Floating point constructors are @samp{.float} or @samp{.single},
+@samp{.double}, and @samp{.tfloat} for 32-, 64-, and 80-bit formats.
+These correspond to opcode suffixes @samp{s}, @samp{l}, and @samp{t}.
+@samp{t} stands for temporary real, and that the 80387 only supports
+this format via the @samp{fldt} (load temporary real to stack top) and
+@samp{fstpt} (store temporary real and pop stack) instructions.
+
+@cindex @code{word} directive, i386
+@cindex @code{long} directive, i386
+@cindex @code{int} directive, i386
+@cindex @code{quad} directive, i386
+@item
+Integer constructors are @samp{.word}, @samp{.long} or @samp{.int}, and
+@samp{.quad} for the 16-, 32-, and 64-bit integer formats. The corresponding
+opcode suffixes are @samp{s} (single), @samp{l} (long), and @samp{q}
+(quad). As with the temporary real format the 64-bit @samp{q} format is
+only present in the @samp{fildq} (load quad integer to stack top) and
+@samp{fistpq} (store quad integer and pop stack) instructions.
+@end itemize
+
+Register to register operations should not use opcode suffixes.
+@samp{fstl %st, %st(1)} will give a warning, and be assembled as if you
+wrote @samp{fst %st, %st(1)}, since all register to register operations
+use 80-bit floating point operands. (Contrast this with @samp{fstl %st, mem},
+which converts @samp{%st} from 80-bit to 64-bit floating point format,
+then stores the result in the 4 byte location @samp{mem})
+
+@node i386-16bit
+@section Writing 16-bit Code
+
+@cindex i386 16-bit code
+@cindex 16-bit code, i386
+@cindex real-mode code, i386
+@cindex @code{code16} directive, i386
+@cindex @code{code32} directive, i386
+While @code{@value{AS}} normally writes only ``pure'' 32-bit i386 code,
+it also supports writing code to run in real mode or in 16-bit protected
+mode code segments. To do this, put a @samp{.code16} directive before
+the assembly language instructions to be run in 16-bit mode. You can
+switch @code{@value{AS}} back to writing normal 32-bit code with the
+@samp{.code32} directive.
+
+The code which @code{@value{AS}} generates in 16-bit mode will not
+necessarily run on a 16-bit pre-80386 processor. To write code that
+runs on such a processor, you must refrain from using @emph{any} 32-bit
+constructs which require @code{@value{AS}} to output address or operand
+size prefixes.
+
+Note that writing 16-bit code instructions by explicitly specifying a
+prefix or a suffix within a 32-bit code section generates different
+machine instructions than those generated for a 16-bit code segment. In a
+32-bit code section, the following code generates the machine
+instruction sequence @samp{66 6a 04}, which pushes the value @samp{4} onto
+the stack, decrementing @samp{%esp} by 2.
+
+@smallexample
+ pushw $4
+@end smallexample
+
+The same code in a 16-bit code section would generate the machine
+instruction sequence @samp{6a 04} (ie. without the operand size prefix),
+which is correct since the processor default operand size is assumed to
+be 16 bits in a 16-bit code section.
+
+@node i386-Bugs
+@section AT&T Syntax bugs
+
+The UnixWare assembler, and probably other AT&T derived ix86 Unix
+assemblers, generate floating point instructions with reversed source
+and destination registers in certain cases. Unfortunately, gcc and
+possibly many other programs use this reversed syntax, so we're stuck
+with it.
+
+For example
+
+@smallexample
+ fsub %st,%st(3)
+@end smallexample
+@noindent
+results in @samp{%st(3)} being updated to @samp{%st - %st(3)} rather
+than the expected @samp{%st(3) - %st}. This happens with all the
+non-commutative arithmetic floating point operations with two register
+operands where the source register is @samp{%st} and the destination
+register is @samp{%st(i)}.
+
+@node i386-Notes
+@section Notes
+
+@cindex i386 @code{mul}, @code{imul} instructions
+@cindex @code{mul} instruction, i386
+@cindex @code{imul} instruction, i386
+There is some trickery concerning the @samp{mul} and @samp{imul}
+instructions that deserves mention. The 16-, 32-, and 64-bit expanding
+multiplies (base opcode @samp{0xf6}; extension 4 for @samp{mul} and 5
+for @samp{imul}) can be output only in the one operand form. Thus,
+@samp{imul %ebx, %eax} does @emph{not} select the expanding multiply;
+the expanding multiply would clobber the @samp{%edx} register, and this
+would confuse @code{@value{GCC}} output. Use @samp{imul %ebx} to get the
+64-bit product in @samp{%edx:%eax}.
+
+We have added a two operand form of @samp{imul} when the first operand
+is an immediate mode expression and the second operand is a register.
+This is just a shorthand, so that, multiplying @samp{%eax} by 69, for
+example, can be done with @samp{imul $69, %eax} rather than @samp{imul
+$69, %eax, %eax}.
+