From d6db1b10969a9f508865d65f025cc30ea93518bd Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Tue, 23 Jul 2024 10:47:27 +0200 Subject: [PATCH] Improved x64 documentation --- src/build/arch/x64/ModRM.go | 19 +++++++++++-------- src/build/arch/x64/SIB.go | 19 +++++++++++-------- src/build/arch/x64/encode.go | 2 +- src/build/arch/x64/encodeNum.go | 2 +- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/build/arch/x64/ModRM.go b/src/build/arch/x64/ModRM.go index ca6a327..bb6852e 100644 --- a/src/build/arch/x64/ModRM.go +++ b/src/build/arch/x64/ModRM.go @@ -1,16 +1,19 @@ package x64 +// AddressMode encodes the addressing mode. +type AddressMode = byte + const ( - AddressMemory = byte(0b00) - AddressMemoryOffset8 = byte(0b01) - AddressMemoryOffset32 = byte(0b10) - AddressDirect = byte(0b11) + AddressMemory = AddressMode(0b00) + AddressMemoryOffset8 = AddressMode(0b01) + AddressMemoryOffset32 = AddressMode(0b10) + AddressDirect = AddressMode(0b11) ) // ModRM is used to generate a ModRM suffix. -// - mod: 2 bits -// - reg: 3 bits -// - rm: 3 bits -func ModRM(mod byte, reg byte, rm byte) byte { +// - mod: 2 bits. The addressing mode. +// - reg: 3 bits. Register reference or opcode extension. +// - rm: 3 bits. Register operand. +func ModRM(mod AddressMode, reg byte, rm byte) byte { return (mod << 6) | (reg << 3) | rm } diff --git a/src/build/arch/x64/SIB.go b/src/build/arch/x64/SIB.go index 030ffac..438024d 100644 --- a/src/build/arch/x64/SIB.go +++ b/src/build/arch/x64/SIB.go @@ -1,16 +1,19 @@ package x64 +// ScaleFactor encodes the scale factor. +type ScaleFactor = byte + const ( - Scale1 = byte(0b00) - Scale2 = byte(0b01) - Scale4 = byte(0b10) - Scale8 = byte(0b11) + Scale1 = ScaleFactor(0b00) + Scale2 = ScaleFactor(0b01) + Scale4 = ScaleFactor(0b10) + Scale8 = ScaleFactor(0b11) ) // SIB is used to generate an SIB byte. -// - scale: 2 bits -// - index: 3 bits -// - base: 3 bits -func SIB(scale byte, index byte, base byte) byte { +// - scale: 2 bits. Multiplies the value of the index. +// - index: 3 bits. Specifies the index register. +// - base: 3 bits. Specifies the base register. +func SIB(scale ScaleFactor, index byte, base byte) byte { return (scale << 6) | (index << 3) | base } diff --git a/src/build/arch/x64/encode.go b/src/build/arch/x64/encode.go index 606f6e2..570076d 100644 --- a/src/build/arch/x64/encode.go +++ b/src/build/arch/x64/encode.go @@ -3,7 +3,7 @@ package x64 import "git.akyoto.dev/cli/q/src/build/cpu" // encode is the core function that encodes an instruction. -func encode(code []byte, mod byte, reg cpu.Register, rm cpu.Register, numBytes byte, opCodes ...byte) []byte { +func encode(code []byte, mod AddressMode, reg cpu.Register, rm cpu.Register, numBytes byte, opCodes ...byte) []byte { w := byte(0) // Indicates a 64-bit register. r := byte(0) // Extension to the "reg" field in ModRM. x := byte(0) // Extension to the SIB index field. diff --git a/src/build/arch/x64/encodeNum.go b/src/build/arch/x64/encodeNum.go index 15efe03..2053dfb 100644 --- a/src/build/arch/x64/encodeNum.go +++ b/src/build/arch/x64/encodeNum.go @@ -7,7 +7,7 @@ import ( ) // encodeNum encodes an instruction with up to two registers and a number parameter. -func encodeNum(code []byte, mod byte, reg cpu.Register, rm cpu.Register, number int, opCode8 byte, opCode32 byte) []byte { +func encodeNum(code []byte, mod AddressMode, reg cpu.Register, rm cpu.Register, number int, opCode8 byte, opCode32 byte) []byte { if SizeOf(int64(number)) == 1 { code = encode(code, mod, reg, rm, 8, opCode8) return append(code, byte(number))