...
1# golang-asm
2
3A mirror of the assembler from the Go compiler, with import paths re-written for the assembler to be functional as a standalone library.
4
5License as per the Go project.
6
7# Status
8
9Works, but expect to dig into the assembler godoc's to work out what to set different parameters of `obj.Prog` to get it to generate specific instructions.
10
11# Example
12
13Demonstrates assembly of a NOP & an ADD instruction on x86-64.
14
15```go
16
17package main
18
19import (
20 "fmt"
21
22 asm "github.com/twitchyliquid64/golang-asm"
23 "github.com/twitchyliquid64/golang-asm/obj"
24 "github.com/twitchyliquid64/golang-asm/obj/x86"
25)
26
27func noop(builder *asm.Builder) *obj.Prog {
28 prog := builder.NewProg()
29 prog.As = x86.ANOPL
30 prog.From.Type = obj.TYPE_REG
31 prog.From.Reg = x86.REG_AX
32 return prog
33}
34
35func addImmediateByte(builder *asm.Builder, in int32) *obj.Prog {
36 prog := builder.NewProg()
37 prog.As = x86.AADDB
38 prog.To.Type = obj.TYPE_REG
39 prog.To.Reg = x86.REG_AL
40 prog.From.Type = obj.TYPE_CONST
41 prog.From.Offset = int64(in)
42 return prog
43}
44
45func movImmediateByte(builder *asm.Builder, reg int16, in int32) *obj.Prog {
46 prog := builder.NewProg()
47 prog.As = x86.AMOVB
48 prog.To.Type = obj.TYPE_REG
49 prog.To.Reg = reg
50 prog.From.Type = obj.TYPE_CONST
51 prog.From.Offset = int64(in)
52 return prog
53}
54
55func main() {
56 b, _ := asm.NewBuilder("amd64", 64)
57 b.AddInstruction(noop(b))
58 b.AddInstruction(movImmediateByte(b, x86.REG_AL, 16))
59 b.AddInstruction(addImmediateByte(b, 16))
60 fmt.Printf("Bin: %x\n", b.Assemble())
61}
62
63```
64
65# Working out the parameters of `obj.Prog`
66
67This took me some time to work out, so I'll write a bit here.
68
69## Use these references
70
71 * `obj.Prog` - [godoc](https://godoc.org/github.com/golang/go/src/cmd/internal/obj#Prog)
72 * Some instructions (like NOP, JMP) are abstract per-platform & can be found [here](https://godoc.org/github.com/golang/go/src/cmd/internal/obj#As)
73
74 * (for amd64) `x86 pkg-constants` - [registers & instructions](https://godoc.org/github.com/golang/go/src/cmd/internal/obj/x86#pkg-constant)
75
76## Instruction constants have a naming scheme
77
78Instructions are defined as constants in the package for the relavant architecture, and have an 'A' prefix and a size suffix.
79
80For example, the MOV instruction for 64 bits of data is `AMOVQ` (well, at least in amd64).
81
82## Search the go source for usage of a given instruction
83
84For example, if I wanted to work out how to emit the MOV instruction for 64bits, I would search the go source on github for `AMOVQ` or `x86.AMOVQ`. Normally, you see find a few examples where the compiler backend fills in a `obj.Prog` structure, and you follow it's lead.
View as plain text