Quando você chama uma função de C/C++, que tem alguns parâmetros menores que 64 bits, o tempo de execução zera a memória da pilha no local inicial desses parâmetros? Ou o topo de cada parâmetro contém lixo?
O espaço para cada parâmetro é de 8 bytes (64 bits), mas eles podem representar valores de 8, 16 ou 32 bits.
Suponha que os parâmetros não sejam passados por registro, pois esta questão se refere a qualquer parâmetro, não apenas aos quatro primeiros.
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]
Primeiramente, não, não há garantia de que o preenchimento entre parâmetros que são passados pela pilha seja zerado. Isso é especificado, por exemplo, no System-V ABI, 3.2 Function Calling Sequence , que é usado em sistemas do tipo Unix.
No entanto, também não importa realmente o que está nos bytes de preenchimento. Para ler o valor de a
bool b
que foi passado pela pilha, o compilador poderia emitirIsso ignora os 56 bits de preenchimento superiores no ponteiro. Se os 56 bits superiores de RAX devem ser zero,
movzx
também pode ser usado da seguinte forma: