1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 12:32:21 +00:00

ch3-04-fix typo

This commit is contained in:
sfw 2018-06-28 20:58:03 +08:00
parent 781962557e
commit f15966d78e

View File

@ -225,7 +225,7 @@ TEXT ·bar(SB), $0-16
RET
```
首先分析foo函数的栈帧的大小foo函数内部有a、b两个局部变量占用16个字节然后要需给要调用的bar函数准备的参数和返回值准备16字节的空间因此总共有32字节的栈帧大小。在调用bar函数前我们已经计算好了栈帧的大小Go汇编语言环境已将真实的SP寄存器调整到合适的大小在调用函数时并不需要再手动调整SP寄存器。在调用函数bar前真SP对应向下增长的栈顶部因此顶部的16个字节和bar函数的参数和返回值是对应的相同的内存空间。我们将保存了b的BX寄存器内容放入`+0(SP)`位置也就是准备bar函数的第一个参数。然后通过CALL指令进行函数调用。在bar函数内首先从第一个参数对应的`+0(FP)`位置去取参数值存入AX寄存器然后再将AX内容放入返回值对应的`ret+8(FP)`内存位置最后调用RET返回。在foo函数中调用bar函数返回后从bar函数返回值对应的`+8(SP)`位置取出结果放到CX寄存从而完成函数调用。
首先分析foo函数的栈帧的大小foo函数内部有a、b两个局部变量占用16个字节然后要需给要调用的bar函数的参数和返回值准备16字节的空间因此总共有32字节的栈帧大小。在调用bar函数前我们已经计算好了栈帧的大小Go汇编语言环境已将真实的SP寄存器调整到合适的大小在调用函数时并不需要再手动调整SP寄存器。在调用函数bar前真SP对应向下增长的栈顶部因此顶部的16个字节和bar函数的参数和返回值是对应的相同的内存空间。我们将保存了b的BX寄存器内容放入`+0(SP)`位置也就是准备bar函数的第一个参数。然后通过CALL指令进行函数调用。在bar函数内首先从第一个参数对应的`+0(FP)`位置去取参数值存入AX寄存器然后再将AX内容放入返回值对应的`ret+8(FP)`内存位置最后调用RET返回。在foo函数中调用bar函数返回后从bar函数返回值对应的`+8(SP)`位置取出结果放到CX寄存从而完成函数调用。
调用其它函数前调用方要选择保存相关寄存器到栈中并在调用函数返回后选择要恢复的寄存器进行保存。Go语言中函数调用是一个复杂的问题因为Go函数不仅仅要了解函数调用函数的布局还会涉及到栈的跳转栈上局部变量的生命周期管理。本节只是简单了解函数调用参数的布局规则在后续的章节中会更详细的讨论函数的细节。