advanced-go-programming-book
advanced-go-programming-book copied to clipboard
3.4.4函数中的局部变量一节中一段话没明白
3.4.4函数中的局部变量一节中 代码如下: func Foo(){ var c []byte var b int16 var a bool } 书中说 局部变量中先定义的变量c与伪寄存器SP对应的地址最远? 该怎么理解 我理解的伪SP寄存器 是指向第一个局部变量的,栈是从高到低的,c应该是先入栈,是离伪SP寄存器最近的 从汇编代码中也可以看出 MOVQ c_cap-8(SP)
请大佬 帮忙解惑~~
这个只是为了便于理解做的一个假设:假设局部变量的顺序和函数参数的顺序是一样的内存顺序规则。
在函数参数中,第一个参数的地址更小,然后第二个参数地址变大,可以参考FP伪寄存器的偏移量。 而伪SP的地址是反向的,如果第一个局部变量的地址(参考函数参数的顺序)最小,那么自然和SP就最远了(伪SP是在高地址位)。
PS: 这些都是假设,只有函数参数属于ABI规范,因此没有ABI规范的局部变量是乱序或优化为常量都有可能。
我感觉可能是当时想错了哈哈
package main
func main() {
var c []byte
var b int16
var a bool
println(&c, &b, &a)
}
三者的地址确实是由大变小,说明在栈内是从底到顶分布的。
想错的原因。。猜测可能是当时用 fmt.Sprintf 打印了 a,b,c 的地址,造成了逃逸,进而导致了判断失误。。。
@xujunhai ,你理解的没问题,伪 SP 是指向第一个局部变量的
@cch123 说到的逃逸正说明了问题所在:局部变量的内存布局是没有abi的,而且可能是测不准的(比如print造成了逃逸)。 这个内容主要的目的是为了说明一种简单可能的布局。另外,可以尝试转为uintptr试试消除逃逸的影响,看看是否存在差异。
这个只是为了便于理解做的一个假设:假设局部变量的顺序和函数参数的顺序是一样的内存顺序规则。
在函数参数中,第一个参数的地址更小,然后第二个参数地址变大,可以参考FP伪寄存器的偏移量。 而伪SP的地址是反向的,如果第一个局部变量的地址(参考函数参数的顺序)最小,那么自然和SP就最远了(伪SP是在高地址位)。
PS: 这些都是假设,只有函数参数属于ABI规范,因此没有ABI规范的局部变量是乱序或优化为常量都有可能。
是和c语言编译器那样么~ 没有栈溢出检查的情况是和保持参数定义顺序入栈的,有栈溢出检查会char int等优化后入栈么?
我感觉可能是当时想错了哈哈
package main func main() { var c []byte var b int16 var a bool println(&c, &b, &a) }
三者的地址确实是由大变小,说明在栈内是从底到顶分布的。
想错的原因。。猜测可能是当时用 fmt.Sprintf 打印了 a,b,c 的地址,造成了逃逸,进而导致了判断失误。。。
@xujunhai ,你理解的没问题,伪 SP 是指向第一个局部变量的
哈哈~ 我试试能不能复现