Q1: stack frames are rounded to a multiple of 8 bytes, to keep the stack pointer 8-byte aligned. Part of that is rounding argsize to 8 bytes. (It's not strictly necessary, and we could report 4, I think, if there are no return values.) Q2: I think 4 are from rounding argsize up to 8 bytes, and 4 are padding to keep the total frame a multiple of 8 bytes. Q3: offsets are from the updated stack pointer (the one generated by the SUBQ $24, SP instruction). So they will be positive.
On Monday, December 19, 2022 at 11:31:47 AM UTC-8 tarorual wrote: > package main > > func main() { > var x int32 = 1 > nop(x) > } > > //go:noinline > func nop(x int32) {} > > *Go version: go1.16.15 windows/amd64* > > I 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) RET > > Obviously, 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-*8* > > *Question1: 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) RET > > I drawn a picture of stack according to the assembly code: > https://i.stack.imgur.com/AHN1b.png > > *Question2: 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. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/1f039f1b-c5b9-49b1-a908-428b0651b712n%40googlegroups.com.