From dc4b9a251cfa6e8879119e36cf07fd35bb5b1ee6 Mon Sep 17 00:00:00 2001 From: chai2010 Date: Fri, 7 Dec 2018 09:45:44 +0800 Subject: [PATCH] =?UTF-8?q?ch3.5:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ch3-asm/ch3-05-control-flow.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ch3-asm/ch3-05-control-flow.md b/ch3-asm/ch3-05-control-flow.md index b4d1bd9..121d2c0 100644 --- a/ch3-asm/ch3-05-control-flow.md +++ b/ch3-asm/ch3-05-control-flow.md @@ -53,8 +53,8 @@ TEXT ·main(SB), $24-0 // 以a为参数调用函数 MOVQ AX, 0(SP) - CALL runtime·printint - CALL runtime·printnl + CALL runtime·printint(SB) + CALL runtime·printnl(SB) // 函数调用后, AX/BX 寄存器可能被污染, 需要重新加载 MOVQ a-8*2(SP), AX // AX = a @@ -63,13 +63,13 @@ TEXT ·main(SB), $24-0 // 计算b值, 并写入内存 MOVQ AX, BX // BX = AX // b = a ADDQ BX, BX // BX += BX // b += a - MULQ AX, BX // BX *= AX // b *= a + IMULQ AX, BX // BX *= AX // b *= a MOVQ BX, b-8*1(SP) // b = BX // 以b为参数调用函数 MOVQ BX, 0(SP) - CALL runtime·printint - CALL runtime·printnl + CALL runtime·printint(SB) + CALL runtime·printnl(SB) RET ``` @@ -82,6 +82,8 @@ TEXT ·main(SB), $24-0 在调用函数返回之后,全部的寄存器将被视为可能被调用的函数修改,因此我们需要从a、b对应的内存中重新恢复寄存器AX和BX。然后参考上面Go语言中b变量的计算方式更新BX对应的值,计算完成后同样将BX的值写入到b对应的内存。 +需要说明的是,上面的代码中`IMULQ AX, BX`使用了`IMULQ`指令来计算乘法。没有使用`MULQ`指令的原因是`MULQ`指令默认使用`AX`保存结果。读者可以自己尝试用`MULQ`指令改写上述代码。 + 最后以b变量作为参数再次调用runtime·printint函数进行输出工作。所有的寄存器同样可能被污染,不过main函数马上就返回了,因此不再需要恢复AX、BX等寄存器了。 重新分析汇编改写后的整个函数会发现里面很多的冗余代码。我们并不需要a、b两个临时变量分配两个内存空间,而且也不需要在每个寄存器变化之后都要写入内存。下面是经过优化的汇编函数: @@ -95,8 +97,8 @@ TEXT ·main(SB), $16-0 MOVQ AX, temp-8(SP) // temp = AX // 以a为参数调用函数 - CALL runtime·printint - CALL runtime·printnl + CALL runtime·printint(SB) + CALL runtime·printnl(SB) // 函数调用后, AX 可能被污染, 需要重新加载 MOVQ temp-8*1(SP), AX // AX = temp @@ -104,7 +106,7 @@ TEXT ·main(SB), $16-0 // 计算b值, 不需要写入内存 MOVQ AX, BX // BX = AX // b = a ADDQ BX, BX // BX += BX // b += a - MULQ AX, BX // BX *= AX // b *= a + IMULQ AX, BX // BX *= AX // b *= a // ... ```