Implemented function calls
This commit is contained in:
@ -1,12 +1,18 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
||||
"git.akyoto.dev/cli/q/src/build/asm"
|
||||
"git.akyoto.dev/cli/q/src/build/os/linux"
|
||||
)
|
||||
|
||||
// Finalize generates the final machine code.
|
||||
func Finalize(functions map[string]*Function) ([]byte, []byte) {
|
||||
a := asm.New()
|
||||
a := entry()
|
||||
|
||||
main := functions["main"]
|
||||
delete(functions, "main")
|
||||
a.Merge(&main.Assembler)
|
||||
|
||||
for _, f := range functions {
|
||||
a.Merge(&f.Assembler)
|
||||
@ -15,3 +21,16 @@ func Finalize(functions map[string]*Function) ([]byte, []byte) {
|
||||
code, data := a.Finalize()
|
||||
return code, data
|
||||
}
|
||||
|
||||
// entry returns the entry point of the executable.
|
||||
// The only job of the entry function is to call `main` and exit cleanly.
|
||||
// The reason we call `main` instead of using `main` itself is to place
|
||||
// a return address on the stack, which allows return statements in `main`.
|
||||
func entry() *asm.Assembler {
|
||||
entry := asm.New()
|
||||
entry.Call("main")
|
||||
entry.MoveRegisterNumber(x64.SyscallArgs[0], linux.Exit)
|
||||
entry.MoveRegisterNumber(x64.SyscallArgs[1], 0)
|
||||
entry.Syscall()
|
||||
return entry
|
||||
}
|
||||
|
Reference in New Issue
Block a user