encoding

package
Version: v0.0.0-...-3f1fa26 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2022 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	IndirectRegisterMode                Mode = 0
	IndirectRegisterByteDisplacedMode   Mode = 1
	IndirectRegisterDoubleDisplacedMode Mode = 2
	DirectRegisterMode                  Mode = 3

	// If RM is set to SIBFollowsRM a SIB byte is expected to follow
	// the ModRM byte (see instruction format)
	SIBFollowsRM uint8 = 4
)
View Source
const (
	VEXOpcodeExtension_None VEXOpcodeExtension = 0x00
	VEXOpcodeExtension_66   VEXOpcodeExtension = 0x01
	VEXOpcodeExtension_f2   VEXOpcodeExtension = 0x03
	VEXOpcodeExtension_f3   VEXOpcodeExtension = 0x02

	VEXLegacyByte_None  VEXLegacyByte = 0x00
	VEXLegacyByte_0f    VEXLegacyByte = 0x01
	VEXLegacyByte_0f_38 VEXLegacyByte = 0x02
	VEXLegacyByte_0f_3a VEXLegacyByte = 0x03
)

Variables

View Source
var Registers16 []*Register = []*Register{
	Ax, Cx, Dx, Bx, Sp, Bp, Si, Di,
	R8w, R9w, R10w, R11w, R12w, R13w, R14w, R15w,
}
View Source
var Registers32 []*Register = []*Register{
	Eax, Ecx, Edx, Ebx, Esp, Ebp, Esi, Edi,
	R8d, R9d, R10d, R11d, R12d, R13d, R14d, R15d,
}
View Source
var Registers64 []*Register = []*Register{
	Rax, Rcx, Rdx, Rbx, Rsp, Rbp, Rsi, Rdi,
	R8, R9, R10, R11, R12, R13, R14, R15,
}
View Source
var Registers8 []*Register = []*Register{
	Al, Cl, Dl, Bl, Spl, Bpl, Sil, Dil,
	R8b, R9b, R10b, R11b, R12b, R13b, R14b, R15b,
}

Note: does not include Ah, Bh, Ch, Dh

Functions

This section is empty.

Types

type Comment

type Comment string

func (Comment) Encode

func (c Comment) Encode() (lib.MachineCode, error)

func (Comment) String

func (c Comment) String() string

type DisplacedRegister

type DisplacedRegister struct {
	*Register
	// TODO: also support the 16 bit form
	Displacement uint8
}

func (*DisplacedRegister) String

func (t *DisplacedRegister) String() string

func (*DisplacedRegister) Type

func (t *DisplacedRegister) Type() lib.Type

type DisplacedSIBRegister

type DisplacedSIBRegister struct {
	Scale Scale
	Index *Register
	Base  *Register
	// TODO: also support the 16 bit form
	Displacement uint8
}

func (*DisplacedSIBRegister) String

func (t *DisplacedSIBRegister) String() string

func (*DisplacedSIBRegister) Type

func (t *DisplacedSIBRegister) Type() lib.Type

type Float32

type Float32 float32

func (Float32) Encode

func (f Float32) Encode() []uint8

func (Float32) String

func (f Float32) String() string

func (Float32) Type

func (f Float32) Type() lib.Type

func (Float32) Width

func (t Float32) Width() lib.Size

type Float64

type Float64 float64

func (Float64) Encode

func (f Float64) Encode() []uint8

func (Float64) String

func (f Float64) String() string

func (Float64) Type

func (f Float64) Type() lib.Type

func (Float64) Width

func (t Float64) Width() lib.Size

type IndirectRegister

type IndirectRegister struct {
	*Register
}

func (*IndirectRegister) String

func (t *IndirectRegister) String() string

func (*IndirectRegister) Type

func (t *IndirectRegister) Type() lib.Type

type InstructionFormat

type InstructionFormat struct {
	Prefixes     []uint8
	VEXPrefix    *VEXPrefix
	REXPrefix    *REXPrefix
	Opcode       []uint8
	ModRM        *ModRM
	SIB          *SIB
	Displacement []uint8
	Immediate    []uint8
}

