目录

Go 汇编

Go 编译器产生的汇编代码是一种中间抽象态,它不是对机器码的映射,而是和平台无关的一个中间态汇编描述,所以汇编代码中有些寄存器是真实的,有些是抽象的,几个抽象的寄存器如下:

SB (Static base pointer):静态基址寄存器,它和全局符号一起表示全局变量的地址。
FP (Frame pointer):栈帧寄存器,该寄存器指向当前函数调用栈帧的栈底位置。
PC (Program counter):程序计数器,存放下一条指令的执行地址,很少直接操作该寄存器,一般是 CALL、RET 等指令隐式的操作。
SP (Stack pointer):栈顶寄存器,一般在函数调用前由主调函数设置 SP 的值对栈空间进行分配或回收。

1) Go 汇编器采用 AT&T 风格的汇编,早期的实现来自 plan9 汇编器,源操作数在前,目的操作数在后。

2) Go 内嵌汇编和反汇编产生的代码并不是一一对应的,汇编编译器对内嵌汇编程序自动做了调整,主要差别就是增加了保护现场,以及函数调用前的保持 PC 、SP 偏移地址重定位等逻辑,反汇编代码更能反映程序的真实执行逻辑。

3) Go 的汇编代码并不是和具体硬件体系结构的机器码一一对应的,而是一种半抽象的描述,寄存器可能是抽象的,也可能是具体的。

package main
func swap (a, b int) (x int, y int) {
    x = b
    y = a
    return
}
func main() {
    swap(10, 20)
}
//- S 产生汇编的代码
//- N 禁用优化
//- 1 禁用内联
$ GOOS=linux GOARCH=amd64 go tool compile -1 -N -S swap.go >swap.s 2>&1