amd64

package module
v0.0.0-...-44622ea Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2018 License: Apache-2.0 Imports: 6 Imported by: 0

README

AMD64 Instruction Assembler

Sourcegraph GoDoc Build Status codecov rcard License

  • generate code during runtime: assembler, but run in your process
  • Go assembly does not support all SIMD instruction

This does not support all instructions yet. But it has laid a ground work on instruction encoding abstraction. New instruction will be added on demand basis.

Tutorial

import . "github.com/modern-go/amd64"

asm := &Assembler{}
asm.Assemble( 
    // RAX = i
    MOV, RAX, QWORD(RSP, 0x08),
    // j = RAX
    MOV, QWORD(RSP, 0x10), RAX,
    // return j
    RET,
)
// ident func does nothing
// return identical value out
var ident func(i int) (j int)
asm.MakeFunc(&ident)
fmt.Println(ident(100)) // will print 100

SIMD

asm := &Assembler{}
asm.Assemble(
    MOV, RDI, QWORD(RSP, 8),
    MOV, RSI, QWORD(RSP, 16),
    MOVD, XMM0, EDI,
    VPBROADCASTD, XMM0, XMM0,
    VPCMPEQD, XMM1, XMM0, XMMWORD(RSI, 0),
    VPCMPEQD, XMM2, XMM0, XMMWORD(RSI, 0x10),
    VPCMPEQD, XMM3, XMM0, XMMWORD(RSI, 0x20),
    VPCMPEQD, XMM4, XMM0, XMMWORD(RSI, 0x30),
    VPACKSSDW, XMM1, XMM1, XMM2,
    VPACKSSDW, XMM2, XMM3, XMM4,
    VPACKSSWB, XMM1, XMM1, XMM2,
    VPMOVMSKB, ECX, XMM1,
    VPCMPEQD, XMM1, XMM0, XMMWORD(RSI, 0x40),
    VPCMPEQD, XMM2, XMM0, XMMWORD(RSI, 0x50),
    VPCMPEQD, XMM3, XMM0, XMMWORD(RSI, 0x60),
    VPCMPEQD, XMM4, XMM0, XMMWORD(RSI, 0x70),
    VPACKSSDW, XMM1, XMM1, XMM2,
    VPACKSSDW, XMM2, XMM3, XMM4,
    VPACKSSWB, XMM1, XMM1, XMM2,
    VPMOVMSKB, EAX, XMM1,
    VPCMPEQD, XMM1, XMM0, XMMWORD(RSI, 0x80),
    VPCMPEQD, XMM2, XMM0, XMMWORD(RSI, 0x90),
    VPCMPEQD, XMM3, XMM0, XMMWORD(RSI, 0xa0),
    VPCMPEQD, XMM4, XMM0, XMMWORD(RSI, 0xb0),
    VPACKSSDW, XMM1, XMM1, XMM2,
    VPACKSSDW, XMM2, XMM3, XMM4,
    VPACKSSWB, XMM1, XMM1, XMM2,
    VPMOVMSKB, EDX, XMM1,
    VPCMPEQD, XMM1, XMM0, XMMWORD(RSI, 0xc0),
    VPCMPEQD, XMM2, XMM0, XMMWORD(RSI, 0xd0),
    VPCMPEQD, XMM3, XMM0, XMMWORD(RSI, 0xe0),
    VPCMPEQD, XMM0, XMM0, XMMWORD(RSI, 0xf0),
    VPACKSSDW, XMM1, XMM1, XMM2,
    VPACKSSDW, XMM0, XMM3, XMM0,
    VPACKSSWB, XMM0, XMM1, XMM0,
    VPMOVMSKB, ESI, XMM0,
    SHL, RSI, IMM(0x30),
    SHL, RDX, IMM(0x20),
    SHL, RAX, IMM(0x10),
    OR, RAX, RCX,
    OR, RAX, RDX,
    OR, RAX, RSI,
    MOV, QWORD(RSP, 0x18), RAX,
    RET,
)
var compareEqual func(key uint32, elements *[64]uint32) (ret uint64)
asm.MakeFunc(&compareEqual)
v1 := [64]uint32{
    3, 0, 0, 3, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 3, 3}
ret := compareEqual(3, &v1)
fmt.Println(strconv.FormatUint(uint64(ret), 2))

the output will be

1100000000000000000000000000000000000000000000000000000000001001

it searches the integer in the array faster by utilizing the SIMD instruction

Acknowledgement

Documentation

Index

Constants

View Source
const (
	ModeIndir       = 0x0
	ModeIndirDisp8  = 0x1
	ModeIndirDisp32 = 0x2
	ModeReg         = 0x3
)
View Source
const PageSize = 4096
View Source
const Prefix16Bit = 0x66