func NewInstructionFormat

func NewInstructionFormat(opcode []uint8) *InstructionFormat

func (*InstructionFormat) Encode

func (i *InstructionFormat) Encode() lib.MachineCode

func (*InstructionFormat) SetDisplacement

func (i *InstructionFormat) SetDisplacement(op lib.Operand, displacement []uint8)

func (*InstructionFormat) SetModRM

func (i *InstructionFormat) SetModRM(mode Mode, rm, reg uint8)

type Int32

type Int32 int32

func (Int32) Encode

func (i Int32) Encode() []uint8

func (Int32) String

func (i Int32) String() string

func (Int32) Type

func (i Int32) Type() lib.Type

func (Int32) Width

func (t Int32) Width() lib.Size

type ModRM

type ModRM struct {
	Mode Mode
	// The r/m field can specify a register or operand or it can be combined with the
	// mod field to encode an addressing mode.
	RM uint8
	// The reg/opcode field specifies either a register number or
	// three more bits of opcode information.
	Reg uint8
}

func NewModRM

func NewModRM(mode Mode, rm, reg uint8) *ModRM

func (*ModRM) Encode

func (m *ModRM) Encode() uint8

type Mode

type Mode uint8

type Opcode

type Opcode struct {
	Name             string
	Prefixes         []uint8
	Opcode           []uint8
	OpcodeExtensions []OpcodeExtensions
	Operands         []OpcodeOperand
}

func (*Opcode) Encode

func (o *Opcode) Encode(ops []lib.Operand) ([]uint8, error)

func (*Opcode) HasExtension

func (o *Opcode) HasExtension(ext OpcodeExtensions) bool

func (*Opcode) String

func (o *Opcode) String() string

type OpcodeExtensions

type OpcodeExtensions int

func (OpcodeExtensions) String

func (i OpcodeExtensions) String() string

type OpcodeOperand

type OpcodeOperand struct {
	Type     OperandType
	Encoding OperandEncoding
}

func (*OpcodeOperand) String

func (o *OpcodeOperand) String() string

func (OpcodeOperand) TypeCheck

func (o OpcodeOperand) TypeCheck(op lib.Operand) bool

type OperandEncoding

type OperandEncoding int
const (
	// Register will be read by the processor
	ModRM_rm_r OperandEncoding = iota
	// Register will be updated by the processor
	ModRM_rm_rw OperandEncoding = iota
	// Register will be read by the processor
	ModRM_reg_r OperandEncoding = iota
	// Register will be updated by the processor
	ModRM_reg_rw OperandEncoding = iota
	// Immediate value
	ImmediateValue OperandEncoding = iota
	// Set VEX.vvvv
	VEX_vvvv OperandEncoding = iota
	// Add register to opcode
	Opcode_plus_rd_r = iota
)

func (OperandEncoding) String

func (i OperandEncoding) String() string

type OperandType

type OperandType int
const (
	OT_rel8     OperandType = iota
	OT_rel16    OperandType = iota
	OT_rel32    OperandType = iota
	OT_m        OperandType = iota
	OT_m16      OperandType = iota
	OT_m32      OperandType = iota
	OT_m64      OperandType = iota
	OT_r8       OperandType = iota
	OT_r16      OperandType = iota
	OT_r32      OperandType = iota
	OT_r64      OperandType = iota
	OT_rm8      OperandType = iota
	OT_rm16     OperandType = iota
	OT_rm32     OperandType = iota
	OT_rm64     OperandType = iota
	OT_imm8     OperandType = iota
	OT_imm16    OperandType = iota
	OT_imm32    OperandType = iota
	OT_imm64    OperandType = iota
	OT_xmm1     OperandType = iota
	OT_xmm1m64  OperandType = iota
	OT_xmm2     OperandType = iota
	OT_xmm2m64  OperandType = iota
	OT_xmm2m128 OperandType = iota
	OT_ymm1     OperandType = iota
	OT_ymm2     OperandType = iota
	OT_ymm2m128 OperandType = iota
)

