On Mon, May 10, 2021 at 5:56 AM 计算鸡 <[email protected]> wrote:
>
> ```go
> package main
>
> type T struct {
>         a *int
> }
>
> func test(t *T, b *int) {
>         t.a = b
> }
> ```
> compile this code use cmd `go build -gcflags '-l' main.go`
> only disable inline stage .
>
> here is the plan9 assembly of function test
>
> ```assembly
> TEXT main.test(SB) src/write-barrier/main.go
>   main.go:7   0x45ec60   64488b0c25f8ffffff   MOVQ FS:0xfffffff8, CX
>   main.go:7   0x45ec69   483b6110             CMPQ 0x10(CX), SP
>   main.go:7   0x45ec6d   7639                 JBE 0x45eca8
>   main.go:7   0x45ec6f   4883ec08             SUBQ $0x8, SP
>   main.go:7   0x45ec73   48892c24             MOVQ BP, 0(SP)
>   main.go:7   0x45ec77   488d2c24             LEAQ 0(SP), BP
>   main.go:8   0x45ec7b   488b7c2410           MOVQ 0x10(SP), DI
>   main.go:8   0x45ec80   8407                 TESTB AL, 0(DI)
>   main.go:8   0x45ec82   833d379c090000       CMPL $0x0, 
> runtime.writeBarrier(SB)
>   main.go:8   0x45ec89   7511                 JNE 0x45ec9c
>   main.go:8   0x45ec8b   488b442418           MOVQ 0x18(SP), AX
>   main.go:8   0x45ec90   488907               MOVQ AX, 0(DI)
>   main.go:9   0x45ec93   488b2c24             MOVQ 0(SP), BP
>   main.go:9   0x45ec97   4883c408             ADDQ $0x8, SP
>   main.go:9   0x45ec9b   c3                   RET
>   main.go:8   0x45ec9c   488b442418           MOVQ 0x18(SP), AX
>   main.go:8   0x45eca1   e8facaffff           CALL runtime.gcWriteBarrier(SB)
>   main.go:8   0x45eca6   ebeb                 JMP 0x45ec93
>   main.go:7   0x45eca8   e8b3afffff           CALL 
> runtime.morestack_noctxt(SB)
>   main.go:7   0x45ecad   ebb1                 JMP main.test(SB)
> ```
>
> i was confused with the instruction ` main.go:8   0x45ec80   8407             
>     TESTB AL, 0(DI)`
> i think it must used for checking nil pointer . but both test and cmp will 
> modify ZF in eflags. ( there is a cmp instruction follow the test )
>
> i think it should insert instruction `JE 0x45ec9c ` between  test and cml 
> instruction .

The "TESTB AL, 0(DI)" instruction will force the processor to attempt
to retrieve the value at address 0(DI).  If DI does not hold a valid
address, the processor will fault.  The runtime will pick up this
fault and turn it into a run-time panic saying "invalid memory address
or nil pointer dereference".

That is, the instruction is not being executed to set the flags.  It
is being executed for its effect of testing whether the memory is
valid.

Ian

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcWXDCrMswVfhHSAXUxd8u3ZCO_RrFBNS_Zic%3Da8ABf30g%40mail.gmail.com.

Reply via email to