x86 architecture
opcode encoding




 
upper case letters
 
DREX MVEX
EVEX
VEX mod R/M  
 
 
dst kkk imm.ssss vvvv reg r/m r | m
            Mem mod != 11
    unused B G E R GPR
        P Q (PR) N (PR) MMX
VD   L H V W (VR) U (VR) ?MM
  {K} unused vK rK   mK mask
        rB   mB bounds
  Sreg  
Address Offset   Creg      
X = [DS:rSI] Y = [ES:rDI] Dreg Flags
Imm Jmp Treg only Z is left

 
lower case letters
 
1 2 4 8 16 32 64  
byte word dword qword oword yword zword  
 
  x = oword or yword   [o,y]
  upper = yword or zword [y,z]
  normal = oword or yword or zword [o,y,z]
  half = qword or oword or yword   [o.q,o,y]
  fourth = dword or qword or oword   o.[d,q,o]
  eighth = word or dword or qword   o.[w,d,q]
 
  v = word or dword or qword  
  z = word or dword or dword  
  y = dword or qword   p = w : [z|v|y] a = z : z t = {eh}

 
colors and annotations
 
  reserved internal normal special  
reserved internal normal x86-x64
...#mod mod can be 0...3
...#reg reg can be 0...7
...#r/m r/m can be 0...7
...v only VEX-encoded form exists
...I64 invalid in PM64
...D64 defaults to O64 in PM64; 66h results in O16 (implicit RSP references)
...Df64 defaults to O64 in PM64; 66h results in O16 in AMD64 but is ignored in EM64T (near branches)
...Dv64 defaults to O64 in PM64; 66h results in #UD due to VEX encoding (near branches with masks)
...F64 defaults to O64 in PM64; 66h is ignored in AMD64 and EM64T (GDTR/IDTR and CRx/DRx/TRx)



 
instruction encodings
 
 
Fundamentally x86 operands are little-endian and of {transform} ( op {hint} ) {mask} form, arranged in dst,src[,...] order.
 
 
L1OM = {sss,ccccc} ( op {nt} ) {kkk}
 
 
K1OM = {sss} ( op {eh} ) {kkk}
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
instruction prefix(es) #1 opcode
byte(s)
mod
R/M
byte
16-bit
32-bit
SIB
byte
displacement immediate #2, #3
P1 P2 P3 P4 O2 O1 D1 D2 D3 D4 I1 I2 I3 I4
SEG, REP, LOCK, 66h, 67h 0Fh xxh byte/word/dword byte/word/dword
instruction prefix(es) opcode
bytes
mod
R/M
byte
16-bit
32-bit
SIB
byte
displacement imm  
P1 P2 P3 P4 O2 O1 O3 D1 D2 D3 D4 I1
SEG, REP, LOCK, 66h, 67h 0Fh 38h xxh byte/word/dword  
3Ah byte
7Ah xxh  
7Bh byte
instruction prefix(es) #4 opcode
byte
mod
R/M
byte
16-bit
32-bit
SIB
byte
displacement imm  
P1 P2 P3 P4 P5 O1 D1 D2 D3 D4 I1
  SEG, 67h C5h VEX xxh byte/word/dword byte
SEG, 67h C4h VEX1 VEX2 xxh
SEG, 67h 8Fh XOP1 XOP2 xxh byte/word/dword byte
byte/word/dword #1
instruction prefix(es) opcode
byte
mod
R/M
byte
16-bit
32-bit
displacement and immediate
P1 P2 P3 P4 P5 P6 P7 O1
  SEG, REP, LOCK, 66h, 67h 62h XBRW
