1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 20:52:22 +00:00

ch3-02: 完善

This commit is contained in:
chai2010 2018-06-23 08:18:29 +08:00
parent 2794974b19
commit 047c5a6185
3 changed files with 77 additions and 0 deletions

View File

@ -140,3 +140,17 @@ Go汇编为了简化汇编代码的编写引入了PC、FP、SP、SB四个伪
当需要区分伪寄存器和真寄存器的时候只需要记住一点:伪寄存器一般需要一个标识符和偏移量为前缀,如果没有标识符前缀则是真寄存器。比如`(SP)``+8(SP)`没有标识符前缀为真SP寄存器`a(SP)``b+8(SP)`有标识符为前缀表示伪寄存器。 当需要区分伪寄存器和真寄存器的时候只需要记住一点:伪寄存器一般需要一个标识符和偏移量为前缀,如果没有标识符前缀则是真寄存器。比如`(SP)``+8(SP)`没有标识符前缀为真SP寄存器`a(SP)``b+8(SP)`有标识符为前缀表示伪寄存器。
## Go函数调用规范
和C语言函数不同Go语言函数的参数和返回值完全通过栈传递。下面是Go函数调用时栈的布局图
![](../images/ch3-func-stack-frame-layout-01.ditaa.png)
在汇编定义函数时我们需要关注framesize和argsize分别对应函数帧大学和函数参数和返回值的大小。
因为函数的参数和返回大学可以通过Go函数的签名解析得到因此argsize一般是可以省略的。需要注意的是输入参数和返回值依此从低地址向高地址顺序排列。同时每个参数的类型需要满足地址对齐要求。
帧大小相对复杂一点:其中包含函数的局部变量和调用其它函数时的参数和返回值空间。局部变量也是从低地址向高地址顺序排列的,因此它们栈增长方向是相反的。
在最下面灰色的部分是调用函数后的返回地址。当执行CALL指令时会自动将SP向下移动并将返回地址和SP寄存器存入栈中。然后被调用的函数执行RET返回指令时先从栈恢复BP和SP寄存器并根取出的返回地址跳转到对应的指令执行。

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,63 @@
Stack frame layout X86/AMD64
---=- +-=-------------------------+
^ | |
| | ret1 to caller |
| | |
| +-=-------------------------+<--ret1+24(FP)
| | |
: | ret0 to caller |
| |
argsize +-=-------------------------+<--ret0+16(FP)
| |
: | arg1 from caller |
| | |
| +-=-------------------------+<--arg1+8(FP)
| | |
| | arg0 from caller |
v | |
---=- +-=-------------------------+<--arg0+0(FP)
| |
| parent return address |
| |
+---------------------------+
| c9D5 |
| caller's BP |
| (if framepointer_enabled) |
---=- +---------------------------+<--BP(pseudo SP)
^ | cD0A |
| | local varable2 |
| | |
| +---------------------------+<--var2-8(SP)
| | cD0A |
| | local varable1 |
| | |
| +---------------------------+<--var1-16(SP)
| | cD0A |
| | local varable0 |
| | |
| +---------------------------+<--var0-24(SP)
: | cYEL |
| | ret1 from callee |
| |
framesize+---------------------------+<--24(SP)
| cYEL |
| | ret0 from callee |
: | |
| +---------------------------+<--16(SP)
| | cF51 |
| | arg1 to callee |
| | |
| +---------------------------+<--8(SP)
| | cF51 |
| | arg0 to callee |
v | |
---=- +---------------------------+<--0(SP)
| cAAA |
| return address |
| |
+---------------------------+
| cAAA |
| caller's BP |
| (if framepointer_enabled) |
+---------------------------+