package main
func main() {
var x int32 = 1
nop(x)
}
//go:noinline
func nop(x int32) {}
Go version: go1.16.15 windows/amd64I wrote above code and compiled it into assembly with `go1.16.15 tool compile -S -N -l main.go` for truly understanding Go functions call.
The following is the assembly code of nop function:
"".nop STEXT nosplit size=1 args=0x8 locals=0x0 funcid=0x0
0x0000 00000 (main.go:9) TEXT "".nop(SB), NOSPLIT|ABIInternal, $0-8
0x0000 00000 (main.go:9) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (main.go:9) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0000 00000 (main.go:9) RETObviously, the nop function returns directly without doing anything. It only has a `int32` type parameter, but we can see the `argsize` is 8 bytes in the assembly:
TEXT "".nop(SB), NOSPLIT|ABIInternal, $0-
8Question1: Why the `argsize` is 8 bytes not 4 bytes?The following is the assembly code of main function:
"".main STEXT size=73 args=0x0 locals=0x18 funcid=0x0
0x0000 00000 (main.go:3) TEXT "".main(SB), ABIInternal, $24-0
0x0000 00000 (main.go:3) MOVQ TLS, CX
0x0009 00009 (main.go:3) PCDATA $0, $-2
0x0009 00009 (main.go:3) MOVQ (CX)(TLS*2), CX
0x0010 00016 (main.go:3) PCDATA $0, $-1
0x0010 00016 (main.go:3) CMPQ SP, 16(CX)
0x0014 00020 (main.go:3) PCDATA $0, $-2
0x0014 00020 (main.go:3) JLS 66
0x0016 00022 (main.go:3) PCDATA $0, $-1
0x0016 00022 (main.go:3) SUBQ $24, SP
0x001a 00026 (main.go:3) MOVQ BP, 16(SP)
0x001f 00031 (main.go:3) LEAQ 16(SP), BP
0x0024 00036 (main.go:3) FUNCDATA $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0024 00036 (main.go:3) FUNCDATA $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
0x0024 00036 (main.go:4) MOVL $1, "".x+12(SP)
0x002c 00044 (main.go:5) MOVL $1, (SP)
0x0033 00051 (main.go:5) PCDATA $1, $0
0x0033 00051 (main.go:5) CALL "".nop(SB)
0x0038 00056 (main.go:6) MOVQ 16(SP), BP
0x003d 00061 (main.go:6) ADDQ $24, SP
0x0041 00065 (main.go:6) RETI drawn a picture of stack according to the assembly code:
https://i.stack.imgur.com/AHN1b.pngQuestion2: I find there are confusing 8 bytes in the stack, why do these 8 bytes exist?
Question3:
Why MOVL $1, "".x+12(SP)but not
MOVL $1, "".x-12(SP)?
I think memory alignment causes the above phenomenon, but I'm not sure.