chai2010 / advanced-go-programming-book

:books: 《Go语言高级编程》开源图书,涵盖CGO、Go汇编语言、RPC实现、Protobuf插件实现、Web框架实现、分布式系统等高阶主题(完稿)
https://chai2010.cn/advanced-go-programming-book/
BSD 2-Clause "Simplified" License
19.4k stars 3.21k forks source link

golang1.18版本的形参使用的寄存器传参? 和汇编章节使用栈的不太一样 #575

Open guonaihong opened 2 years ago

guonaihong commented 2 years ago

提示:哪一章节的问题,建议如何修改

go 编译器版本

go1.18

go命令选项

go tool compile -l -N -S add.go

在阅读汇编那节内容. 做了个实验, 发现函数里面的参数从寄存器里面拿就可以了. 当然我的汇编比较菜, 也有可能是看错了.

func AddNine(a int, b int, c int, d int, e int, f int, g int, h int, i int) int {
    z := a + b + c + d + f + g + h + i
    return z
}
"".AddNine STEXT nosplit size=126 args=0x48 locals=0x18 funcid=0x0 align=0x0
    0x0000 00000 (add.go:47)    TEXT    "".AddNine(SB), NOSPLIT|ABIInternal, $24-72
    0x0000 00000 (add.go:47)    SUBQ    $24, SP
    0x0004 00004 (add.go:47)    MOVQ    BP, 16(SP)
    0x0009 00009 (add.go:47)    LEAQ    16(SP), BP
    0x000e 00014 (add.go:47)    FUNCDATA    $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x000e 00014 (add.go:47)    FUNCDATA    $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
    0x000e 00014 (add.go:47)    FUNCDATA    $5, "".AddNine.arginfo1(SB)
    0x000e 00014 (add.go:47)    MOVQ    AX, "".a+32(SP)
    0x0013 00019 (add.go:47)    MOVQ    BX, "".b+40(SP)
    0x0018 00024 (add.go:47)    MOVQ    CX, "".c+48(SP)
    0x001d 00029 (add.go:47)    MOVQ    DI, "".d+56(SP)
    0x0022 00034 (add.go:47)    MOVQ    SI, "".e+64(SP)
    0x0027 00039 (add.go:47)    MOVQ    R8, "".f+72(SP)
    0x002c 00044 (add.go:47)    MOVQ    R9, "".g+80(SP)
    0x0031 00049 (add.go:47)    MOVQ    R10, "".h+88(SP)
    0x0036 00054 (add.go:47)    MOVQ    R11, "".i+96(SP)
    0x003b 00059 (add.go:47)    MOVQ    $0, "".~r0(SP)
    0x0043 00067 (add.go:48)    MOVQ    "".a+32(SP), AX
    0x0048 00072 (add.go:48)    ADDQ    "".b+40(SP), AX
    0x004d 00077 (add.go:48)    ADDQ    "".c+48(SP), AX
    0x0052 00082 (add.go:48)    ADDQ    "".d+56(SP), AX
    0x0057 00087 (add.go:48)    ADDQ    "".f+72(SP), AX
    0x005c 00092 (add.go:48)    ADDQ    "".g+80(SP), AX
    0x0061 00097 (add.go:48)    ADDQ    "".h+88(SP), AX
    0x0066 00102 (add.go:48)    ADDQ    "".i+96(SP), AX
    0x006b 00107 (add.go:48)    MOVQ    AX, "".z+8(SP)
    0x0070 00112 (add.go:49)    MOVQ    AX, "".~r0(SP)
    0x0074 00116 (add.go:49)    MOVQ    16(SP), BP
    0x0079 00121 (add.go:49)    ADDQ    $24, SP
    0x007d 00125 (add.go:49)    RET
    0x0000 48 83 ec 18 48 89 6c 24 10 48 8d 6c 24 10 48 89  H...H.l$.H.l$.H.
    0x0010 44 24 20 48 89 5c 24 28 48 89 4c 24 30 48 89 7c  D$ H.\$(H.L$0H.|
    0x0020 24 38 48 89 74 24 40 4c 89 44 24 48 4c 89 4c 24  $8H.t$@L.D$HL.L$
    0x0030 50 4c 89 54 24 58 4c 89 5c 24 60 48 c7 04 24 00  PL.T$XL.\$`H..$.
    0x0040 00 00 00 48 8b 44 24 20 48 03 44 24 28 48 03 44  ...H.D$ H.D$(H.D
    0x0050 24 30 48 03 44 24 38 48 03 44 24 48 48 03 44 24  $0H.D$8H.D$HH.D$
    0x0060 50 48 03 44 24 58 48 03 44 24 60 48 89 44 24 08  PH.D$XH.D$`H.D$.
    0x0070 48 89 04 24 48 8b 6c 24 10 48 83 c4 18 c3        H..$H.l$.H....
"".AddTen STEXT nosplit size=131 args=0x50 locals=0x18 funcid=0x0 align=0x0

观察的现象是, <=9个形参使用寄存器(关闭golang编译器优化) > 9的部分使用栈. 想找大佬确认下, 是否我这边看错了. 分别是ax, bx, cx, di, si, r8, r9, r10, r11

chai2010 commented 2 years ago

书中是Go1.10的汇编规则。汇编语言并不是Go1承诺不会变化的部分,Go1.18确实发生了一些变化,变得更有效率、也更加繁琐,未来也有可能会发生变化。你自行对比下变化的部分,也欢迎PR

ZzzJing commented 2 years ago

这是来自QQ邮箱的假期自动回复邮件。你好,我最近正在休假中,无法亲自回复你的邮件。我将在假期结束后,尽快给你回复。