diff --git a/src/x64/StoreDynamic.go b/src/x64/StoreDynamic.go index 0fdeb9c..3a214c9 100644 --- a/src/x64/StoreDynamic.go +++ b/src/x64/StoreDynamic.go @@ -8,55 +8,7 @@ import ( // StoreDynamicNumber stores a number into the memory address at `destination` with a register offset. func StoreDynamicNumber(code []byte, destination cpu.Register, offset cpu.Register, length byte, number int) []byte { - var ( - w = byte(0) - r = byte(0) - x = byte(0) - b = byte(0) - opCode = byte(0xC7) - mod = AddressMemory - ) - - if length == 1 { - opCode = 0xC6 - } - - if offset == RSP { - tmp := offset - offset = destination - destination = tmp - } - - if length == 8 { - w = 1 - } - - if offset > 0b111 { - x = 1 - offset &= 0b111 - } - - if destination > 0b111 { - b = 1 - destination &= 0b111 - } - - if destination == RBP || destination == R13 { - mod = AddressMemoryOffset8 - } - - if length == 2 { - code = append(code, 0x66) - } - - code = append(code, REX(w, r, x, b)) - code = append(code, opCode) - code = append(code, ModRM(mod, 0b000, 0b100)) - code = append(code, SIB(Scale1, byte(offset), byte(destination))) - - if mod == AddressMemoryOffset8 { - code = append(code, 0x00) - } + code = memoryAccessDynamic(code, 0xC6, 0xC7, destination, offset, length, 0b000) switch length { case 8, 4: @@ -71,60 +23,5 @@ func StoreDynamicNumber(code []byte, destination cpu.Register, offset cpu.Regist // StoreDynamicRegister stores the contents of the `source` register into the memory address at `destination` with a register offset. func StoreDynamicRegister(code []byte, destination cpu.Register, offset cpu.Register, length byte, source cpu.Register) []byte { - var ( - w = byte(0) - r = byte(0) - x = byte(0) - b = byte(0) - opCode = byte(0x89) - mod = AddressMemory - ) - - if length == 1 { - opCode = 0x88 - } - - if offset == RSP { - tmp := offset - offset = destination - destination = tmp - } - - if length == 8 { - w = 1 - } - - if source > 0b111 { - r = 1 - source &= 0b111 - } - - if offset > 0b111 { - x = 1 - offset &= 0b111 - } - - if destination > 0b111 { - b = 1 - destination &= 0b111 - } - - if destination == RBP || destination == R13 { - mod = AddressMemoryOffset8 - } - - if length == 2 { - code = append(code, 0x66) - } - - code = append(code, REX(w, r, x, b)) - code = append(code, opCode) - code = append(code, ModRM(mod, byte(source), 0b100)) - code = append(code, SIB(Scale1, byte(offset), byte(destination))) - - if mod == AddressMemoryOffset8 { - code = append(code, 0x00) - } - - return code + return memoryAccessDynamic(code, 0x88, 0x89, destination, offset, length, source) } diff --git a/src/x64/memoryAccess.go b/src/x64/memoryAccess.go index 1ff2bca..c1c658c 100644 --- a/src/x64/memoryAccess.go +++ b/src/x64/memoryAccess.go @@ -4,10 +4,6 @@ import "git.akyoto.dev/cli/q/src/cpu" // memoryAccess encodes a memory access. func memoryAccess(code []byte, opCode8 byte, opCode32 byte, register cpu.Register, offset byte, numBytes byte, source cpu.Register) []byte { - if numBytes == 2 { - code = append(code, 0x66) - } - opCode := opCode32 if numBytes == 1 { @@ -20,6 +16,10 @@ func memoryAccess(code []byte, opCode8 byte, opCode32 byte, register cpu.Registe mod = AddressMemoryOffset8 } + if numBytes == 2 { + code = append(code, 0x66) + } + code = encode(code, mod, source, register, numBytes, opCode) if register == RSP || register == R12 { diff --git a/src/x64/memoryAccessDynamic.go b/src/x64/memoryAccessDynamic.go new file mode 100644 index 0000000..8400351 --- /dev/null +++ b/src/x64/memoryAccessDynamic.go @@ -0,0 +1,63 @@ +package x64 + +import "git.akyoto.dev/cli/q/src/cpu" + +// memoryAccessDynamic encodes a memory access using the value of a register as an offset. +func memoryAccessDynamic(code []byte, opCode8 byte, opCode32 byte, destination cpu.Register, offset cpu.Register, numBytes byte, source cpu.Register) []byte { + var ( + w = byte(0) + r = byte(0) + x = byte(0) + b = byte(0) + opCode = opCode32 + mod = AddressMemory + ) + + if numBytes == 1 { + opCode = opCode8 + } + + if offset == RSP { + tmp := offset + offset = destination + destination = tmp + } + + if numBytes == 8 { + w = 1 + } + + if source > 0b111 { + r = 1 + source &= 0b111 + } + + if offset > 0b111 { + x = 1 + offset &= 0b111 + } + + if destination > 0b111 { + b = 1 + destination &= 0b111 + } + + if destination == RBP || destination == R13 { + mod = AddressMemoryOffset8 + } + + if numBytes == 2 { + code = append(code, 0x66) + } + + code = append(code, REX(w, r, x, b)) + code = append(code, opCode) + code = append(code, ModRM(mod, byte(source), 0b100)) + code = append(code, SIB(Scale1, byte(offset), byte(destination))) + + if mod == AddressMemoryOffset8 { + code = append(code, 0x00) + } + + return code +}