func (OperandType) String

func (i OperandType) String() string

type REXPrefix

type REXPrefix struct {
	// When true a 64-bit operand size is used. Otherwise the default size is used.
	W bool
	// This is an extension to the ModRM.Reg field.
	R bool
	// This is an extension to the SIB.index field.
	X bool
	// This is an extension to the ModRM.RM field or the SIB.base field.
	B bool
}

func NewREXPrefix

func NewREXPrefix(w, r, x, b bool) *REXPrefix

func (*REXPrefix) Encode

func (r *REXPrefix) Encode() uint8

func (*REXPrefix) String

func (r *REXPrefix) String() string

type RIPRelative

type RIPRelative struct {
	Displacement Int32
}

Get address relative to instruction pointer

func (*RIPRelative) String

func (t *RIPRelative) String() string

func (*RIPRelative) Type

func (t *RIPRelative) Type() lib.Type

func (*RIPRelative) Width

func (t *RIPRelative) Width() lib.Size

type Register

type Register struct {
	Name     string
	Register uint8
	Size     Size
}
var (
	Rax *Register = NewRegister("rax", 0, QUADWORD)
	Rcx *Register = NewRegister("rcx", 1, QUADWORD)
	Rdx *Register = NewRegister("rdx", 2, QUADWORD)
	Rbx *Register = NewRegister("rbx", 3, QUADWORD)
	Rsp *Register = NewRegister("rsp", 4, QUADWORD) // stack pointer
	Rbp *Register = NewRegister("rbp", 5, QUADWORD) // frame pointer
	Rsi *Register = NewRegister("rsi", 6, QUADWORD)
	Rdi *Register = NewRegister("rdi", 7, QUADWORD)
	R8  *Register = NewRegister("r8", 8, QUADWORD)
	R9  *Register = NewRegister("r9", 9, QUADWORD)
	R10 *Register = NewRegister("r10", 10, QUADWORD)
	R11 *Register = NewRegister("r11", 11, QUADWORD)
	R12 *Register = NewRegister("r12", 12, QUADWORD)
	R13 *Register = NewRegister("r13", 13, QUADWORD)
	R14 *Register = NewRegister("r14", 14, QUADWORD)
	R15 *Register = NewRegister("r15", 15, QUADWORD)

	Eax  *Register = NewRegister("eax", 0, DOUBLE)
	Ecx  *Register = NewRegister("ecx", 1, DOUBLE)
	Edx  *Register = NewRegister("edx", 2, DOUBLE)
	Ebx  *Register = NewRegister("ebx", 3, DOUBLE)
	Esp  *Register = NewRegister("esp", 4, DOUBLE)
	Ebp  *Register = NewRegister("ebp", 5, DOUBLE)
	Esi  *Register = NewRegister("esi", 6, DOUBLE)
	Edi  *Register = NewRegister("edi", 7, DOUBLE)
	R8d  *Register = NewRegister("r8d", 8, DOUBLE)
	R9d  *Register = NewRegister("r9d", 9, DOUBLE)
	R10d *Register = NewRegister("r10d", 10, DOUBLE)
	R11d *Register = NewRegister("r11d", 11, DOUBLE)
	R12d *Register = NewRegister("r12d", 12, DOUBLE)
	R13d *Register = NewRegister("r13d", 13, DOUBLE)
	R14d *Register = NewRegister("r14d", 14, DOUBLE)
	R15d *Register = NewRegister("r15d", 15, DOUBLE)

	Ax   *Register = NewRegister("ax", 0, WORD)
	Cx   *Register = NewRegister("cx", 1, WORD)
	Dx   *Register = NewRegister("dx", 2, WORD)
	Bx   *Register = NewRegister("bx", 3, WORD)
	Sp   *Register = NewRegister("sp", 4, WORD)
	Bp   *Register = NewRegister("bp", 5, WORD)
	Si   *Register = NewRegister("si", 6, WORD)
	Di   *Register = NewRegister("di", 7, WORD)
	R8w  *Register = NewRegister("r8w", 8, WORD)
	R9w  *Register = NewRegister("r9w", 9, WORD)
	R10w *Register = NewRegister("r10w", 10, WORD)
	R11w *Register = NewRegister("r11w", 11, WORD)
	R12w *Register = NewRegister("r12w", 12, WORD)
	R13w *Register = NewRegister("r13w", 13, WORD)
	R14w *Register = NewRegister("r14w", 14, WORD)
	R15w *Register = NewRegister("r15w", 15, WORD)

	Al   *Register = NewRegister("al", 0, BYTE)
	Cl   *Register = NewRegister("cl", 1, BYTE)
	Dl   *Register = NewRegister("dl", 2, BYTE)
	Bl   *Register = NewRegister("bl", 3, BYTE)
	Spl  *Register = NewRegister("spl", 4, BYTE)
	Bpl  *Register = NewRegister("bpl", 5, BYTE)
	Sil  *Register = NewRegister("sil", 6, BYTE)
	Dil  *Register = NewRegister("dil", 7, BYTE)
	R8b  *Register = NewRegister("r8b", 8, BYTE)
	R9b  *Register = NewRegister("r9b", 9, BYTE)
	R10b *Register = NewRegister("r10b", 10, BYTE)
	R11b *Register = NewRegister("r11b", 11, BYTE)
	R12b *Register = NewRegister("r12b", 12, BYTE)
	R13b *Register = NewRegister("r13b", 13, BYTE)
	R14b *Register = NewRegister("r14b", 14, BYTE)
	R15b *Register = NewRegister("r15b", 15, BYTE)

	Ah *Register = NewRegister("ah", 4, BYTE)
	Ch *Register = NewRegister("ch", 5, BYTE)
	Dh *Register = NewRegister("dh", 6, BYTE)
	Bh *Register = NewRegister("bh", 7, BYTE)

	Xmm0  *Register = NewRegister("xmm0", 0, OWORD)
	Xmm1  *Register = NewRegister("xmm1", 1, OWORD)
	Xmm2  *Register = NewRegister("xmm2", 2, OWORD)
	Xmm3  *Register = NewRegister("xmm3", 3, OWORD)
	Xmm4  *Register = NewRegister("xmm4", 4, OWORD)
	Xmm5  *Register = NewRegister("xmm5", 5, OWORD)
	Xmm6  *Register = NewRegister("xmm6", 6, OWORD)
	Xmm7  *Register = NewRegister("xmm7", 7, OWORD)
	Xmm8  *Register = NewRegister("xmm8", 8, OWORD)
	Xmm9  *Register = NewRegister("xmm9", 9, OWORD)
	Xmm10 *Register = NewRegister("xmm10", 10, OWORD)
	Xmm11 *Register = NewRegister("xmm11", 11, OWORD)
	Xmm12 *Register = NewRegister("xmm12", 12, OWORD)
	Xmm13 *Register = NewRegister("xmm13", 13, OWORD)
	Xmm14 *Register = NewRegister("xmm14", 14, OWORD)
	Xmm15 *Register = NewRegister("xmm15", 15, OWORD)

	Ymm0  *Register = NewRegister("ymm0", 0, YWORD)
	Ymm1  *Register = NewRegister("ymm1", 1, YWORD)
	Ymm2  *Register = NewRegister("ymm2", 2, YWORD)
	Ymm3  *Register = NewRegister("ymm3", 3, YWORD)
	Ymm4  *Register = NewRegister("ymm4", 4, YWORD)
	Ymm5  *Register = NewRegister("ymm5", 5, YWORD)
	Ymm6  *Register = NewRegister("ymm6", 6, YWORD)
	Ymm7  *Register = NewRegister("ymm7", 7, YWORD)
	Ymm8  *Register = NewRegister("ymm8", 8, YWORD)
	Ymm9  *Register = NewRegister("ymm9", 9, YWORD)
	Ymm10 *Register = NewRegister("ymm10", 10, YWORD)
	Ymm11 *Register = NewRegister("ymm11", 11, YWORD)
	Ymm12 *Register = NewRegister("ymm12", 12, YWORD)
	Ymm13 *Register = NewRegister("ymm13", 13, YWORD)
	Ymm14 *Register = NewRegister("ymm14", 14, YWORD)
	Ymm15 *Register = NewRegister("ymm15", 15, YWORD)

	Zmm0  *Register = NewRegister("zmm0", 0, ZWORD)
	Zmm1  *Register = NewRegister("zmm1", 1, ZWORD)
	Zmm2  *Register = NewRegister("zmm2", 2, ZWORD)
	Zmm3  *Register = NewRegister("zmm3", 3, ZWORD)
	Zmm4  *Register = NewRegister("zmm4", 4, ZWORD)
	Zmm5  *Register = NewRegister("zmm5", 5, ZWORD)
	Zmm6  *Register = NewRegister("zmm6", 6, ZWORD)
	Zmm7  *Register = NewRegister("zmm7", 7, ZWORD)
	Zmm8  *Register = NewRegister("zmm8", 8, ZWORD)
	Zmm9  *Register = NewRegister("zmm9", 9, ZWORD)
	Zmm10 *Register = NewRegister("zmm10", 10, ZWORD)
	Zmm11 *Register = NewRegister("zmm11", 11, ZWORD)
	Zmm12 *Register = NewRegister("zmm12", 12, ZWORD)
	Zmm13 *Register = NewRegister("zmm13", 13, ZWORD)
	Zmm14 *Register = NewRegister("zmm14", 14, ZWORD)
	Zmm15 *Register = NewRegister("zmm15", 15, ZWORD)
)

