1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 04:22:22 +00:00
This commit is contained in:
chai2010 2018-07-22 16:29:50 +08:00
commit 32d59e6e6f

View File

@ -11,7 +11,7 @@
![](../images/ch3-func-stack-frame-layout-01.ditaa.png)
首先是调用函数前转变的输入参数和返回值空间。然后CALL指令将首先触发返回地址入栈操作。在进入到被调用函数内之后汇编器自动插入了BP寄存器相关的指令因此BP寄存器和返回地址是紧着的。再下面就是当前函数的局部变量的空间包含再次调用其它函数需要准备的调用参数空间。被调用的函数执行RET返回指令时先从栈恢复BP和SP寄存器接着取出的返回地址跳转到对应的指令执行。
首先是调用函数前转变的输入参数和返回值空间。然后CALL指令将首先触发返回地址入栈操作。在进入到被调用函数内之后汇编器自动插入了BP寄存器相关的指令因此BP寄存器和返回地址是紧着的。再下面就是当前函数的局部变量的空间包含再次调用其它函数需要准备的调用参数空间。被调用的函数执行RET返回指令时先从栈恢复BP和SP寄存器接着取出的返回地址跳转到对应的指令执行。
## 高级汇编语言
@ -107,9 +107,9 @@ type stack struct {
}
```
在g结构体中的stackguard0成员是出现爆栈前的警戒线。stackguard0的偏移量是16个字节因此上述代码中的`CMPQ SP, 16(AX)`表示将当前的真实SP和爆栈警戒线比较如果超出警戒线则表示需要进行栈扩容也就是跳转到L_MORE_STK。在L_MORE_STK标号处线调用runtime·morestack_noctxt进行栈扩容然后又跳回到函数到开始位置,此时此刻函数的栈已经调整了。然后再进行一次栈大小的检测,如果依然不足则继续扩容,直到栈足够大为止。
在g结构体中的stackguard0成员是出现爆栈前的警戒线。stackguard0的偏移量是16个字节因此上述代码中的`CMPQ SP, 16(AX)`表示将当前的真实SP和爆栈警戒线比较如果超出警戒线则表示需要进行栈扩容也就是跳转到L_MORE_STK。在L_MORE_STK标号处先调用runtime·morestack_noctxt进行栈扩容然后又跳回到函数的开始位置,此时此刻函数的栈已经调整了。然后再进行一次栈大小的检测,如果依然不足则继续扩容,直到栈足够大为止。
以上是栈的扩容,但是栈到收缩是在何时处理到我们知道Go运行时会定期进行垃圾回收操作这其中包含栈的回收工作。如果栈使用到比例小于一定到阈值则分配一个较小到栈空间然后将栈上面到数据移动到新的栈中栈移动的过程和栈扩容的过程类似。
以上是栈的扩容,但是栈的收缩是在何时处理的我们知道Go运行时会定期进行垃圾回收操作这其中包含栈的回收工作。如果栈使用到比例小于一定到阈值则分配一个较小到栈空间然后将栈上面到数据移动到新的栈中栈移动的过程和栈扩容的过程类似。
## PCDATA和FUNCDATA