Skip to content

Instantly share code, notes, and snippets.

@mrnugget
Created August 17, 2018 15:18
Show Gist options
  • Save mrnugget/ab15e1eb8c0c17b32ef7b7918377b629 to your computer and use it in GitHub Desktop.
Save mrnugget/ab15e1eb8c0c17b32ef7b7918377b629 to your computer and use it in GitHub Desktop.
JITting a function that writes the letter 'H' to a bytes buffer
package main
import (
"bytes"
"fmt"
"github.com/nelhage/gojit"
"github.com/nelhage/gojit/amd64"
)
var abi amd64.ABI
func main() {
// mmap executable memory
buf, e := gojit.Alloc(gojit.PageSize * 4)
if e != nil {
panic(e)
}
// Output buffer
wr := bytes.NewBuffer([]byte{})
// Set up amd64 assembler
asm := &amd64.Assembler{Buf: buf, ABI: abi}
asm.Mov(amd64.Indirect{amd64.Rdi, 0, 64}, amd64.Rax)
// Move 0x48 ('H' in hex) to %rax
asm.Addb(amd64.Imm{int32(0x48)}, amd64.Indirect{amd64.Rax, 0, 8})
// Save %rax
asm.Push(amd64.Rax)
// Setup arguments for call to `wr.Write` on stack
asm.Sub(amd64.Imm{48}, amd64.Rsp)
asm.Mov(amd64.Imm{1}, amd64.Indirect{amd64.Rsp, 16, 64})
asm.Mov(amd64.Imm{1}, amd64.Indirect{amd64.Rsp, 8, 64})
asm.Mov(amd64.Rax, amd64.Indirect{amd64.Rsp, 0, 64})
asm.CallFunc(wr.Write)
// Remove arguments from stack
asm.Add(amd64.Imm{48}, amd64.Rsp)
// Restore %rax
asm.Pop(amd64.Rax)
// Return from jitted function
asm.Ret()
// Cast executable memory into function
var jittedFunc func()
asm.BuildTo(&jittedFunc)
// Call function
jittedFunc()
fmt.Println(wr.String())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment