1
// Copyright 2014 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
5
// Package x86asm implements decoding of x86 machine code.
13
// An Inst is a single instruction.
15
Prefix Prefixes // Prefixes applied to the instruction.
16
Op Op // Opcode mnemonic
17
Opcode uint32 // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)
18
Args Args // Instruction arguments, in Intel order
19
Mode int // processor mode in bits: 16, 32, or 64
20
AddrSize int // address size in bits: 16, 32, or 64
21
DataSize int // operand size in bits: 16, 32, or 64
22
MemBytes int // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.
23
Len int // length of encoded instruction in bytes
24
PCRel int // length of PC-relative address in instruction encoding
25
PCRelOff int // index of start of PC-relative address in instruction encoding
28
// Prefixes is an array of prefixes associated with a single instruction.
29
// The prefixes are listed in the same order as found in the instruction:
30
// each prefix byte corresponds to one slot in the array. The first zero
31
// in the array marks the end of the prefixes.
32
type Prefixes [14]Prefix
34
// A Prefix represents an Intel instruction prefix.
35
// The low 8 bits are the actual prefix byte encoding,
36
// and the top 8 bits contain distinguishing bits and metadata.
40
// Metadata about the role of a prefix in an instruction.
41
PrefixImplicit Prefix = 0x8000 // prefix is implied by instruction text
42
PrefixIgnored Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix
43
PrefixInvalid Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)
45
// Memory segment overrides.
46
PrefixES Prefix = 0x26 // ES segment override
47
PrefixCS Prefix = 0x2E // CS segment override
48
PrefixSS Prefix = 0x36 // SS segment override
49
PrefixDS Prefix = 0x3E // DS segment override
50
PrefixFS Prefix = 0x64 // FS segment override
51
PrefixGS Prefix = 0x65 // GS segment override
54
PrefixPN Prefix = 0x12E // predict not taken (conditional branch only)
55
PrefixPT Prefix = 0x13E // predict taken (conditional branch only)
58
PrefixDataSize Prefix = 0x66 // operand size override
59
PrefixData16 Prefix = 0x166
60
PrefixData32 Prefix = 0x266
61
PrefixAddrSize Prefix = 0x67 // address size override
62
PrefixAddr16 Prefix = 0x167
63
PrefixAddr32 Prefix = 0x267
66
PrefixLOCK Prefix = 0xF0 // lock
67
PrefixREPN Prefix = 0xF2 // repeat not zero
68
PrefixXACQUIRE Prefix = 0x1F2
69
PrefixBND Prefix = 0x2F2
70
PrefixREP Prefix = 0xF3 // repeat
71
PrefixXRELEASE Prefix = 0x1F3
73
// The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).
74
// the other bits are set or not according to the intended use.
75
PrefixREX Prefix = 0x40 // REX 64-bit extension prefix
76
PrefixREXW Prefix = 0x08 // extension bit W (64-bit instruction width)
77
PrefixREXR Prefix = 0x04 // extension bit R (r field in modrm)
78
PrefixREXX Prefix = 0x02 // extension bit X (index field in sib)
79
PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
80
PrefixVEX2Bytes Prefix = 0xC5 // Short form of vex prefix
81
PrefixVEX3Bytes Prefix = 0xC4 // Long form of vex prefix
84
// IsREX reports whether p is a REX prefix byte.
85
func (p Prefix) IsREX() bool {
86
return p&0xF0 == PrefixREX
89
func (p Prefix) IsVEX() bool {
90
return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes
93
func (p Prefix) String() string {
94
p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
95
if s := prefixNames[p]; s != "" {
101
if p&PrefixREXW != 0 {
104
if p&PrefixREXR != 0 {
107
if p&PrefixREXX != 0 {
110
if p&PrefixREXB != 0 {
116
return fmt.Sprintf("Prefix(%#x)", int(p))
119
// An Op is an x86 opcode.
122
func (op Op) String() string {
124
if i < 0 || i >= len(opNames) || opNames[i] == "" {
125
return fmt.Sprintf("Op(%d)", i)
130
// An Args holds the instruction arguments.
131
// If an instruction has fewer than 4 arguments,
132
// the final elements in the array are nil.
135
// An Arg is a single instruction argument,
136
// one of these types: Reg, Mem, Imm, Rel.
142
// Note that the implements of Arg that follow are all sized
143
// so that on a 64-bit machine the data can be inlined in
144
// the interface value instead of requiring an allocation.
146
// A Reg is a single register.
147
// The zero Reg value has no name but indicates “no register.”
229
// Instruction pointer.
234
// 387 floating point registers.
272
// Segment registers.
287
// Control registers.
338
func (r Reg) String() string {
340
if i < 0 || i >= len(regNames) || regNames[i] == "" {
341
return fmt.Sprintf("Reg(%d)", i)
346
// A Mem is a memory reference.
347
// The general form is Segment:[Base+Scale*Index+Disp].
358
func (m Mem) String() string {
359
var base, plus, scale, index, disp string
362
base = m.Base.String()
369
scale = fmt.Sprintf("%d*", m.Scale)
371
index = m.Index.String()
373
if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
374
disp = fmt.Sprintf("%+#x", m.Disp)
376
return "[" + base + plus + scale + index + disp + "]"
379
// A Rel is an offset relative to the current instruction pointer.
384
func (r Rel) String() string {
385
return fmt.Sprintf(".%+d", r)
388
// An Imm is an integer constant.
393
func (i Imm) String() string {
394
return fmt.Sprintf("%#x", int64(i))
397
func (i Inst) String() string {
399
for _, p := range i.Prefix {
403
if p&PrefixImplicit != 0 {
406
fmt.Fprintf(&buf, "%v ", p)
408
fmt.Fprintf(&buf, "%v", i.Op)
410
for _, v := range i.Args {
414
fmt.Fprintf(&buf, "%s%v", sep, v)
420
func isReg(a Arg) bool {
425
func isSegReg(a Arg) bool {
427
return ok && ES <= r && r <= GS
430
func isMem(a Arg) bool {
435
func isImm(a Arg) bool {
440
func regBytes(a Arg) int {
445
if AL <= r && r <= R15B {
448
if AX <= r && r <= R15W {
451
if EAX <= r && r <= R15L {
454
if RAX <= r && r <= R15 {
460
func isSegment(p Prefix) bool {
462
case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
468
// The Op definitions and string list are in tables.go.
470
var prefixNames = map[Prefix]string{
480
PrefixAddrSize: "ADDRSIZE",
481
PrefixDataSize: "DATASIZE",
482
PrefixAddr16: "ADDR16",
483
PrefixData16: "DATA16",
484
PrefixAddr32: "ADDR32",
485
PrefixData32: "DATA32",
487
PrefixXACQUIRE: "XACQUIRE",
488
PrefixXRELEASE: "XRELEASE",
494
var regNames = [...]string{