...

Text file src/github.com/twitchyliquid64/golang-asm/README.md

Documentation: github.com/twitchyliquid64/golang-asm

     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