当您从 C/C++ 调用函数时,该函数的某些参数小于 64 位,运行时是否会将这些参数起始位置的堆栈内存清零?或者每个参数的顶部是否包含垃圾?
每个参数的空间为 8 个字节(64 位),但它们可能代表 8、16 或 32 位值。
假设参数不是通过寄存器传递的,因为这个问题涉及任何参数,而不仅仅是前 4 个参数。
void foobar(bool a, i32 b, float c, i64 d)
{
int x = 0, y = 0, z = 0;
}
----------------------------------------
# Stack Frame #
[... Previous StackFrame ...] // <HIGH ADDRESS>
[d]
[c]
[b] // Do the top 32 most-significan-bits of param 'b' contain garbage, or zero?
[a]
[ReturnAddr]
[Saved rbp]
[x]
[y]
[z]
// read 'b' value -- if the top 32bits of 'b' contains garbage, rax has wrong value.
mov rax, qword ptr[rbp+24]
首先,不,不能保证通过堆栈传递的参数之间的填充被清零。 这是指定的,例如在 System-V ABI,3.2 函数调用序列中,用于类 Unix 系统。
但是,填充字节中的内容也并不重要。 要读取通过堆栈传递的
bool b
的值,编译器可以发出
mov al, byte ptr[rbp+24]
mov
还将结果进行零扩展,因此 rax
的高 56 位现在为零。