声明
golang使用的是plan9汇编,不少调度的底层代码都是通过plan9实现,因此了解plan9汇编对Go源码剖析有非常重要的意义,以下的内容均针对golang中使用的plan9汇编。
汇编知识比较杂,如果有需要可以专门去学,本文只是为了看懂golang使用的汇编代码,因此只是简单介绍。
以下内容均来自网上整理,非原创,如有雷同,见谅。
通用寄存器
rax, rbx, rcx, rdx, rdi, rsi, r8~r15 共15个通用寄存器。
在golang中这些寄存器对应了R1-R15,对应关系如下
硬件寄存器 | Golang中的表示 |
---|---|
rax | R1 |
rbx | R2 |
rcx | R3 |
rdx | R4 |
rdi | R5 |
rdi | R6 |
rsi | R7 |
r8-r14 | R8-14 |
rip(pc) | R15 |
在golang汇编中还出现了R29之类的寄存器 都可以理解为通用寄存器
LR(link register) == R14 特别的寄存器,主程序处理异常时会跳转到子程序,该寄存器保存主程序当前的PC值。或者函数调用时,记录主函数调用子函数后下一个要执行的PC值。
特殊的寄存器
FP(Frame pointer): arguments and locals --->用于访问函数传入的参数
PC(Program counter): jumps and branches --->执行指令的地址
SB(Static base pointer): global symbols --->表示对应symbol的地址
SP(Stack pointer): top of stack --->栈顶地址
常见汇编指令含义
MOVD fn+0(FP), R3 // R3=fn.0 其中FP表示地址fn表示结构体 FP表示该地址数据为fn结构体取该结构体偏移0后的8字节 即
MOVD g_m(g), R4 // R4=g.m g表示地址指向当前正在运行的g g_m表示取g这个结构体中的成员m的值
g结构体的定义
type g struct {
...
m *m
...
}
通过如上方式获取结构体成员的值,和为结构体成员赋值。
函数调用内存分布
该图来源于https://chai2010.cn/advanced-go-programming-book/ch3-asm/ch3-06-func-again.html。
有疑问加站长微信联系(非本文作者)