Implemented function calls

This commit is contained in:
2024-06-18 16:42:56 +02:00
parent 086998a0c3
commit 76db8feee3
11 changed files with 114 additions and 62 deletions

View File

@ -4,7 +4,6 @@ import (
"encoding/binary"
"git.akyoto.dev/cli/q/src/build/arch/x64"
"git.akyoto.dev/cli/q/src/build/config"
)
// Assembler contains a list of instructions.
@ -23,19 +22,14 @@ func New() *Assembler {
func (a *Assembler) Finalize() ([]byte, []byte) {
code := make([]byte, 0, len(a.Instructions)*8)
data := make([]byte, 0, 16)
labels := map[string]Address{}
pointers := []Pointer{}
for _, x := range a.Instructions {
switch x.Mnemonic {
case MOVE:
code = x64.MoveRegNum32(code, uint8(x.Data.(*RegisterNumber).Register), uint32(x.Data.(*RegisterNumber).Number))
if x.Data.(*RegisterNumber).IsPointer {
pointers = append(pointers, Pointer{
Position: Address(len(code) - 4),
Address: Address(x.Data.(*RegisterNumber).Number),
})
}
regNum := x.Data.(*RegisterNumber)
code = x64.MoveRegNum32(code, uint8(regNum.Register), uint32(regNum.Number))
case RETURN:
code = x64.Return(code)
@ -43,17 +37,33 @@ func (a *Assembler) Finalize() ([]byte, []byte) {
case SYSCALL:
code = x64.Syscall(code)
case CALL:
code = x64.Call(code, 0x00_00_00_00)
label := x.Data.(*Label)
nextInstructionAddress := len(code)
pointers = append(pointers, Pointer{
Position: Address(len(code) - 4),
Resolve: func() Address {
destination := labels[label.Name]
distance := int32(destination) - int32(nextInstructionAddress)
return Address(distance)
},
})
case LABEL:
labels[x.Data.(*Label).Name] = Address(len(code))
default:
panic("Unknown mnemonic: " + x.Mnemonic.String())
}
}
dataStart := config.BaseAddress + config.CodeOffset + Address(len(code))
// dataStart := config.BaseAddress + config.CodeOffset + Address(len(code))
for _, pointer := range pointers {
slice := code[pointer.Position : pointer.Position+4]
address := dataStart + pointer.Address
binary.LittleEndian.PutUint32(slice, address)
binary.LittleEndian.PutUint32(slice, pointer.Resolve())
}
return code, data