Compreendendo os slots de atraso de ramificação para reverter MIPS

Estou revertendo estaticamente alguns softwares compilados para um Atheros AR7161 usando radare2. Este processador implementa MIPS, e eu me lembro que MIPS tem um slot de atraso de ramificação. Isso é realmente perceptível na desmontagem porque posso ver as instruções que devem ser executadas logicamente antes que os ramos sejam colocados logo após eles.

No entanto, ao analisar algum trecho de código, encontrei uma instrução beqz para a qual, supondo que a instrução após ela deve ser executada primeiro não faz sentido no contexto do programa. Devo admitir que minha análise pode estar errada, o que não é improvável; no entanto, tenho algumas dúvidas que também gostaria de esclarecer:

  • Faça todas as instruções de desvio / salto sempre usar o slot de atraso de desvio de forma que a instrução logo após deve ser logicamente executada primeiro ? Se não, em quais casos não seria?

  • Existe alguma maneira de fazer o radare2 mostrar a ordem de execução lógica em vez daquela codificada no binário?

Editar : concretamente, estou lidando com a seguinte sequência:

beqz v0, <some address> lb v0, 0x40(sp) 

Tenho uma imagem muito difusa na minha cabeça sobre essas instruções indo para o pipeline. Posso imaginar a segunda instrução sendo buscada enquanto a primeira está sendo decodificada; , a execução do slot de atraso de ramificação deve realmente começar. No entanto, a instrução de ramificação depende do mesmo registro sendo modificado pela instrução no slot de atraso de ramificação, então o que acontecerá? A instrução de ramificação avaliará a condição usando o registro antigo va lue, ou o novo atualizado por lb?

Obrigado

Comentários

  • Você pode se beneficiar lendo a série MIPS por Raymond Chen aqui: link A primeira resposta é não (e consulte o link para obter detalhes). Não posso ' não responder à segunda.

Resposta

A instrução no slot de retardo de ramificação é avaliada após a instrução de ramificação (ou salto). A execução da instrução no branch delay slot não afeta a avaliação da condição do branch.

Eu observei o branch delay slot ser usado para algumas coisas:

  • Última instrução do bloco básico que conduz à instrução de desvio
    • O teste de desvio não será dependente da saída do cálculo da instrução de slot de atraso de desvio
    • Normalmente visto com saltos / desvios incondicionais como b, jal
  • A primeira instrução do bloco de queda .
    • Nenhum efeito colateral deve estar presente se a ramificação for tomada.
    • A análise mostrará que quaisquer registros afetados não são necessários caso a ramificação seja tomada
  • A primeira instrução de bloco se a ramificação for tomada
    • Se houver vários caminhos para o destino da ramificação, esta instrução provavelmente será vista várias vezes com as diferentes ramificações
  • A carga de um valor condicional, geralmente para valores de retorno

Este artigo entra em detalhes sobre os slots de atraso de ramificação.

Conforme observado por Igor, a versão “provável” da instrução de ramificação mantém os efeitos da instrução no slot de atraso de ramificação apenas se a instrução for realmente executada.

Resposta

  1. Existem variações de ramificações condicionais chamadas “ramificação [na condição] provável”, por exemplo
    • bgezl – Ramificação em Maior que ou Igual a zero provável
    • beql – Ramificação ativada Igualmente provável

Essas instruções têm um intervalo de atraso, mas a instrução no intervalo de atraso é executada apenas se a ramificação for tomada. Se a ramificação não for tomada, a instrução no slot de atraso é não executada ( anulada ) .

NB: essas instruções foram removidas na versão 6 da arquitetura MIPS. Ele também adicionou variações compactas de branches que não têm slots de atraso

Quanto ao seu snippet, suspeito fortemente que o branch usa o valor de registro antigo , mas você provavelmente pode confirmá-lo apenas executando-o em um processador real.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *