C运行时函数调用前是否清空参数Home Slots?小参数高位值疑问
问题
当从C/C++调用包含小于64位参数的函数时,运行时会将这些参数在Home Location的栈内存清零吗?还是每个参数的高位会保留垃圾值?
每个参数的栈空间为8字节(64位),但它们可能代表8位、16位或32位的值。假设参数不通过寄存器传递,本问题适用于所有参数,而非仅前4个。
void foobar(bool a, int32_t b, float c, int64_t d) { int x = 0, y = 0, z = 0; }
栈帧示意
[... 前一个栈帧 ...] // <高地址> [d] [c] [b] // 参数'b'的高32位是包含垃圾值还是被清零? [a] [返回地址] [保存的rbp] [x] [y] [z]
若以64位宽度读取参数b,如果高位有垃圾值,rax会得到错误结果:
mov rax, qword ptr[rbp+24]
结论
参数栈空间的高位(超出参数实际宽度的部分)会保留垃圾值,不会被自动清零。
具体说明:
- 调用方在压栈参数时,仅会写入参数的有效位:比如
bool类型仅写入最低1位,int32_t仅写入最低32位,高位字节/位不会主动清零,会保留栈空间之前的残留垃圾值。 - 从C/C++标准角度,直接以64位宽度读取原本为32位的栈参数属于违反类型规则的操作,不在标准的行为保证范围内;但从实际汇编层面,编译器生成的调用代码不会主动清理这些高位。
- 正确的读取方式是匹配参数实际类型的宽度:比如针对
int32_t b,应使用32位指令读取(mov eax, dword ptr[rbp+24]),此时高位会根据类型进行符号扩展(有符号类型)或零扩展(无符号类型),得到正确值;若强行以64位宽度读取,高位垃圾值会被一并读入,导致错误。
内容的提问来源于stack exchange,提问作者Dess
相关产品推荐
相关产品推荐

