Improved Windows ABI support

This commit is contained in:
Eduard Urbach 2025-02-15 18:23:33 +01:00
parent 91a3ec9d52
commit b3fec98baf
Signed by: eduard
GPG key ID: 49226B848C78F6C8
22 changed files with 124 additions and 32 deletions

View file

@ -1,6 +0,0 @@
package x86
// AlignStack aligns RSP on a 16-byte boundary.
func AlignStack(code []byte) []byte {
return append(code, 0x48, 0x83, 0xE4, 0xF0)
}

View file

@ -1,6 +1,31 @@
package x86
import "git.akyoto.dev/cli/q/src/cpu"
import (
"git.akyoto.dev/cli/q/src/cpu"
"git.akyoto.dev/cli/q/src/sizeof"
)
// PushNumber pushes a number onto the stack.
func PushNumber(code []byte, number int) []byte {
length := sizeof.Signed(number)
if length >= 8 {
panic("x86 does not support pushing 64-bit numbers")
}
if length >= 2 {
return append(
code,
0x68,
byte(number),
byte(number>>8),
byte(number>>16),
byte(number>>24),
)
}
return append(code, 0x6A, byte(number))
}
// PushRegister pushes the value inside the register onto the stack.
func PushRegister(code []byte, register cpu.Register) []byte {

View file

@ -8,6 +8,28 @@ import (
"git.akyoto.dev/go/assert"
)
func TestPushNumber(t *testing.T) {
usagePatterns := []struct {
Number int
Code []byte
}{
{0, []byte{0x6A, 0x00}},
{1, []byte{0x6A, 0x01}},
{-1, []byte{0x6A, 0xFF}},
{127, []byte{0x6A, 0x7F}},
{128, []byte{0x68, 0x80, 0x00, 0x00, 0x00}},
{0xFF, []byte{0x68, 0xFF, 0x00, 0x00, 0x00}},
{0xFFFF, []byte{0x68, 0xFF, 0xFF, 0x00, 0x00}},
{0x7FFFFFFF, []byte{0x68, 0xFF, 0xFF, 0xFF, 0x7F}},
}
for _, pattern := range usagePatterns {
t.Logf("push %d", pattern.Number)
code := x86.PushNumber(nil, pattern.Number)
assert.DeepEqual(t, code, pattern.Code)
}
}
func TestPushRegister(t *testing.T) {
usagePatterns := []struct {
Register cpu.Register

View file

@ -25,7 +25,7 @@ var (
AllRegisters = []cpu.Register{RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15}
SyscallInputRegisters = []cpu.Register{RAX, RDI, RSI, RDX, R10, R8, R9}
SyscallOutputRegisters = []cpu.Register{RAX, RCX, R11}
GeneralRegisters = []cpu.Register{RBX, R12, R13, R14, R15, RCX, R11, RBP}
GeneralRegisters = []cpu.Register{RBX, R12, R13, R14, R15, RCX, R11}
InputRegisters = SyscallInputRegisters
OutputRegisters = SyscallInputRegisters
WindowsInputRegisters = []cpu.Register{RCX, RDX, R8, R9}

View file

@ -8,7 +8,6 @@ import (
)
func TestX86(t *testing.T) {
assert.DeepEqual(t, x86.AlignStack(nil), []byte{0x48, 0x83, 0xE4, 0xF0})
assert.DeepEqual(t, x86.Call(nil, 1), []byte{0xE8, 0x01, 0x00, 0x00, 0x00})
assert.DeepEqual(t, x86.CallAtAddress(nil, 1), []byte{0xFF, 0x15, 0x01, 0x00, 0x00, 0x00})
assert.DeepEqual(t, x86.ExtendRAXToRDX(nil), []byte{0x48, 0x99})