打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
X86

This article describes how x86 and x86-64 instructions are encoded.

Contents

 [] 

General Overview

An x86-64 instruction may be at most 15 bytes in length. It consists of the following components in the given order, where the prefixes are at the least-significant (lowest) address in memory:

  • (1-4 bytes, optional)
  • (1-4 bytes, required)
  • (1 byte, if required)
  • (1 byte, if required)
  • (1, 2, 4 or 8 bytes, if required)
  • (1, 2, 4 or 8 bytes, if required)

Registers

The registers are encoded using the 4-bit values in the X.Reg column of the following table. X.Reg is in binary.

X.Reg 8-bit GP 16-bit GP 32-bit GP 64-bit GP 80-bit x87 64-bit MMX 128-bit XMM 256-bit YMM 16-bit Segment 32-bit Control 32-bit Debug
0.000 (0)ALAXEAXRAXST0MMX0XMM0YMM0ESCR0DR0
0.001 (1)CLCXECXRCXST1MMX1XMM1YMM1CSCR1DR1
0.010 (2)DLDXEDXRDXST2MMX2XMM2YMM2SSCR2DR2
0.011 (3)BLBXEBXRBXST3MMX3XMM3YMM3DSCR3DR3
0.100 (4)AH, SPLSPESPRSPST4MMX4XMM4YMM4FSCR4DR4
0.101 (5)CH, BPLBPEBPRBPST5MMX5XMM5YMM5GSCR5DR5
0.110 (6)DH, SILSIESIRSIST6MMX6XMM6YMM6-CR6DR6
0.111 (7)BH, DILDIEDIRDIST7MMX7XMM7YMM7-CR7DR7
1.000 (8)R8LR8WR8DR8-MMX0XMM8YMM8ESCR8DR8
1.001 (9)R9LR9WR9DR9-MMX1XMM9YMM9CSCR9DR9
1.010 (10)R10LR10WR10DR10-MMX2XMM10YMM10SSCR10DR10
1.011 (11)R11LR11WR11DR11-MMX3XMM11YMM11DSCR11DR11
1.100 (12)R12LR12WR12DR12-MMX4XMM12YMM12FSCR12DR12
1.101 (13)R13LR13WR13DR13-MMX5XMM13YMM13GSCR13DR13
1.110 (14)R14LR14WR14DR14-MMX6XMM14YMM14-CR14DR14
1.111 (15)R15LR15WR15DR15-MMX7XMM15YMM15-CR15DR15

1: When any REX prefix is used, SPL, BPL, SIL and DIL are used. Otherwise, without any REX prefix AH, CH, DH and BH are used.

Legacy Prefixes

Each instruction can have up to four prefixes. Sometimes a prefix is required for the instruction while it loses it's original meaning (i.e. a 'mandatory prefix'). The following prefixes can be used, the order does not matter:

  • Prefix group 1
    • 0xF0: LOCK prefix
    • 0xF2: REPNE/REPNZ prefix
    • 0xF3: REP or REPE/REPZ prefix
  • Prefix group 2
    • 0x2E: CS segment override
    • 0x36: SS segment override
    • 0x3E: DS segment override
    • 0x26: ES segment override
    • 0x64: FS segment override
    • 0x65: GS segment override
    • 0x2E: Branch not taken
    • 0x3E: Branch taken
  • Prefix group 3
    • 0x66: Operand-size override prefix
  • Prefix group 4
    • 0x67: Address-size override prefix

When there are two or more prefixes from a single group, the behavior is undefined. Some processors ignore the subsequent prefixes from the same group, or use only the last prefix specified for any group.

LOCK prefix

With the LOCK prefix, certain read-modify-write instructions are executed atomically. The LOCK prefix can only be used with the following instructions or an Invalid Opcode Exception occurs: ADC, ADD, AND, BTC, BTR, BTS, CMPXCHG, CMPXCHG8B, CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XADD, XCHG and XOR.

REPNE/REPNZ, REP and REPE/REPZ prefixes

The repeat prefixes cause string handling instructions to be repeated.

The REP prefix will repeat the associated instruction up to CX times, decreasing CX with every repetition. It can be used with the INS, LODS, MOVS, OUTS and STOS instructions.

