📄 c-i386.texi
字号:
The bus lock prefix @samp{lock} inhibits interrupts during execution ofthe instruction it precedes. (This is only valid with certaininstructions; see a 80386 manual for details).@cindex coprocessor wait, i386@itemThe wait for coprocessor prefix @samp{wait} waits for the coprocessor tocomplete the current instruction. This should never be needed for the80386/80387 combination.@cindex repeat prefixes, i386@itemThe @samp{rep}, @samp{repe}, and @samp{repne} prefixes are addedto string instructions to make them repeat @samp{%ecx} times (@samp{%cx}times if the current address size is 16-bits).@cindex REX prefixes, i386@itemThe @samp{rex} family of prefixes is used by x86-64 to encodeextensions to i386 instruction set. The @samp{rex} prefix has fourbits --- an operand size overwrite (@code{64}) used to change operand sizefrom 32-bit to 64-bit and X, Y and Z extensions bits used to extend theregister set.You may write the @samp{rex} prefixes directly. The @samp{rex64xyz}instruction emits @samp{rex} prefix with all the bits set. By omittingthe @code{64}, @code{x}, @code{y} or @code{z} you may write otherprefixes as well. Normally, there is no need to write the prefixesexplicitly, since gas will automatically generate them based on theinstruction operands.@end itemize@node i386-Memory@section Memory References@cindex i386 memory references@cindex memory references, i386@cindex x86-64 memory references@cindex memory references, x86-64An Intel syntax indirect memory reference of the form@smallexample@var{section}:[@var{base} + @var{index}*@var{scale} + @var{disp}]@end smallexample@noindentis translated into the AT&T syntax@smallexample@var{section}:@var{disp}(@var{base}, @var{index}, @var{scale})@end smallexample@noindentwhere @var{base} and @var{index} are the optional 32-bit base andindex 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} isspecified, @var{scale} is taken to be 1. @var{section} specifies theoptional section register for the memory operand, and may override thedefault section register (see a 80386 manual for section registerdefaults). Note that section overrides in AT&T syntax @emph{must}be preceded by a @samp{%}. If you specify a section override whichcoincides with the default section register, @code{@value{AS}} does @emph{not}output any section register override prefixes to assemble the giveninstruction. Thus, section overrides can be specified to emphasize whichsection 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} ismissing, 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 heredefaults 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 sectionregister @var{section} being @samp{%gs}.@end tableAbsolute (as opposed to PC relative) call and jump operands must beprefixed 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, long, or quadruple) with aninstruction mnemonic suffix (@samp{b}, @samp{w}, @samp{l} or @samp{q},respectively).The x86-64 architecture adds an RIP (instruction pointer relative)addressing. This addressing mode is specified by using @samp{rip} as abase register. Only constant offsets are valid. For example:@table @asis@item AT&T: @samp{1234(%rip)}, Intel: @samp{[rip + 1234]}Points to the address 1234 bytes past the end of the currentinstruction.@item AT&T: @samp{symbol(%rip)}, Intel: @samp{[rip + symbol]}Points to the @code{symbol} in RIP relative way, this is shorter thanthe default absolute addressing.@end tableOther addressing modes remain unchanged in x86-64 architecture, exceptregisters used are 64-bit instead of 32-bit.@node i386-Jumps@section Handling of Jump Instructions@cindex jump optimization, i386@cindex i386 jump optimization@cindex jump optimization, x86-64@cindex x86-64 jump optimizationJump instructions are always optimized to use the smallest possibledisplacements. This is accomplished by using byte (8-bit) displacementjumps whenever the target is sufficiently close. If a byte displacementis insufficient a long displacement is used. We do not supportword (16-bit) displacement jumps in 32-bit mode (i.e. prefixing the jumpinstruction with the @samp{data16} instruction prefix), since the 80386insists upon masking @samp{%eip} to 16 bits after the word displacementis added. (See also @pxref{i386-Arch})Note that the @samp{jcxz}, @samp{jecxz}, @samp{loop}, @samp{loopz},@samp{loope}, @samp{loopnz} and @samp{loopne} instructions only come in bytedisplacements, so that if you use these instructions (@code{@value{GCC}} doesnot use them) you may get an error message (and incorrect code). The AT&T80386 assembler tries to get around this problem by expanding @samp{jcxz foo}to@smallexample jcxz cx_zero jmp cx_nonzerocx_zero: jmp foocx_nonzero:@end smallexample@node i386-Float@section Floating Point@cindex i386 floating point@cindex floating point, i386@cindex x86-64 floating point@cindex floating point, x86-64All 80387 floating point types except packed BCD are supported.(BCD support may be added without much difficulty). These datatypes 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 instruction mnemonic suffix and a constructorassociated with it. Instruction mnemonic suffixes specify the operand'sdata type. 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@cindex @code{float} directive, x86-64@cindex @code{single} directive, x86-64@cindex @code{double} directive, x86-64@cindex @code{tfloat} directive, x86-64@itemize @bullet@itemFloating point constructors are @samp{.float} or @samp{.single},@samp{.double}, and @samp{.tfloat} for 32-, 64-, and 80-bit formats.These correspond to instruction mnemonic suffixes @samp{s}, @samp{l},and @samp{t}. @samp{t} stands for 80-bit (ten byte) real. The 80387only supports this format via the @samp{fldt} (load 80-bit real to stacktop) and @samp{fstpt} (store 80-bit 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@cindex @code{word} directive, x86-64@cindex @code{long} directive, x86-64@cindex @code{int} directive, x86-64@cindex @code{quad} directive, x86-64@itemInteger constructors are @samp{.word}, @samp{.long} or @samp{.int}, and@samp{.quad} for the 16-, 32-, and 64-bit integer formats. Thecorresponding instruction mnemonic suffixes are @samp{s} (single),@samp{l} (long), and @samp{q} (quad). As with the 80-bit real format,the 64-bit @samp{q} format is only present in the @samp{fildq} (loadquad integer to stack top) and @samp{fistpq} (store quad integer and popstack) instructions.@end itemizeRegister to register operations should not use instruction mnemonic suffixes.@samp{fstl %st, %st(1)} will give a warning, and be assembled as if youwrote @samp{fst %st, %st(1)}, since all register to register operationsuse 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-SIMD@section Intel's MMX and AMD's 3DNow! SIMD Operations@cindex MMX, i386@cindex 3DNow!, i386@cindex SIMD, i386@cindex MMX, x86-64@cindex 3DNow!, x86-64@cindex SIMD, x86-64@code{@value{AS}} supports Intel's MMX instruction set (SIMDinstructions for integer data), available on Intel's Pentium MMXprocessors and Pentium II processors, AMD's K6 and K6-2 processors,Cyrix' M2 processor, and probably others. It also supports AMD's 3DNow!instruction set (SIMD instructions for 32-bit floating point data)available on AMD's K6-2 processor and possibly others in the future.Currently, @code{@value{AS}} does not support Intel's floating pointSIMD, Katmai (KNI).The eight 64-bit MMX operands, also used by 3DNow!, are called @samp{%mm0},@samp{%mm1}, ... @samp{%mm7}. They contain eight 8-bit integers, four16-bit integers, two 32-bit integers, one 64-bit integer, or two 32-bitfloating point values. The MMX registers cannot be used at the same timeas the floating point stack.See Intel and AMD documentation, keeping in mind that the operand order ininstructions is reversed from the Intel syntax.@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{code16gcc} directive, i386@cindex @code{code16} directive, i386@cindex @code{code32} directive, i386@cindex @code{code64} directive, i386@cindex @code{code64} directive, x86-64While @code{@value{AS}} normally writes only ``pure'' 32-bit i386 codeor 64-bit x86-64 code depending on the default configuration,it also supports writing code to run in real mode or in 16-bit protectedmode code segments. To do this, put a @samp{.code16} or@samp{.code16gcc} directive before the assembly language instructions tobe run in 16-bit mode. You can switch @code{@value{AS}} back to writingnormal 32-bit code with the @samp{.code32} directive.@samp{.code16gcc} provides experimental support for generating 16-bitcode from gcc, and differs from @samp{.code16} in that @samp{call},@samp{ret}, @samp{enter}, @samp{leave}, @samp{push}, @samp{pop},@samp{pusha}, @samp{popa}, @samp{pushf}, and @samp{popf} instructionsdefault to 32-bit size. This is so that the stack pointer ismanipulated in the same way over function calls, allowing access tofunction parameters at the same stack offsets as in 32-bit mode.@samp{.code16gcc} also automatically adds address size prefixes wherenecessary to use the 32-bit addressing modes that gcc generates.The code which @code{@value{AS}} generates in 16-bit mode will notnecessarily run on a 16-bit pre-80386 processor. To write code thatruns on such a processor, you must refrain from using @emph{any} 32-bitconstructs which require @code{@value{AS}} to output address or operandsize prefixes.Note that writing 16-bit code instructions by explicitly specifying aprefix or an instruction mnemonic suffix within a 32-bit code sectiongenerates different machine instructions than those generated for a16-bit code segment. In a 32-bit code section, the following codegenerates the machine opcode bytes @samp{66 6a 04}, which pushes thevalue @samp{4} onto the stack, decrementing @samp{%esp} by 2.@smallexample pushw $4@end smallexampleThe same code in a 16-bit code section would generate the machineopcode bytes @samp{6a 04} (ie. without the operand size prefix), whichis correct since the processor default operand size is assumed to be 16bits in a 16-bit code section.@node i386-Bugs@section AT&T Syntax bugsThe UnixWare assembler, and probably other AT&T derived ix86 Unixassemblers, generate floating point instructions with reversed sourceand destination registers in certain cases. Unfortunately, gcc andpossibly many other programs use this reversed syntax, so we're stuckwith it.For example@smallexample fsub %st,%st(3)@end smallexample@noindentresults in @samp{%st(3)} being updated to @samp{%st - %st(3)} ratherthan the expected @samp{%st(3) - %st}. This happens with all thenon-commutative arithmetic floating point operations with two registeroperands where the source register is @samp{%st} and the destinationregister is @samp{%st(i)}.@node i386-Arch@section Specifying CPU Architecture@cindex arch directive, i386@cindex i386 arch directive@cindex arch directive, x86-64@cindex x86-64 arch directive@code{@value{AS}} may be told to assemble for a particular CPUarchitecture with the @code{.arch @var{cpu_type}} directive. Thisdirective enables a warning when gas detects an instruction that is notsupported on the CPU specified. The choices for @var{cpu_type} are:@multitable @columnfractions .20 .20 .20 .20@item @samp{i8086} @tab @samp{i186} @tab @samp{i286} @tab @samp{i386}@item @samp{i486} @tab @samp{i586} @tab @samp{i686} @tab @samp{pentium}@item @samp{pentiumpro} @tab @samp{pentium4} @tab @samp{k6} @tab @samp{athlon}@item @samp{sledgehammer}@end multitableApart from the warning, there are only two other effects on@code{@value{AS}} operation; Firstly, if you specify a CPU other than@samp{i486}, then shift by one instructions such as @samp{sarl $1, %eax}will automatically use a two byte opcode sequence. The larger threebyte opcode sequence is used on the 486 (and when no architecture isspecified) because it executes faster on the 486. Note that you canexplicitly request the two byte opcode by writing @samp{sarl %eax}.Secondly, if you specify @samp{i8086}, @samp{i186}, or @samp{i286},@emph{and} @samp{.code16} or @samp{.code16gcc} then byte offsetconditional jumps will be promoted when necessary to a two instructionsequence consisting of a conditional jump of the opposite sense aroundan unconditional jump to the target.Following the CPU architecture, you may specify @samp{jumps} or@samp{nojumps} to control automatic promotion of conditional jumps.@samp{jumps} is the default, and enables jump promotion; All externaljumps will be of the long variety, and file-local jumps will be promotedas necessary. (@pxref{i386-Jumps}) @samp{nojumps} leaves externalconditional jumps as byte offset jumps, and warns about file-localconditional jumps that @code{@value{AS}} promotes.Unconditional jumps are treated as for @samp{jumps}.For example@smallexample .arch i8086,nojumps@end smallexample@node i386-Notes@section Notes@cindex i386 @code{mul}, @code{imul} instructions@cindex @code{mul} instruction, i386@cindex @code{imul} instruction, i386@cindex @code{mul} instruction, x86-64@cindex @code{imul} instruction, x86-64There is some trickery concerning the @samp{mul} and @samp{imul}instructions that deserves mention. The 16-, 32-, 64- and 128-bit expandingmultiplies (base opcode @samp{0xf6}; extension 4 for @samp{mul} and 5for @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 thiswould confuse @code{@value{GCC}} output. Use @samp{imul %ebx} to get the64-bit product in @samp{%edx:%eax}.We have added a two operand form of @samp{imul} when the first operandis an immediate mode expression and the second operand is a register.This is just a shorthand, so that, multiplying @samp{%eax} by 69, forexample, can be done with @samp{imul $69, %eax} rather than @samp{imul$69, %eax, %eax}.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -