The assembler program is a way to parse a description of that semi-abstract instruction set and turn it into instructions to be input to the linker. If you want to see what the instructions look like in assembly for a given architecture, say amd64, there are many examples in the sources of the standard library, in packages such as runtime and math/big. You can also examine what the compiler emits as assembly code (the actual output may differ from what you see here):

$ cat x.go
package main

func main() {
	println(3)
}
$ GOOS=linux GOARCH=amd64 go tool compile -S x.go        # or: go build -gcflags -S x.go
"".main STEXT size=74 args=0x0 locals=0x10
	0x0000 00000 (x.go:3)	TEXT	"".main(SB), $16-0
	0x0000 00000 (x.go:3)	MOVQ	(TLS), CX
	0x0009 00009 (x.go:3)	CMPQ	SP, 16(CX)
	0x000d 00013 (x.go:3)	JLS	67
	0x000f 00015 (x.go:3)	SUBQ	$16, SP
	0x0013 00019 (x.go:3)	MOVQ	BP, 8(SP)
	0x0018 00024 (x.go:3)	LEAQ	8(SP), BP
	0x001d 00029 (x.go:3)	FUNCDATA	$0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
	0x001d 00029 (x.go:3)	FUNCDATA	$1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
	0x001d 00029 (x.go:3)	FUNCDATA	$2, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
	0x001d 00029 (x.go:4)	PCDATA	$0, $0
	0x001d 00029 (x.go:4)	PCDATA	$1, $0
	0x001d 00029 (x.go:4)	CALL	runtime.printlock(SB)
	0x0022 00034 (x.go:4)	MOVQ	$3, (SP)
	0x002a 00042 (x.go:4)	CALL	runtime.printint(SB)
	0x002f 00047 (x.go:4)	CALL	runtime.printnl(SB)
	0x0034 00052 (x.go:4)	CALL	runtime.printunlock(SB)
	0x0039 00057 (x.go:5)	MOVQ	8(SP), BP
	0x003e 00062 (x.go:5)	ADDQ	$16, SP
	0x0042 00066 (x.go:5)	RET
	0x0043 00067 (x.go:5)	NOP
	0x0043 00067 (x.go:3)	PCDATA	$1, $-1
	0x0043 00067 (x.go:3)	PCDATA	$0, $-1
	0x0043 00067 (x.go:3)	CALL	runtime.morestack_noctxt(SB)
	0x0048 00072 (x.go:3)	JMP	0
...
To see what gets put in the binary after linking, use go tool objdump:

$ go build -o x.exe x.go
$ go tool objdump -s main.main x.exe
TEXT main.main(SB) /tmp/x.go
  x.go:3		0x10501c0		65488b0c2530000000	MOVQ GS:0x30, CX
  x.go:3		0x10501c9		483b6110		CMPQ 0x10(CX), SP
  x.go:3		0x10501cd		7634			JBE 0x1050203
  x.go:3		0x10501cf		4883ec10		SUBQ $0x10, SP
  x.go:3		0x10501d3		48896c2408		MOVQ BP, 0x8(SP)
  x.go:3		0x10501d8		488d6c2408		LEAQ 0x8(SP), BP
  x.go:4		0x10501dd		e86e45fdff		CALL runtime.printlock(SB)
  x.go:4		0x10501e2		48c7042403000000	MOVQ $0x3, 0(SP)
  x.go:4		0x10501ea		e8e14cfdff		CALL runtime.printint(SB)
  x.go:4		0x10501ef		e8ec47fdff		CALL runtime.printnl(SB)
  x.go:4		0x10501f4		e8d745fdff		CALL runtime.printunlock(SB)
  x.go:5		0x10501f9		488b6c2408		MOVQ 0x8(SP), BP
  x.go:5		0x10501fe		4883c410		ADDQ $0x10, SP
  x.go:5		0x1050202		c3			RET
  x.go:3		0x1050203		e83882ffff		CALL runtime.morestack_noctxt(SB)
  x.go:3		0x1050208		ebb6			JMP main.main(SB)
