我正在将Go 1.14与linux / riscv64目标一起使用,并且正在编译一个hello世界,在汇编中可以看到它:
1b078: 04813183 ld gp,72(sp)
1b07c: 00018003 lb zero,0(gp)
1b080: 00313423 sd gp,8(sp)
如您所见,[GP + 0]的负载为零,根据规范,该负载应为“异常或其他”:即使丢弃了加载值,目标为x0的加载仍必须引发任何异常并引起任何其他副作用。
这到底是怎么回事?编译器会产生错误的输出吗?
最佳答案
我对riscv一无所知,但这是一种常见的模式。
内存访问仅检查[gp + 0]是否可访问且可读,而无需实际读取。
这对于以下情况很有用:
func f(a *[0x100001]byte) {
(*a)[0x100000] = 1;
}
编译器必须生成以下伪代码:check_not_null(a)
store(a + 0x100000, 1)
可以使用您发现的相同构造来实现null检查,而无需分支。
关于go - Go编译器产生奇怪的加载到x0中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63105488/