If a 66H override is used with REX and REX.W = 0, the operand size is 16 bits.

View Source
const Prefix32Bit = 0x67

In 64-bit mode, the instruction’s default address size is 64 bits, 32 bit address size is supported using the prefix 67H.

View Source
const PtrSize = 32 << uintptr(^uintptr(0)>>63)
View Source
const RegEBP = 5
View Source
const RegESP = 4
View Source
const Scale1 = 0
View Source
const Scale2 = 1
View Source
const Scale4 = 2
View Source
const Scale8 = 3

Variables

View Source
var (
	AL = Register{"al", 0, 8, []Qualifier{
		{REG: "al"},
		{R: 8},
		{RM: 8},
	}}
	AX = Register{"ax", 0, 16, []Qualifier{
		{R: 16},
		{RM: 16},
	}}
	EAX = Register{"eax", 0, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RAX = Register{"rax", 0, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	ECX = Register{"ecx", 1, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RCX = Register{"rcx", 1, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	EDX = Register{"edx", 2, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RDX = Register{"rdx", 2, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	BL = Register{"bl", 3, 8, []Qualifier{
		{R: 8},
		{RM: 8},
	}}
	BX = Register{"bx", 3, 16, []Qualifier{
		{R: 16},
		{RM: 16},
	}}
	EBX = Register{"ebx", 3, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RBX = Register{"rbx", 3, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	ESP = Register{"esp", 4, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RSP = Register{"rsp", 4, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	EBP = Register{"ebp", 5, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RBP = Register{"rbp", 5, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	ESI = Register{"esi", 6, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RSI = Register{"rsi", 6, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	EDI = Register{"edi", 7, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	RDI = Register{"rdi", 7, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}

	R8D = Register{"r8d", 8, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R8 = Register{"r8", 8, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	R9D = Register{"r9d", 9, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R9 = Register{"r9", 9, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	R10D = Register{"r10d", 10, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R10 = Register{"r10", 10, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	R11D = Register{"r11d", 11, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R11 = Register{"r11", 11, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	R12D = Register{"r12d", 12, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R12 = Register{"r12", 12, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	R13D = Register{"r13d", 13, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R13 = Register{"r13", 13, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	R14D = Register{"r14d", 14, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R14 = Register{"r14", 14, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	R15D = Register{"r15d", 15, 32, []Qualifier{
		{R: 32},
		{RM: 32},
	}}
	R15 = Register{"r15", 15, 64, []Qualifier{
		{R: 64},
		{RM: 64},
	}}
	XMM0 = Register{"xmm0", 0, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
	XMM1 = Register{"xmm1", 1, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
	XMM2 = Register{"xmm2", 2, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
	XMM3 = Register{"xmm3", 3, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
	XMM4 = Register{"xmm4", 4, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
	XMM5 = Register{"xmm5", 5, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
	XMM6 = Register{"xmm6", 6, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
	XMM7 = Register{"xmm7", 7, 128, []Qualifier{
		{REG: "xmm"},
		{REG: "xmm", M: 128},
	}}
)
View Source
var ABSOLUTE = Register{/* contains filtered or unexported fields */}
View Source
var ADD = &instruction{
	mnemonic: "add",
	opcode:   0x00,
	encoding: twoOperands,
	variants: variants{
		{{RM: 8}, {R: 8}}:         {},
		{{RM: 16}, {R: 16}}:       {opcode: 0x01},
		{{RM: 32}, {R: 32}}:       {opcode: 0x01},
		{{RM: 64}, {R: 64}}:       {opcode: 0x01},
		{{R: 8}, {RM: 8}}:         {opcode: 0x02},
		{{R: 16}, {RM: 16}}:       {opcode: 0x03},
		{{R: 32}, {RM: 32}}:       {opcode: 0x03},
		{{R: 64}, {RM: 64}}:       {opcode: 0x03},
		{{REG: "al"}, {IMM: 8}}:   {opcode: 0x04, encoding: encodingI},
		{{REG: "ax"}, {IMM: 16}}:  {opcode: 0x05, encoding: encodingI},
		{{REG: "eax"}, {IMM: 32}}: {opcode: 0x05, encoding: encodingI},
		{{RM: 8}, {IMM: 8}}:       {opcode: 0x80},
		{{RM: 16}, {IMM: 16}}:     {opcode: 0x81},
		{{RM: 32}, {IMM: 32}}:     {opcode: 0x81},
		{{RM: 64}, {IMM: 64}}:     {opcode: 0x81},
		{{RM: 16}, {IMM: 8}}:      {opcode: 0x83},
		{{RM: 32}, {IMM: 8}}:      {opcode: 0x83},
		{{RM: 64}, {IMM: 8}}:      {opcode: 0x83},
	},
}
View Source
var DEC = &instruction{
	mnemonic:  "dec",
	opcode:    0xff,
	opcodeReg: 1,
	encoding:  oneOperand,
	variants: variants{
		{{RM: 8}}:  {opcode: 0xfe},
		{{RM: 16}}: {},
		{{RM: 32}}: {},
		{{RM: 64}}: {},
	},
}
View Source
var INC = &instruction{
	mnemonic: "inc",
	opcode:   0xff,
	encoding: oneOperand,
	variants: variants{
		{{RM: 8}}:  {opcode: 0xfe},
		{{RM: 16}}: {},
		{{RM: 32}}: {},
		{{RM: 64}}: {},
	},
}
View Source
var MOV = &instruction{
	mnemonic: "mov",
	opcode:   0x88,
	encoding: twoOperands,
	variants: variants{
		{{RM: 8}, {R: 8}}:   {},
		{{RM: 16}, {R: 16}}: {opcode: 0x89},
		{{RM: 32}, {R: 32}}: {opcode: 0x89},
		{{RM: 64}, {R: 64}}: {opcode: 0x89},
		{{R: 8}, {RM: 8}}:   {opcode: 0x8a},
		{{R: 16}, {RM: 16}}: {opcode: 0x8b},
		{{R: 32}, {RM: 32}}: {opcode: 0x8b},
		{{R: 64}, {RM: 64}}: {opcode: 0x8b},
		{{REG: "xmm"}, {REG: "xmm", M: 128}}: {

			vexForm: form0F, opcode: 0x28, encoding: encodingA,
		},
		{{REG: "xmm", M: 128}, {REG: "xmm"}}: {

			vexForm: form0F, opcode: 0x29, encoding: encodingB,
		},
	},
}
View Source
var MOVAPS = &instruction{
	mnemonic: "movaps",
	vexForm:  form0F,
	opcode:   0x28,
	encoding: twoOperands,
	variants: variants{
		{{REG: "xmm"}, {REG: "xmm", M: 128}}: {encoding: encodingA},
		{{REG: "xmm", M: 128}, {REG: "xmm"}}: {opcode: 0x29, encoding: encodingB},
	},
}
View Source
var MOVD = &instruction{
	mnemonic: "movd",
	vexForm:  formVEX2,
	vexPP:    1,
	opcode:   0x6e,
	encoding: twoOperands,
	variants: variants{
		{{REG: "xmm"}, {RM: 32}}: {encoding: encodingA},
	},
}
View Source
var OR = &instruction{
	mnemonic: "or",
	opcode:   0x09,
	encoding: twoOperands,
	variants: variants{
		{{RM: 16}, {R: 16}}: {},
		{{RM: 32}, {R: 32}}: {},
		{{RM: 64}, {R: 64}}: {},
	},
}
View Source
var RET = &instruction{
	mnemonic: "ret",
	opcode:   0xc3,
	encoding: zeroOperand,
}
View Source
var RIP = Register{/* contains filtered or unexported fields */}
View Source
var SHL = &instruction{
	mnemonic:  "shl",
	opcode:    0xc0,
	opcodeReg: 4,
	encoding:  twoOperands,
	variants: variants{
		{{RM: 16}, {IMM: 8}}: {opcode: 0xc1},
		{{RM: 32}, {IMM: 8}}: {opcode: 0xc1},
		{{RM: 64}, {IMM: 8}}: {opcode: 0xc1},
	},
}
View Source
var VMOVAPS = &instruction{
	mnemonic: "vmovaps",
	vexForm:  formVEX2,
	opcode:   0x28,
	encoding: twoOperands,
	variants: variants{
		{{REG: "xmm"}, {REG: "xmm", M: 128}}: {encoding: encodingA},
		{{REG: "xmm", M: 128}, {REG: "xmm"}}: {opcode: 0x29, encoding: encodingB},
	},
}
View Source
var VPACKSSDW = &instruction{
	mnemonic: "vpackssdw",
	vexForm:  formVEX2,
	vexPP:    1,
	opcode:   0x6b,
	encoding: threeOperands,
	variants: variants{
		{{REG: "xmm"}, {REG: "xmm"}, {REG: "xmm", M: 128}}: {encoding: encodingB3},
	},
}
View Source
var VPACKSSWB = &instruction{
	mnemonic: "vpacksswb",
	vexForm:  formVEX2,
	vexPP:    1,
	opcode:   0x63,
	encoding: threeOperands,
	variants: variants{
		{{REG: "xmm"}, {REG: "xmm"}, {REG: "xmm", M: 128}}: {encoding: encodingB3},
	},
}
View Source
var VPBROADCASTD = &instruction{
	mnemonic: "vpbroadcastd",
	vexForm:  formVEX3,
	vexPP:    1,
	opcode:   0x58,
	encoding: twoOperands,
	variants: variants{
		{{REG: "xmm"}, {REG: "xmm"}}: {encoding: encodingA},
	},
}
View Source
var VPCMPEQD = &instruction{
	mnemonic: "vpcmpeqd",
	vexForm:  formVEX2,
	vexPP:    1,
	opcode:   0x76,
	encoding: threeOperands,
	variants: variants{
		{{REG: "xmm"}, {REG: "xmm"}, {REG: "xmm", M: 128}}: {encoding: encodingB3},
	},
}
View Source
var VPMOVMSKB = &instruction{
	mnemonic: "vpmovmskb",
	vexForm:  formVEX2,
	vexPP:    1,
	opcode:   0xd7,
	encoding: twoOperands,
	variants: variants{
		{{R: 32}, {REG: "xmm"}}: {encoding: encodingRM},
	},
}

Functions

func BYTE

func BYTE(base Register, offset int) interface{}

func BYTE_SIB

func BYTE_SIB(scale byte, index Register, base Register, offset int) interface{}

func DWORD

func DWORD(base Register, offset int) interface{}

func DWORD_SIB

func DWORD_SIB(scale byte, index Register, base Register, offset int) interface{}

func Dump

func Dump(instructions ...interface{}) string

func HaveAVX

func HaveAVX() bool

HaveAVX returns true when there is AVX support

func HaveAVX2

func HaveAVX2() bool

HaveAVX2 returns true when there is AVX2 support

func HaveAVX512

func HaveAVX512() bool

HaveAVX512 returns true when there is AVX512 support

func HaveSSSE3

func HaveSSSE3() bool

HaveSSSE3 returns true when there is SSSE3 support

func IMM

func IMM(val uint32) interface{}

func MODRM

func MODRM(mod byte, reg byte, rm byte) byte

func QWORD

func QWORD(base Register, offset int) interface{}

func QWORD_SIB

func QWORD_SIB(scale byte, index Register, base Register, offset int) interface{}

func REX

func REX(w, r, x, b bool) byte

func SIB

func SIB(scale byte, index byte, base byte) byte

func VEX2

func VEX2(r, vvvv, l, pp byte) byte

func VEX31

func VEX31(r, x, b, m byte) byte

func VEX32

func VEX32(w, vvvv, l, pp byte) byte

func WORD

func WORD(base Register, offset int) interface{}

func WORD_SIB

func WORD_SIB(scale byte, index Register, base Register, offset int) interface{}

func XMMWORD

func XMMWORD(base Register, offset int) interface{}

Types

type AbsoluteIndirect

type AbsoluteIndirect struct {
	Indirect
}

type Assembler

type Assembler struct {
	Buffer []byte
	Error  error
}

func (*Assembler) Assemble

func (asm *Assembler) Assemble(instructions ...interface{})

func (*Assembler) MakeFunc

func (asm *Assembler) MakeFunc(f interface{})

func (*Assembler) ReportError

func (asm *Assembler) ReportError(err error)

type Immediate

type Immediate struct {
	// contains filtered or unexported fields
}

func (Immediate) Bits

func (i Immediate) Bits() byte

func (Immediate) Qualifiers

func (i Immediate) Qualifiers() []Qualifier

func (Immediate) String

func (i Immediate) String() string

type Indirect

type Indirect struct {
	// contains filtered or unexported fields
}

func (Indirect) Bits

func (i Indirect) Bits() byte

func (Indirect) Qualifiers

func (i Indirect) Qualifiers() []Qualifier

func (Indirect) String

func (i Indirect) String() string

type Operand

type Operand interface {
	fmt.Stringer

	Qualifiers() []Qualifier
	Bits() byte
	// contains filtered or unexported methods
}

type Qualifier

type Qualifier struct {
	R   byte   // register, size
	M   byte   // memory, size
	RM  byte   // register or memory, size
	IMM byte   // immediate, size
	REG string // special register
}

type Register

type Register struct {
	// contains filtered or unexported fields
}

func (Register) Bits

func (r Register) Bits() byte

func (Register) Qualifiers

func (r Register) Qualifiers() []Qualifier

func (Register) String

func (r Register) String() string

func (Register) Value

func (r Register) Value() byte

type RipIndirect

type RipIndirect struct {
	Indirect
}

type ScaledIndirect

type ScaledIndirect struct {
	Indirect
	// contains filtered or unexported fields
}

func (ScaledIndirect) String

func (i ScaledIndirect) String() string

type VariantKey

type VariantKey [3]Qualifier

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL