在golang1.17之前,函数的参数和返回值都是放在函数栈里面的,比如函数A调用函数B,那么B的实参和返回值都是存放在函数A的栈里面,所以可以轻松的返回多个值。
其他的编程语言大都使用某个寄存器来存储函数的返回值。
但是从golang1.17开始,还是换成了使用寄存器来存储函数的参数和返回值,如果有多个返回值则依次使用AX, BX, CX, DX, SI, DI
等寄存器来存储,这样可以稍微提升一些性能。
https://golang.google.cn/doc/go1.17
go
package main
func main() {
x, y, z := function(1, 10, 100)
println(x, y, z)
}
func function(a, b, c int64) (int64, int64, int64) {
a++
b++
c++
return a, b, c
}
go tool compile -S -N -l cat.go
assembly
main.main STEXT size=165 args=0x0 locals=0x68 funcid=0x0 align=0x0
TEXT main.main(SB), ABIInternal, $104-0
CMPQ SP, 16(R14)
PCDATA $0, $-2
JLS 154
PCDATA $0, $-1
SUBQ $104, SP
MOVQ BP, 96(SP)
LEAQ 96(SP), BP
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
MOVL $1, AX
MOVL $10, BX
MOVL $100, CX
PCDATA $1, $0
CALL main.function(SB)
MOVQ AX, main..autotmp_6+64(SP)
MOVQ BX, main..autotmp_7+56(SP)
MOVQ CX, main..autotmp_8+48(SP)
MOVQ AX, main..autotmp_3+88(SP)
MOVQ BX, main..autotmp_4+80(SP)
MOVQ CX, main..autotmp_5+72(SP)
MOVQ AX, main.x+40(SP)
MOVQ BX, main.y+32(SP)
MOVQ CX, main.z+24(SP)
CALL runtime.printlock(SB)
MOVQ main.x+40(SP), AX
CALL runtime.printint(SB)
CALL runtime.printsp(SB)
MOVQ main.y+32(SP), AX
CALL runtime.printint(SB)
CALL runtime.printsp(SB)
MOVQ main.z+24(SP), AX
CALL runtime.printint(SB)
CALL runtime.printnl(SB)
CALL runtime.printunlock(SB)
MOVQ 96(SP), BP
ADDQ $104, SP
RET
NOP
PCDATA $1, $-1
PCDATA $0, $-2
CALL runtime.morestack_noctxt(SB)
PCDATA $0, $-1
NOP
JMP 0
main.function STEXT nosplit size=118 args=0x18 locals=0x20 funcid=0x0 align=0x0
TEXT main.function(SB), NOSPLIT|ABIInternal, $32-24
SUBQ $32, SP
MOVQ BP, 24(SP)
LEAQ 24(SP), BP
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $5, main.function.arginfo1(SB)
MOVQ AX, main.a+40(SP)
MOVQ BX, main.b+48(SP)
MOVQ CX, main.c+56(SP)
MOVQ $0, main.~r0+16(SP)
MOVQ $0, main.~r1+8(SP)
MOVQ $0, main.~r2(SP)
MOVQ main.a+40(SP), AX
INCQ AX
MOVQ AX, main.a+40(SP)
MOVQ main.b+48(SP), BX
INCQ BX
MOVQ BX, main.b+48(SP)
MOVQ main.c+56(SP), CX
INCQ CX
MOVQ CX, main.c+56(SP)
MOVQ AX, main.~r0+16(SP)
MOVQ BX, main.~r1+8(SP)
MOVQ CX, main.~r2(SP)
MOVQ 24(SP), BP
ADDQ $32, SP
RET