func Get64BitRegisterByIndex

func Get64BitRegisterByIndex(ix uint8) *Register

func GetFloatingPointRegisterByIndex

func GetFloatingPointRegisterByIndex(ix uint8) *Register

func NewRegister

func NewRegister(name string, register uint8, size Size) *Register

func (*Register) Encode

func (r *Register) Encode() uint8

func (*Register) ForOperandWidth

func (r *Register) ForOperandWidth(w Size) *Register

func (*Register) Get16BitRegister

func (r *Register) Get16BitRegister() *Register

func (*Register) Get32BitRegister

func (r *Register) Get32BitRegister() *Register

func (*Register) Get64BitRegister

func (r *Register) Get64BitRegister() *Register

func (*Register) Get8BitRegister

func (r *Register) Get8BitRegister() *Register

func (*Register) String

func (r *Register) String() string

func (*Register) Type

func (r *Register) Type() Type

func (*Register) Width

func (r *Register) Width() Size

type SIB

type SIB struct {
	Scale Scale // 2 bits
	Index uint8 // 3 bits
	Base  uint8 // 3 bits
}

func NewSIB

func NewSIB(scale Scale, index, base uint8) *SIB

func (*SIB) Encode

func (s *SIB) Encode() uint8

type SIBRegister

type SIBRegister struct {
	*Register
	Index *Register
	Scale Scale
}

func (*SIBRegister) String

func (t *SIBRegister) String() string

func (*SIBRegister) Type

func (t *SIBRegister) Type() lib.Type

type Scale

type Scale uint8
const (
	Scale1 Scale = 0
	Scale2 Scale = 1
	Scale4 Scale = 2
	Scale8 Scale = 3
)

func ScaleForItemWidth

func ScaleForItemWidth(itemWidth lib.Size) Scale

func (Scale) String

func (s Scale) String() string

type Uint16

type Uint16 uint16

func (Uint16) Encode

func (i Uint16) Encode() []uint8

func (Uint16) String

func (i Uint16) String() string

func (Uint16) Type

func (i Uint16) Type() lib.Type

func (Uint16) Width

func (t Uint16) Width() lib.Size

type Uint32

type Uint32 uint32

func (Uint32) Encode

func (i Uint32) Encode() []uint8

func (Uint32) String

func (i Uint32) String() string

func (Uint32) Type

func (i Uint32) Type() lib.Type

func (Uint32) Width

func (t Uint32) Width() lib.Size

type Uint64

type Uint64 uint64

func (Uint64) Encode

func (i Uint64) Encode() []uint8

func (Uint64) String

func (i Uint64) String() string

func (Uint64) Type

func (i Uint64) Type() lib.Type

