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.

Reply via email to