A diferença entre os registros salvos e salvos de Callee afeta significativamente o desempenho e a eficiência do programa, principalmente através da sobrecarga de economizar e restaurar valores de registro durante as chamadas de função.
registros salvos de chamadas (também conhecidos como registros voláteis): *
Definição: Esses registros são de responsabilidade do
chamador (a função que faz a chamada) para preservar se seus valores forem necessários após o retorno do Callee (a função que está sendo chamada).
* Mecanismo
: Antes de chamar uma função, se o chamador tiver valores importantes armazenados nos registros salvos de chamadas, ele deverá empurrar esses valores para a pilha (ou salvá-los em outros lugares da memória). Após o retorno do Callee, o chamador pode recuperar os valores salvos nesses registros.
*
Impacto no desempenho: *
Sobrecarga no local de chamada: Os registros salvos de chamadas levam à sobrecarga na função de chamada. Cada chamada pode exigir registros de empurrar e estourar, mesmo que o Callee não use esses registros.
*
potencialmente menos sobrecarga se Callee for simples: Se o Callee for pequeno e não precisar usar muitos registros, o chamador pode não precisar salvar nada, tornando a chamada relativamente eficiente. O chamador salva apenas os registros que sabe que precisa * e * o callee pode potencialmente confundir.
*
Adequado para valores de vida curta: Bom para variáveis que só precisam viver em um pequeno escopo, pois a economia/restauração se torna menos preocupante.
*
Exemplo: Em muitas convenções de chamadas x86-64 (como o System v amd64 abi), registra registros como `rax`,` rcx`, `rdi`,` rsi`, `r8`er,` r9`, `r10`,` r11` e alguns registros de ponto flutuante são como `xmm0-xm0.
registros salvos de Callee (também conhecidos como registros não voláteis): *
Definição: Esses registros são de responsabilidade do
callee (a função que está sendo chamada) para preservar. Se o Callee quiser usá -los, ele deve salvar seus valores originais no início da função e restaurá -los antes de retornar.
* Mecanismo
: O Callee empurra os valores originais desses registros para a pilha no início de sua execução. Antes de retornar, o Callee recolhe esses valores aos registros, restaurando -os efetivamente ao seu estado original.
*
Impacto no desempenho: *
Sobrecarga dentro do callee: Os registros salvos de Callee introduzem a sobrecarga na função Callee. Cada Callee usando esses registros deve executar a poupança e a restauração, independentemente do que o chamador está fazendo.
*
melhor para Callee usando muitos registros: Se o Callee precisar de muitos registros, o uso de registros salvos de Callee poderá ser mais eficiente do que os registros salvos de chamadas. O chamador tem a garantia de que esses registros serão preservados sem ter que fazer nada.
*
Adequado para valores de vida longa: Bom para variáveis que precisam viver em um grande escopo de função, pois a sobrecarga de salvar/restaurar é amortizada por maior duração de seu uso.
*
Exemplo: No sistema x86-64 v amd64 abi, registra registros como `rbx`,` rsp`, `rbp`,` r12`, `r13`,` r14`, `r15` são salvados. `rsp` é especial (ponteiro de pilha) e` rbp` (ponteiro base) é frequentemente usado para gerenciamento e depuração de quadros de pilha.
Diferenças -chave e implicações de desempenho: | Recurso | Registros salvos de chamadas | Registros salvos de Callee |
| ---------
| Responsabilidade | Chamador para salvar e restaurar, se necessário, antes de ligar para uma função. | Callee para salvar e restaurar se forem usados pelo Callee. |
| Sobrecarga | Principalmente na função de chamada (potencialmente sem sobrecarga se o chamador não precisar desses registros). | Principalmente dentro da função chamada (sobrecarga se o chamador precisa ou não dos registros preservados). |
| Melhor uso | Quando o chamador precisa preservar os valores em apenas um pequeno subconjunto de chamadas. | Quando o Callee é grande e provavelmente usará muitos registros, evitando que o chamador tenha que salvar muitos registros possíveis. |
| Exemplo (x86-64) | `rax`,` rcx`, `rdi`,` rsi`, `r8`,` r9`, `r10`,` r11` | `rbx`,` rsp`, `rbp`,` r12`, `r13`,` r14`, `r15` |
Qual é melhor? Não há abordagem universalmente "melhor". A escolha ideal depende das especificidades das convenções de chamada, da estrutura do programa, da frequência das chamadas de função e do tamanho e da complexidade das funções. As estratégias de alocação de registro usadas por compiladores e programadores visam minimizar a sobrecarga de salvar e restaurar registros, escolhendo de forma inteligente quais registros para usar para diferentes fins.
*
pequenas chamadas frequentes: O chamado pode ser preferível, pois o chamador salva apenas o que precisa. O Callee consegue usar os registros sem nenhum custo de economia/restauração.
*
chamadas grandes pouco frequentes: A Callee salva pode ser preferível se o Callee usar muitos registros. O Callee terá o custo de economizar/restaurar esses registros, mas o chamador está livre de ter que antecipar quais registros precisam ser salvos.
em resumo: A escolha entre os registros salvos e salvos de Callee envolve uma troca entre as despesas gerais no local da chamada e a sobrecarga dentro da função chamada. As convenções eficazes de alocação e chamada de registro visam minimizar essa sobrecarga para melhorar o desempenho do programa. Compiladores e programadores de montagem devem entender esses conceitos para otimizar o código para obter eficiência. O ABI (interface binária do aplicativo) define quais registros são salvos de chamadas e que são salvos de callee para uma arquitetura e sistema operacional específico.