func (Uint64) Width

func (t Uint64) Width() lib.Size

type Uint8

type Uint8 uint8

func (Uint8) Encode

func (i Uint8) Encode() []uint8

func (Uint8) String

func (i Uint8) String() string

func (Uint8) Type

func (i Uint8) Type() lib.Type

func (Uint8) Width

func (t Uint8) Width() lib.Size

type VEXLegacyByte

type VEXLegacyByte uint8

type VEXOpcodeExtension

type VEXOpcodeExtension uint8

type VEXPrefix

type VEXPrefix struct {
	// Non-destructive source register encoding.
	// It is represented by the notation, VEX.vvvv. This field is encoded using
	// 1’s complement form (inverted form), i.e. XMM0/YMM0/R0 is encoded as 1111B,
	// XMM15/YMM15/R15 is encoded as 0000B.
	Source uint8

	// Vector length encoding: This 1-bit field represented by the notation
	// VEX.L. L= 0 means vector length is 128 bits wide, L=1 means 256 bit vector.
	L bool

	// REX prefix functionality: Full REX prefix functionality is provided in
	// the three-byte form of VEX prefix. However the VEX bit fields providing
	// REX functionality are encoded using 1’s complement form.
	// Two-byte form of the VEX prefix only provides the equivalent functionality of REX.R
	R bool
	W bool
	X bool
	B bool

	// Compaction of SIMD prefix: Legacy SSE instructions effectively use SIMD
	// prefixes (66H, F2H, F3H) as an opcode extension field. VEX prefix
	// encoding allows the functional capability of such legacy SSE
	// instructions (operating on XMM registers, bits 255:128 of corresponding
	// YMM unmodified) to be encoded using the VEX.pp field without the
	// presence of any SIMD prefix. The VEX-encoded 128-bit instruction will
	// zero-out bits 255:128 of the destination register. VEX-encoded
	// instruction may have 128 bit vector length or 256 bits length.
	//
	// VEX.pp
	VEXOpcodeExtension VEXOpcodeExtension

	// Compaction of two-byte and three-byte opcode: More recently introduced
	// legacy SSE instructions employ two and three-byte opcode. The one or two
	// leading bytes are: 0FH, and 0FH 3AH/0FH 38H. The one-byte escape (0FH)
	// and two-byte escape (0FH 3AH, 0FH 38H) can also be interpreted as an
	// opcode extension field. The VEX.mmmmm field provides compaction to allow
	// many legacy instruction to be encoded without the constant byte
	// sequence, 0FH, 0FH 3AH, 0FH 38H.
	//
	// 00000: Reserved for future use (will #UD)
	// 00001: implied 0F leading opcode byte
	// 00010: implied 0F 38 leading opcode bytes
	// 00011: implied 0F 3A leading opcode bytes
	// 00100-11111: Reserved for future use (will #UD)
	//
	// VEX.mmmmm
	VEXLegacyByte VEXLegacyByte
}

The VEX prefix is encoded in either the two-byte form (the first byte must be C5H) or in the three-byte form (the first byte must be C4H). The two-byte VEX is used mainly for 128-bit, scalar, and the most common 256-bit AVX instructions; while the three-byte VEX provides a compact replacement of REX and 3-byte opcode instructions (including AVX and FMA instructions).

func NewVEXPrefix

func NewVEXPrefix() *VEXPrefix

func (*VEXPrefix) Encode

func (v *VEXPrefix) Encode() []uint8

type Value

type Value interface {
	Type() lib.Type
	String() string
	Encode() []uint8
	Width() lib.Size
}

Jump to

Keyboard shortcuts

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