 |
|
14
whitehack Mar 4, 2019
我觉得你应该从汇编的角度来分析。
teststr.go ``` package main
func test(str *string) int {
return len(*str) } func test2(str string) int {
return len(str) }
func main() { s :="a"
test2(s) test(&s)
}
```
汇编
``` "".test STEXT nosplit size=53 args=0x10 locals=0x10 0x0000 00000 (teststr.go:3) TEXT "".test(SB), NOSPLIT, $16-16 0x0000 00000 (teststr.go:3) SUBQ $16, SP 0x0004 00004 (teststr.go:3) MOVQ BP, 8(SP) 0x0009 00009 (teststr.go:3) LEAQ 8(SP), BP 0x000e 00014 (teststr.go:3) FUNCDATA $0, gclocals·1a65e721a2ccc325b382662e7ffee780(SB) 0x000e 00014 (teststr.go:3) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB) 0x000e 00014 (teststr.go:3) FUNCDATA $3, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB) 0x000e 00014 (teststr.go:3) PCDATA $2, $0 0x000e 00014 (teststr.go:3) PCDATA $0, $0 0x000e 00014 (teststr.go:3) MOVQ $0, "".~r1+32(SP) 0x0017 00023 (teststr.go:5) PCDATA $2, $1 0x0017 00023 (teststr.go:5) PCDATA $0, $1 0x0017 00023 (teststr.go:5) MOVQ "".str+24(SP), AX 0x001c 00028 (teststr.go:5) TESTB AL, (AX) 0x001e 00030 (teststr.go:5) PCDATA $2, $0 0x001e 00030 (teststr.go:5) MOVQ 8(AX), AX 0x0022 00034 (teststr.go:5) MOVQ AX, ""..autotmp_2(SP) 0x0026 00038 (teststr.go:5) MOVQ AX, "".~r1+32(SP) 0x002b 00043 (teststr.go:5) MOVQ 8(SP), BP 0x0030 00048 (teststr.go:5) ADDQ $16, SP 0x0034 00052 (teststr.go:5) RET
```
``` "".test2 STEXT nosplit size=47 args=0x18 locals=0x10 0x0000 00000 (teststr.go:7) TEXT "".test2(SB), NOSPLIT, $16-24 0x0000 00000 (teststr.go:7) SUBQ $16, SP 0x0004 00004 (teststr.go:7) MOVQ BP, 8(SP) 0x0009 00009 (teststr.go:7) LEAQ 8(SP), BP 0x000e 00014 (teststr.go:7) FUNCDATA $0, gclocals·1a65e721a2ccc325b382662e7ffee780(SB) 0x000e 00014 (teststr.go:7) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB) 0x000e 00014 (teststr.go:7) FUNCDATA $3, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB) 0x000e 00014 (teststr.go:7) PCDATA $2, $0 0x000e 00014 (teststr.go:7) PCDATA $0, $0 0x000e 00014 (teststr.go:7) MOVQ $0, "".~r1+40(SP) 0x0017 00023 (teststr.go:9) PCDATA $0, $1 0x0017 00023 (teststr.go:9) MOVQ "".str+32(SP), AX 0x001c 00028 (teststr.go:9) MOVQ AX, ""..autotmp_2(SP) 0x0020 00032 (teststr.go:9) MOVQ AX, "".~r1+40(SP) 0x0025 00037 (teststr.go:9) MOVQ 8(SP), BP 0x002a 00042 (teststr.go:9) ADDQ $16, SP 0x002e 00046 (teststr.go:9) RET
```
test 指针参数代码都比 不传指针的多。
指针的计算要多一个操作
下面是调用
``` // 定义字符串 0x0024 00036 (teststr.go:13) LEAQ go.string."a"(SB), AX 0x002b 00043 (teststr.go:13) MOVQ AX, "".s+24(SP) 0x0030 00048 (teststr.go:13) MOVQ $1, "".s+32(SP)
// 传值 0x0039 00057 (teststr.go:15) PCDATA $2, $0 // StringSlice 结构 0x0039 00057 (teststr.go:15) MOVQ AX, (SP) 0x003d 00061 (teststr.go:15) MOVQ $1, 8(SP) 0x0046 00070 (teststr.go:15) CALL "".test2(SB)
// 传指针 0x004b 00075 (teststr.go:16) LEAQ "".s+24(SP), AX 0x0050 00080 (teststr.go:16) PCDATA $2, $0 // Stringslice 指针 0x0050 00080 (teststr.go:16) MOVQ AX, (SP) 0x0054 00084 (teststr.go:16) CALL "".test(SB) ```
|