- For beginners, I recommend these introductory tutorials first:
Assembly Language Quick Start
Assembly Language Primer (Ruan Yifeng) - Be sure to read Mr. Ruan’s tutorial in detail
Common Identifiers (See Registers and Operation Instructions tables at the end for more)
$
prefix followed by numbers represents a constant valueFUNCDATA
andPCDATA
instructions contain garbage collector information generated by the compilerPCDATA
syntax:PCDATA tableid, tableoffset
PCDATA
has two parameters: table type and table offset. Current implementations includePCDATA_StackMapIndex
andPCDATA_InlTreeIndex
table types. Both contain code location info (file path, line numbers, function info), withPCDATA_InlTreeIndex
used for inlined functions.
FUNCDATA tableid, tableoffset
Similar to
PCDATA
: first parameter is table type, second is table offset. Current implementations define three FUNC table types:FUNCDATA_ArgsPointerMaps
(function argument pointers),FUNCDATA_LocalsPointerMaps
(local pointers), andFUNCDATA_InlTree
(inlined function pointers). These tables help Go’s garbage collector track pointer lifecycles.
Operations Below
C:\Users\seth-shi> cat main.go
package main
func Add(x, y int) int {
return x + y
}
C:\Users\seth-shi> go build -gcflags -S main.go
- Comments starting with
##
are my understanding/research results.[]
indicates areas needing further study
# command-line-arguments
## Defines process "".Add with args=0x0 locals=0x18 (hex 24) [Need to study size/args]
"".Add STEXT nosplit size=19 args=0x18 locals=0x0 funcid=0x0
## TEXT pseudo-operation defines process at "".Add(SB) address
## $0-24 indicates stack size (3*8 bytes for ints?) [Needs verification]
## ABIInternal = Application Binary Interface Internal
0x0000 00000 (C:\Users\seth-shi\main.go:3) TEXT "".Add(SB), NOSPLIT|ABIInternal, $0-24
## GC info (ignore)
0x0000 00000 (C:\Users\seth-shi\main.go:3) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (C:\Users\seth-shi\main.go:3) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
## Move stack+16 to AX [Need to verify stack direction]
0x0000 00000 (C:\Users\seth-shi\main.go:4) MOVQ "".y+16(SP), AX
## Move stack+8 to CX
0x0005 00005 (C:\Users\seth-shi\main.go:4) MOVQ "".x+8(SP), CX
## Add CX to AX
0x000a 00010 (C:\Users\seth-shi\main.go:4) ADDQ CX, AX
## Store result at stack+24
0x000d 00013 (C:\Users\seth-shi\main.go:4) MOVQ AX, "".~r2+24(SP)
## Return
0x0012 00018 (C:\Users\seth-shi\main.go:4) RET
0x0000 48 8b 44 24 10 48 8b 4c 24 08 48 01 c8 48 89 44 H.D$.H.L$.H..H.D
0x0010 24 18 c3 $..
go.cuinfo.packagename.main SDWARFCUINFO dupok size=0
0x0000 6d 61 69 6e main
go.string."0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nmod\tseth\t(devel)\t\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2" SRODATA dupok size=78
0x0000 30 77 af 0c 92 74 08 02 41 e1 c1 07 e6 d6 18 e6 0w...t..A.......
0x0010 70 61 74 68 09 63 6f 6d 6d 61 6e 64 2d 6c 69 6e path.command-lin
0x0020 65 2d 61 72 67 75 6d 65 6e 74 73 0a 6d 6f 64 09 e-arguments.mod.
0x0030 73 65 74 68 09 28 64 65 76 65 6c 29 09 0a f9 32 seth.(devel)...2
0x0040 43 31 86 18 20 72 00 82 42 10 41 16 d8 f2 C1.. r..B.A...
""..inittask SNOPTRDATA size=24
0x0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0010 00 00 00 00 00 00 00 00 ........
runtime.modinfo SDATA size=16
0x0000 00 00 00 00 00 00 00 00 4e 00 00 00 00 00 00 00 ........N.......
rel 0+8 t=1 go.string."0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nmod\tseth\t(devel)\t\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2"+0
type..importpath.unsafe. SRODATA dupok size=9
0x0000 00 00 06 75 6e 73 61 66 65 ...unsafe
gclocals·33cdeccccebe80329f1fdbee7f5874cb SRODATA dupok size=8
0x0000 01 00 00 00 00 00 00 00 ........
# command-line-arguments
runtime.main_main·f: function main is undeclared in the main package
Registers
Mnemonic | Name | Purpose |
---|---|---|
AX | Accumulator Register | Data storage for arithmetic, operands, results, and temporary addresses |
BX | Base Register | Memory access address storage |
CX | Count Register | Counter values |
DX | Data Register | Data transfer and I/O port addresses |
SP | Stack Pointer | symbol+offset(SP) = Go pseudo-register; offset(SP) = hardware register |
BP | Base Pointer | Stack base address before function entry |
SB | Static Base Pointer | Go pseudo-register. foo(SB) = memory address; foo+4(SB) = 4-byte offset |
FP | Frame Pointer | Go pseudo-register. References function parameters via symbol+offset(FP) |
SI | Source Index | Source operand offset |
DI | Destination Index | Destination operand offset |
Operation Instructions
Mnemonic | Type | Purpose | Example |
---|---|---|---|
MOVQ | Data Transfer | Move data | MOVQ 48, AX moves 48 to AX |
LEAQ | Address Transfer | Load effective address | LEAQ AX, BX loads AX address into BX |
ADDQ | Arithmetic | Add and assign | ADDQ BX, AX stores BX+AX in AX |
SUBQ | Arithmetic | Subtract and assign | (Similar to ADDQ) |
IMULQ | Arithmetic | Unsigned multiply | (Similar to ADDQ) |
IDIVQ | Arithmetic | Unsigned divide | IDIVQ CX divides AX by CX, result in AX |
CMPQ | Comparison | Compare values | CMPQ SI, CX compares registers |
CALL | Control Flow | Function call | CALL runtime.printnl(SB) calls println |
JMP | Control Flow | Unconditional jump | JMP 389 jumps to 0x0185 |
JLS | Control Flow | Conditional jump (less than) | JLS 389 jumps if SI < CX |
References
A Morning Spent on Golang’s Plan9 Assembly
Go Compiler Tools: Plan9 Assembly
Go Plan9 Assembly Primer - Bridging Application and Low-Level [Go Night Reading]