The assembler uses various directives to bind text and data to symbol names. For example, here is a simple complete function definition. The TEXT directive declares the symbol runtime·profileloop and the instructions that follow form the body of the function. The last instruction in a TEXT block must be some sort of jump, usually a RET (pseudo-)instruction. (If it's not, the linker will append a jump-to-itself instruction; there is no fallthrough in TEXTs.) After the symbol, the arguments are flags (see below) and the frame size, a constant (but see below):

TEXT runtime·profileloop(SB),NOSPLIT,$8
	MOVQ	$runtime·profileloop1(SB), CX
	MOVQ	CX, 0(SP)
	CALL	runtime·externalthreadhandler(SB)
	RET
Field offsets are of the form type_field. Struct sizes are of the form type__size. For example, consider the following Go definition:

type reader struct {
	buf [bufSize]byte
	r   int
}
Branches and direct jumps are always written as offsets to the PC, or as jumps to labels:

label:
	MOVW $0, R1
	JMP label
Global data symbols are defined by a sequence of initializing DATA directives followed by a GLOBL directive. Each DATA directive initializes a section of the corresponding memory. The memory not explicitly initialized is zeroed. The general form of the DATA directive is

DATA	symbol+offset(SB)/width, value
For example,

DATA divtab<>+0x00(SB)/4, $0xf4f8fcff
DATA divtab<>+0x04(SB)/4, $0xe6eaedf0
...
DATA divtab<>+0x3c(SB)/4, $0x81828384
GLOBL divtab<>(SB), RODATA, $64

GLOBL runtime·tlsoffset(SB), NOPTR, $4
It is impractical to list all the instructions and other details for each machine. To see what instructions are defined for a given machine, say ARM, look in the source for the obj support library for that architecture, located in the directory src/cmd/internal/obj/arm. In that directory is a file a.out.go; it contains a long list of constants starting with A, like this:

const (
	AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota
	AEOR
	ASUB
	ARSB
	AADD
	...
For example, the sequence to load g and m using CX looks like this:

#include "go_tls.h"
#include "go_asm.h"
...
get_tls(CX)
MOVL	g(CX), AX     // Move g into AX.
MOVL	g_m(AX), BX   // Move g.m into BX.
The assemblers are designed to support the compiler so not all hardware instructions are defined for all architectures: if the compiler doesn't generate it, it might not be there. If you need to use a missing instruction, there are two ways to proceed. One is to update the assembler to support that instruction, which is straightforward but only worthwhile if it's likely the instruction will be used again. Instead, for simple one-off cases, it's possible to use the BYTE and WORD directives to lay down explicit data into the instruction stream within a TEXT. Here's how the 386 runtime defines the 64-bit atomic load function.

// uint64 atomicload64(uint64 volatile* addr);
// so actually
// void atomicload64(uint64 *res, uint64 volatile *addr);
TEXT runtime·atomicload64(SB), NOSPLIT, $0-12
	MOVL	ptr+0(FP), AX
	TESTL	$7, AX
	JZ	2(PC)
	MOVL	0, AX // crash with nil ptr deref
	LEAL	ret_lo+4(FP), BX
	// MOVQ (%EAX), %MM0
	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
	// MOVQ %MM0, 0(%EBX)
	BYTE $0x0f; BYTE $0x7f; BYTE $0x03
	// EMMS
	BYTE $0x0F; BYTE $0x77
	RET

Recommend

Managing Go installations Uninstalling Go Windows

Managing Go installations Installing multiple Go versions

Go 1.10 Release Notes Core library Minor changes to the library

Go 1.10 Release Notes Tools Doc

Go 1.10 Release Notes Tools Cgo

Go 1.1 Release Notes Changes to the standard library Exp and old subtrees moved to go.exp and go.text subrepositories

Go 1.1 Release Notes Changes to the standard library bufio.Scanner

Go 1.1 Release Notes Changes to the implementations and tools Build constraints

Go 1.1 Release Notes Changes to the implementations and tools Changes to the go test command

Go 1.1 Release Notes Changes to the implementations and tools Changes to the go command

Go 1.1 Release Notes Changes to the implementations and tools Unicode

Go 1.1 Release Notes Changes to the implementations and tools Size of int on 64-bit platforms

Go 1.1 Release Notes Changes to the language Method values

Go 1.1 Release Notes Changes to the language Integer division by zero

Go 1.8 Release Notes Changes to the language

Go 1.2 Release Notes Changes to the standard library The text/template and html/template packages

Go 1.2 Release Notes Changes to the standard library The fmt package

Go 1.2 Release Notes Changes to the implementations and tools The go doc command is deleted

Go 1.2 Release Notes Changes to the implementations and tools Test coverage

Go 1.2 Release Notes Changes to the implementations and tools Godoc and vet moved to the go.tools subrepository

Go 1.2 Release Notes Changes to the language Three-index slices

Go 1.2 Release Notes Changes to the language Use of nil

Go 1.5 Release Notes Core library Flag

Go 1.5 Release Notes Tools Trace command

Go 1.5 Release Notes Tools Linker

Go 1.5 Release Notes Tools Assembler

Go 1.5 Release Notes Tools Renaming

Go 1.5 Release Notes Changes to the language Map literals

Go 1.17 Release Notes Tools Vet New warnings for Is, As and Unwrap methods

Go 1.17 Release Notes Tools Vet New warning for calling signal.Notify on unbuffered channels

Go 1.17 Release Notes Tools Go command Pruned module graphs in go 1.17 modules

Debugging Go Code with GDB Tutorial Pretty Printing

Debugging Go Code with GDB Tutorial Inspecting the stack

Debugging Go Code with GDB Tutorial Setting breakpoints

Debugging Go Code with GDB Tutorial Inspecting the source

Debugging Go Code with GDB Tutorial Getting Started

Debugging Go Code with GDB Introduction Go Extensions

Debugging Go Code with GDB Introduction Common Operations

Bootstrap Components Creating your own

Bootstrap Components Responsive

Bootstrap Components Modifiers

Bootstrap Optimize Lean JavaScript Default Exports

Bootstrap Optimize Lean JavaScript

Bootstrap Optimize Lean Sass imports

Bootstrap CSS variables Examples

Bootstrap CSS variables Root variables

Bootstrap Sass Mixins Color schemes

Bootstrap Sass Functions Add and Subtract functions

Bootstrap Sass Functions Color contrast

Bootstrap Sass Functions Colors

Bootstrap Sass Maps and loops Remove from map