REPE and REPZ are synonyms and repeat the instruction until CX reaches 0 or when ZF is set to 0. It can be used with the CMPS, CMPSB, CMPSD, CMPSW, SCAS, SCASB, SCASD and SCASW instructions.

REPNE and REPNZ also are synonyms and repeat the instruction until CX reaches 0 or when ZF is set to 1. It can be used with the CMPS, CMPSB, CMPSD, CMPSW, SCAS, SCASB, SCASD and SCASW instructions

CS, SS, DS, ES, FS and GS segment override prefixes

Segment overrides are used with instructions that reference non-stack memory. The default segment is implied by the instruction, and using a specific override forces the use of the specified segment for memory operands.

In 64-bit the CS, SS, DS and ES segment overrides are ignored.

Branch taken/not taken prefixes

Branch hints may be used to lessen the impact of branch misprediction somewhat. The 'branch taken' hint is a strong hint, while the 'branch not taken' hint is a weak hint. The branch hints are only supported by Intel since the Pentium 4. Whether using them on AMD architectures has any (positive or negative) effect at all is not known.

Operand-size and address-size override prefix

The default operand-size and address-size can be overridden using these prefix. See the following table:

  CS.d REX.W 0x66 operand prefix 0x67 address prefix Operand size Address size
Real mode /
Virtual 8086 mode
N/AN/A No No16-bit16-bit
N/AN/A No Yes16-bit32-bit
N/AN/A Yes No32-bit16-bit
N/AN/A Yes Yes32-bit32-bit
Protected mode /
Long compatibility mode
0N/A No No16-bit16-bit
0N/A No Yes16-bit32-bit
0N/A Yes No32-bit16-bit
0N/A Yes Yes32-bit32-bit
1N/A No No32-bit32-bit
1N/A No Yes32-bit16-bit
1N/A Yes No16-bit32-bit
1N/A Yes Yes16-bit16-bit
Long 64-bit mode Ignored 0 No No32-bit64-bit
Ignored 0 No Yes32-bit32-bit
Ignored 0 Yes No16-bit64-bit
Ignored 0 Yes Yes16-bit32-bit
Ignored 1Ignored No64-bit64-bit
Ignored 1ignored Yes64-bit32-bit

1: Certain instructions default to (or are fixed at) 64-bit operands and do not need the REX prefix for this, see .

NASM

NASM determines the operand size by looking at the MODRM.reg or (for a register) MODRM.rm fields. When they are both 32-bit, the operand size becomes 32-bit. Same for 16-bit and 64-bit. When they differ, an error occurs at compile time.The address size is determined by looking at (for a memory operand) the MODRM.rm field, or the SIB.base, SIB.index and displacement, in that order. So when SIB.base uses a 16-bit register (such as AX), the address size becomes 16-bit. Using a 32-bit displacement will result in the displacement being truncated.

Opcode

The x86-64 instruction set defines many opcodes and many ways to encode them, depending on several factors.

Legacy opcodes

Legacy (and x87) opcodes consist of, in this order:

  • mandatory prefix;
  • REX prefix;
  • opcode.

Mandatory prefix

Certain instructions (most notably the SIMD instructions) require a mandatory prefix (0x66, 0xF2 or 0xF3), which looks like a normal modifier prefix. When a mandatory prefix is required, it is put with the modifier prefixes before the REX prefix (if any).

REX prefix

The REX prefix is only available in long mode.

Usage

A REX prefix must be encoded when:

  • using 64-bit operand size and the instruction does not default to 64-bit operand size; or
  • using one of the extended registers (R8 to R15, XMM8 to XMM15, YMM8 to YMM15, CR8 to CR15 and DR8 to DR15); or
  • using one of the uniform byte registers SPL, BPL, SIL or DIL.

A REX prefix must not be encoded when:

  • using one of the high byte registers AH, CH, BH or DH.

In all other cases, the REX prefix is ignored. The use of multiple REX prefixes is undefined, although processors seem to use only the last REX prefix.

Instructions that default to 64-bit operand size in long mode are:

CALL (near)ENTERJcc
JrCXZJMP (near)LEAVE
LGDTLIDTLLDT
LOOPLOOPccLTR
MOV CR(n)MOV DR(n)POP reg/mem
POP regPOP FSPOP GS
POPFQPUSH imm8PUSH imm32
PUSH reg/memPUSH regPUSH FS
PUSH GSPUSHFQRET (near)
Encoding

