Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.4.4函数中的局部变量一节中一段话没明白 #516

Open
xujunhai opened this issue Jul 24, 2020 · 5 comments
Open

3.4.4函数中的局部变量一节中一段话没明白 #516

xujunhai opened this issue Jul 24, 2020 · 5 comments

Comments

@xujunhai
Copy link

3.4.4函数中的局部变量一节中
代码如下:
func Foo(){
var c []byte
var b int16
var a bool
}
书中说 局部变量中先定义的变量c与伪寄存器SP对应的地址最远? 该怎么理解
我理解的伪SP寄存器 是指向第一个局部变量的,栈是从高到低的,c应该是先入栈,是离伪SP寄存器最近的
从汇编代码中也可以看出 MOVQ c_cap-8(SP)

请大佬 帮忙解惑~~

WechatIMG8717

@chai2010
Copy link
Owner

chai2010 commented Jul 25, 2020

这个只是为了便于理解做的一个假设:假设局部变量的顺序和函数参数的顺序是一样的内存顺序规则。

在函数参数中,第一个参数的地址更小,然后第二个参数地址变大,可以参考FP伪寄存器的偏移量。
而伪SP的地址是反向的,如果第一个局部变量的地址(参考函数参数的顺序)最小,那么自然和SP就最远了(伪SP是在高地址位)。

PS: 这些都是假设,只有函数参数属于ABI规范,因此没有ABI规范的局部变量是乱序或优化为常量都有可能。

@cch123
Copy link
Collaborator

cch123 commented Jul 25, 2020

我感觉可能是当时想错了哈哈

package main

func main() {
	var c []byte
	var b int16
	var a bool
	println(&c, &b, &a)
}

三者的地址确实是由大变小,说明在栈内是从底到顶分布的。

想错的原因。。猜测可能是当时用 fmt.Sprintf 打印了 a,b,c 的地址,造成了逃逸,进而导致了判断失误。。。

@xujunhai ,你理解的没问题,伪 SP 是指向第一个局部变量的

@chai2010
Copy link
Owner

@cch123 说到的逃逸正说明了问题所在:局部变量的内存布局是没有abi的,而且可能是测不准的(比如print造成了逃逸)。
这个内容主要的目的是为了说明一种简单可能的布局。另外,可以尝试转为uintptr试试消除逃逸的影响,看看是否存在差异。

@xujunhai
Copy link
Author

这个只是为了便于理解做的一个假设:假设局部变量的顺序和函数参数的顺序是一样的内存顺序规则。

在函数参数中,第一个参数的地址更小,然后第二个参数地址变大,可以参考FP伪寄存器的偏移量。
而伪SP的地址是反向的,如果第一个局部变量的地址(参考函数参数的顺序)最小,那么自然和SP就最远了(伪SP是在高地址位)。

PS: 这些都是假设,只有函数参数属于ABI规范,因此没有ABI规范的局部变量是乱序或优化为常量都有可能。

是和c语言编译器那样么~ 没有栈溢出检查的情况是和保持参数定义顺序入栈的,有栈溢出检查会char int等优化后入栈么?

@xujunhai
Copy link
Author

我感觉可能是当时想错了哈哈

package main

func main() {
	var c []byte
	var b int16
	var a bool
	println(&c, &b, &a)
}

三者的地址确实是由大变小,说明在栈内是从底到顶分布的。

想错的原因。。猜测可能是当时用 fmt.Sprintf 打印了 a,b,c 的地址,造成了逃逸,进而导致了判断失误。。。

@xujunhai ,你理解的没问题,伪 SP 是指向第一个局部变量的

哈哈~ 我试试能不能复现

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants