Considere o seguinte exemplo:
struct vector {
int size() const;
bool empty() const;
};
bool vector::empty() const
{
return size() == 0;
}
O código de montagem gerado para vector::empty
(por clang, com otimizações):
push rax
call vector::size() const
test eax, eax
sete al
pop rcx
ret
Por que alocar espaço na pilha? Não é usado de todo. O push
e pop
pode ser omitido. Compilações otimizadas de MSVC e gcc também usam espaço de pilha para esta função (veja no godbolt ), portanto, deve haver uma razão.
this
parâmetro implícito ?vector::size()
não está definido no exemplo para simular que não está embutido.vector::size()
não é relevante para alocar ou não alocar um quadro de pilhavector::empty()
. Emempty()
que é simplesmente chamado, seja ele qual for.Respostas:
Ele aloca espaço na pilha, para que a pilha seja alinhada por 16 bytes. É necessário, porque o endereço de retorno ocupa 8 bytes; portanto, é necessário um espaço adicional de 8 bytes para manter a pilha de 16 bytes alinhada.
O alinhamento de quadros de pilha pode ser configurado com argumentos de linha de comando para alguns compiladores.
rsp
no início da função, o que significa que algo mais também afeta isso.-mstack-alignment
opção especifica o alinhamento da pilha. Parece que o padrão é 16, embora não esteja documentado. Se você defini-lo como 8, a alocação da pilha (push
epop
) desaparece do código de montagem gerado.-mpreferred-stack-boundary
opção especifica o alinhamento da pilha. Se o valor fornecido for N, significa 2 ^ N bytes de alinhamento. O valor padrão é 4, o que significa 16 bytes. Se você defini-lo como 3 (ou seja, 8 bytes), a alocação da pilha (sub
eadd
pararsp
) desaparece do código de montagem gerado.Confira no godbolt .
fonte