The layout is as follows:

  7                           0+---+---+---+---+---+---+---+---+| 0   1   0   0 | W | R | X | B |+---+---+---+---+---+---+---+---+
Field Length Description
01004 bitsFixed bit pattern
W1 bitWhen 1, a 64-bit operand size is used. Otherwise, when 0, the default operand size is used (which is 32-bit for most but not all instructions, see ).
R1 bitThis 1-bit value is an extension to the MODRM.reg field. See .
X1 bitThis 1-bit value is an extension to the SIB.index field. See .
B1 bitThis 1-bit value is an extension to the MODRM.rm field or the SIB.base field. See .

Opcode

The opcode can be 1, 2 or 3 bytes in length. Depending on the opcode escape sequence, a different opcode map is selected. Possible opcode sequences are:

  • <op>
  • 0x0F <op>
  • 0x0F 0x38 <op>
  • 0x0F 0x3A <op>

Note that opcodes can specify that the REG field in the ModR/M byte is fixed at a particular value.

VEX/XOP opcodes

A VEX/XOP prefix must be encoded when:

  • the instruction has only its VEX/XOP opcode and no legacy opcode; or
  • 256-bit YMM registers are used; or
  • more than three operands are used (e.g. nondestructive-source operations); or
  • when using 128-bit XMM destination registers, bits 128-255 of the corresponding YMM register must be cleared.

A VEX/XOP prefix must not be encoded when:

  • when using 128-bit XMM destination registers, bits 128-255 of the corresponding YMM register must not be changed.


There are many VEX and XOP instructions, all of which can be encoded using the three byte VEX/XOP escape prefix. The VEX and XOP escape prefixes use fields with the following semantics:

Field Length Description
VEX/XOP prefix8 bitsPrefix.
Prefix Opcode map and encoding
0xC4Three-byte VEX
0xC5Two-byte VEX
0x8FThree-byte XOP
~R1 bitThis 1-bit value is an 'inverted' extension to the MODRM.reg field. The inverse of REX.R. See .
~X1 bitThis 1-bit value is an 'inverted' extension to the SIB.index field. The inverse of REX.X. See .
~B1 bitThis 1-bit value is an 'inverted' extension to the MODRM.rm field or the SIB.base field. The inverse of REX.B. See .
map_select5 bitsSpecifies the opcode map to use.
W/E1 bitFor integer instructions: when 1, a 64-bit operand size is used; otherwise, when 0, the default operand size is used (equivalent with REX.W). For non-integer instructions, this bit is a general opcode extension bit.
~vvvv4 bitsAn additional operand for the instruction. The value of the XMM or YMM register (see ) is 'inverted'.
L1 bitWhen 0, a 128-bit vector lengh is used. Otherwise, when 1, a 256-bit vector length is used.
pp2 bitsSpecifies an implied mandatory prefix for the opcode.
Value (binary) Implied mandatory prefix
00none
010x66
100xF3
110xF2

Three byte VEX escape prefix

The layout is as follows, starting with a byte with value 0xC4:

  7                           0       7                           0     7                           0+---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+| 1   1   0   0   0   1   0   0 |   |~R |~X |~B |     map_select    |   |W/E|     ~vvvv     | L |   pp  |+---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+

A VEX instruction whose values for certain fields are VEX.~X == 1, VEX.~B == 1, VEX.W/E == 0 and map_select == b00001 may be encoded using the .

Three byte XOP escape prefix

The layout is the same as the , but with initial byte value 0x8F:

  7                           0       7                           0     7                           0+---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+| 1   0   0   0   1   1   1   1 |   |~R |~X |~B |     map_select    |   |W/E|     ~vvvv     | L |   pp  |+---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+

Two byte VEX escape prefix

A VEX instruction whose values for certain fields are VEX.~X == 1, VEX.~B == 1, VEX.W/E == 0 and map_select == b00001 may be encoded using the two byte VEX escape prefix. The layout is as follows:

  7                           0       7                           0+---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+| 1   1   0   0   0   1   0   1 |   |~R |     ~vvvv     | L |   pp  |+---+---+---+---+---+---+---+---+   +---+---+---+---+---+---+---+---+

3DNow! opcodes

3DNow! opcodes consist of, in this order:

  • fixed opcode;
  • (ModR/M, SIB, displacement);
  • immediate opcode byte.

Fixed opcode

All 3DNow! opcodes have a fixed two-byte sequence equal to 0x0F 0x0F in the opcode position of the instruction.

Immediate opcode byte

3DNow! instructions encode the actual opcode as an 8-bit immediate value trailing the instruction (thus after the ModR/M, SIB and displacement).

ModR/M and SIB bytes

The ModR/M and SIB bytes are used to encode up to two operands of an instruction, each of which is a direct register or effective memory address.

ModR/M

The ModR/M byte encodes a register or an opcode extension, and a register or a memory address. It has the following fields:

  7                           0+---+---+---+---+---+---+---+---+|  mod  |    reg    |     rm    |+---+---+---+---+---+---+---+---+
Field Length Description
MODRM.mod2 bitsIn general, when this field is b11, then register-direct addressing mode is used; otherwise register-indirect addressing mode is used.
MODRM.reg3 bitsThis field can have one of two values:
  • A 3-bit opcode extension, which is used by some instructions but has no further meaning other than distinguishing the instruction from other instructions.
  • A 3-bit register reference, which can be used as the source or the destination of an instruction (depending on the instruction). The referenced register depends on the of the instruction and the instruction itself. See for the values to use for each of the registers. The REX.R, VEX.~R or XOP.~R field can extend this field with 1 most-significant bit to 4 bits total.
MODRM.rm3 bitsSpecifies a direct or indirect register operand, optionally with a displacement. The REX.B, VEX.~B or XOP.~B field can extend this field with 1 most-significant bit to 4 bits total.

16-bit addressing

These are the meanings of the Mod (vertically) and REX/VEX/XOP.B and R/M bits (horizontally) for . B.R/M and Mod are in binary. The SIB-byte is not used in 16-bit addressing. In Long processing mode there is no way to specify 16-bit addresses.

16-bit B.R/M
Mod x.000
AX, R8W
x.001
CX, R9W
x.010
DX, R10W
x.011
BX, R11W
x.100
SP, R12W
x.101
BP, R13W
x.110
SI, R14W
x.111
DI, R15W
00[BX + SI][BX + DI][BP + SI][BP + DI][SI][DI][disp16][BX]
01[BX + SI + disp8][BX + DI + disp8][BP + SI + disp8][BP + DI + disp8][SI + disp8][DI + disp8][BP + disp8][BX + disp8]
10[BX + SI + disp16][BX + DI + disp16][BP + SI + disp16][BP + DI + disp16][SI + disp16][DI + disp16][BP + disp16][BX + disp16]
11r/m

32/64-bit addressing

These are the meanings of the Mod (vertically) and REX/VEX/XOP.B and R/M bits (horizontally) for . B.R/M and Mod are in binary.

32/64-bit B.R/M
Mod 0.000
AX
0.001
CX
0.010
DX
0.011
BX
0.100
SP
0.101
BP
0.110
SI
0.111
DI
1.000
R8
1.001
R9
1.010
R10
1.011
R11
1.100
R12
1.101
R13
1.110
R14
1.111
R15
00[r/m][][, + disp32][r/m][][, + disp32][r/m]
01[r/m + disp8][ + disp8][r/m + disp8][ + disp8][r/m + disp8]
10[r/m + disp32][ + disp32][r/m + disp32][ + disp32][r/m + disp32]
11r/m

1: In protected/compatibility mode, this is just disp32, but in long mode this is [RIP]+disp32 (for 64-bit addresses) or [EIP]+disp32 (for 32-bit addresses, i.e. with address-size override prefix, see here).
2: In long mode, to encode disp32 as in protected/compatibility mode, use the SIB byte.

RIP/EIP-relative addressing

Addressing in x86-64 can be relative to the current instruction pointer value. This is indicated with the RIP (64-bit) and EIP (32-bit) instruction pointer registers, which are not otherwise exposed to the program and may not exist physically. RIP-relative addressing allows object files to be location independent.

SIB

The SIB byte has the following fields:

  7                           0+---+---+---+---+---+---+---+---+| scale |   index   |    base   |+---+---+---+---+---+---+---+---+
Field Length Description
SIB.scale2 bitsThis field indicates the scaling factor of SIB.index, where s (as used in the tables) equals 2SIB.scale.
SIB.scale factor s
b001
b012
b104
b118
SIB.index3 bitsThe index register to use. See for the values to use for each of the registers. The REX.X, VEX.~X or XOP.~X field can extend this field with 1 most-significant bit to 4 bits total.
SIB.base3 bitsThe base register to use. See for the values to use for each of the registers. The REX.B, VEX.~B or XOP.~B field can extend this field with 1 most-significant bit to 4 bits total.

32/64-bit addressing

The meaning of the SIB byte while using 32 or 64-bit addressing is as follows. The ModR/M byte's Mod field and the SIB byte's index field are used vertically, the SIB byte's base field and REX/VEX/XOP.B bit horizontally. The s is the . B.Base, X.Index and Mod are in binary.

B.Base
Mod X.Index 0.000
AX
0.001
CX
0.010
DX
0.011
BX
0.100
SP
0.101
BP
0.110
SI
0.111
DI
1.000
R8
1.001
R9
1.010
R10
1.011
R11
1.100
R12
1.101
R13
1.110
R14
1.111
R15
00 0.000 AX[base + (index * s)][(index * s) + disp32][base + (index * s)][(index * s) + disp32][base + (index * s)]
0.001 CX
0.010 DX
0.011 BX
0.100 SP[base] [disp32][base] [disp32][base]
0.101 BP[base + (index * s)][(index * s) + disp32][base + (index * s)][(index * s) + disp32][base + (index * s)]
0.110 SI
0.111 DI
1.000 R8
1.001 R9
1.010 R10
1.011 R11
1.100 R12
1.101 R13
1.110 R14
1.111 R15
B.Base
Mod X.Index 0.000
AX
0.001
CX
0.010
DX
0.011
BX
0.100
SP
0.101
BP
0.110
SI
0.111
DI
1.000
R8
1.001
R9
1.010
R10
1.011
R11
1.100
R12
1.101
R13
1.110
R14
1.111
R15
01 0.000 AX[base + (index * s) + disp8]
0.001 CX
0.010 DX
0.011 BX
0.100 SP[base + disp8]
0.101 BP[base + (index * s) + disp8]
0.110 SI
0.111 DI
1.000 R8
1.001 R9
1.010 R10
1.011 R11
1.100 R12
1.101 R13
1.110 R14
1.111 R15
B.Base
Mod X.Index 0.000
AX
0.001
CX
0.010
DX
0.011
BX
0.100
SP
0.101
BP
0.110
SI
0.111
DI
1.000
R8
1.001
R9
1.010
R10
1.011
R11
1.100
R12
1.101
R13
1.110
R14
1.111
R15
10 0.000 AX[base + (index * s) + disp32]
0.001 CX
0.010 DX
0.011 BX
0.100 SP[base + disp32]
0.101 BP[base + (index * s) + disp32]
0.110 SI
0.111 DI
1.000 R8
1.001 R9
1.010 R10
1.011 R11
1.100 R12
1.101 R13
1.110 R14
1.111 R15

1: No base register is encoded.
2: No index register is encoded.

Displacement

A displacement value is a 1, 2, 4, or 8 byte offset added to the calculated address. When an 8 byte displacement is used, no immediate operand is encoded.

The displacement value, if any, follows the ModR/M and SIB bytes discussed above. When the ModR/M or SIB tables state that a disp value is required, or without a ModR/M byte the use of moffset (AMD) or moffs (Intel) in the mnemonic syntax of the instruction, then the displacement bytes are required.

Immediate

Some instructions require an immediate value. The instruction (and the operand-size column in the above table) determine the length of the immediate value. The imm8 mnemonic (or 8-bit ) means a one byte immediate value, imm16 (or 16-bit operand-size) means a two byte immediate value, imm32 (or 32-bit operand-size) a four byte value and imm64 (or 64-bit operand-size) an eight byte value. When an 8 byte immediate value is encoded, no displacement can be encoded.

See Also

External References

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux兼容内核论坛 ? 查看主题 - 【x64 指令系统】之指令编码内幕
Briefly explain the 8086 instruction format.
AMD 的 XOP 指令集编码内幕
深入系统底层
x86_64 内核常用汇编
CPU指令集的诞生、发展、分类及对处理器性能提升的作用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服