and
oooo
I1 I2 I1 I1  
word byte byte
SIB
byte
D1 D2 D3 D4  
byte/word/dword
SEG, REP, LOCK, 66h, 67h D6h NT, sss,
and
R'R B'B
v or c
and
kkk
xxh D1 D2 D3 D4 I1 I2
byte/word/dword word
instruction prefix(es) #4 opcode
byte
mod
R/M
byte
16-bit
32-bit
SIB
byte
displacement imm  
P1 P2 P3 P4 P5 P6 O1 D1 D2 D3 D4 I1
SEG, 67h 62h MVEX1 MVEX2 MVEX3 xxh byte/word/dword byte
EVEX1 EVEX2 EVEX3
instruction prefix(es) #5 opcode
bytes
mod
R/M
byte
16-bit
32-bit
SIB
byte
DREX
byte
displacement imm  
P1 P2 P3 P4 O2 O1 O3 D1 D2 D3 D4 I1
SEG, REP, LOCK, 66h, 67h 0Fh 24h xxh byte/word/dword  
25h byte
notes descriptions
#1 In some cases it is possible to encode valid instructions that exceed the traditional 15-byte length limit. For example:

  ; 16-bit mode
  F2 F0 36 66 67 81 84 24 disp32 imm32 =  xaquire lock add [ss:esp*1+disp32],imm32
  F3 F0 36 66 67 81 84 24 disp32 imm32 = xrelease lock add [ss:esp*1+disp32],imm32
  
  ; 16-bit mode
  36 67 8F EA 78 12 84 24 disp32 imm32 = lwpins eax,[ss:esp*1+disp32],imm32
  36 67 8F EA 78 12 8C 24 disp32 imm32 = lwpval eax,[ss:esp*1+disp32],imm32
  36 67 8F EA 78 10 84 24 disp32 imm32 =  bextr eax,[ss:esp*1+disp32],imm32
  
  ; 64-bit mode
  64 67 8F EA F8 12 84 18 disp32 imm32 = lwpins rax,[fs:eax+ebx+disp32],imm32
  64 67 8F EA F8 12 8C 18 disp32 imm32 = lwpval rax,[fs:eax+ebx+disp32],imm32
  64 67 8F EA F8 10 84 18 disp32 imm32 =  bextr rax,[fs:eax+ebx+disp32],imm32

It is up to the user to avoid these cases (and the resulting #GP exception).
#2 Most 3DNow! instructions use the immediate byte as a third opcode byte.
#3 Some SSE/SSE2 instructions use the immediate byte as a condition code.
#4 The use of a REPE, REPNE, 66h, or REX prefix will result in a #UD exception.
#5 The use of a REX prefix will result in a #UD exception. The DREX byte is used instead.

 
byte encodings
 
 
type
 
7 6 5 4 3 2 1 0   7 6 5 4 3 2 1 0   7 6 5 4 3 2 1 0   7 6 5 4 3 2 1 0
mod R/M
and SIB
 
mod
 
reg r/m   scale index base        
 
REX
 
0100b = 4xh W R X B   the REX prefix must immediately precede the opcode byte(s)    
 
DREX
 
D dst (VD) O
C
0
R X B    OC0=0 for reg,r/m
 OC0=1 for r/m,reg
outside PM64, DREX.[DRXB]
are silently ignored if set to 1
   
L1OM
(misc)
 
0110_0010b = 62h
 
  X B R W oooo        
L1OM
(vector)
 
1101_0110b = D6h
 
  N
T
sss R' R B'
or
X
B   vvvvv
or
ccccc
kkk    
 
VEX2
 
1100_0101b = C5h   R vvvv L pp   mmmmm = 00001b
is implied for VEX2
   
 
VEX3
 
1100_0100b = C4h   R X B mmmmm   W vvvv L pp    
 
MVEX
 
0110_0010b = 62h   R X B R' mmmm   W vvvv 0 pp   E sss v' kkk
 
EVEX
 
0110_0010b = 62h   R X B R' 0 0 mm   W vvvv 1 pp   z LL
or
RC
b v' aaa
 
XOP
 
1000_1111b = 8Fh   R X B mmmmm   W vvvv L pp    
fields descriptions
inverted bits are stored inverted
W 0 = default operand size
1 = 64-bit operand size
R' and R mod R/M byte reg field extension
X SIB byte index field extension
mod R/M byte r/m field extension (for SIB-less MVEX/EVEX)
B mod R/M byte r/m field extension
SIB byte base field extension
opcode byte reg field extension
v' VEX prefix vvvv field extension
SIB byte index field extension (for VSIB with MVEX/EVEX)
m VEX = 000_00b (1-byte map), 000_01b (2-byte map), 000_10b (0Fh,38h), 000_11b (0Fh,3Ah)
XOP = 01000b (XOP 8 with imm), 01001b (XOP 9 without imm), 01010b (XOP A with imm)
pp 00b (none), 01b (66h), 10b (F3h), 11b (F2h)
LL or RC 00b (128-bit), 01b (256-bit), 10b (512-bit), 11b (reserved) or 00b (RN), 01b (RD), 10b (RU), 11b (RZ)



main page