Pergunta

Estou fazendo um curso de montagem agora, e o cara que verifica nossas tarefas domésticas é uma aberração de otimização da velha escola muito pedante. Por exemplo, ele deduz 10% se vê:

mov ax, 0

ao invés de:

xor ax,ax

Mesmo que seja usado apenas uma vez.

Não sou um iniciante completo na programação de montagem, mas não sou um especialista em otimização, por isso preciso da sua ajuda em algo (pode ser uma pergunta muito estúpida, mas vou fazer de qualquer maneira): se eu precisar definir um valor de registro para 1 ou (-1) é melhor usar:

mov ax, 1

ou faça algo como:

xor ax,ax
inc ax

Eu realmente preciso de uma boa nota, então estou tentando obtê -la o mais otimizada possível. (Eu preciso otimizar o tempo e o tamanho do código)

Foi útil?

Solução

Um rápido Google para 8086 instructions timings size apareceu http://8086.tk/ que parece ter todos os horários e tamanhos para os conjuntos de instruções 8086 (e mais).

Sem dúvida, você pode encontrar a Intel Doco oficial na Web com informações semelhantes.

Para sua pergunta específica:

xor ax,ax
inc ax

leva 3+3 = 6 ciclos de relógio e 2+1 = 3 bytes enquanto

mov ax,1

leva 4 ciclos de relógio e 3 bytes.

Portanto, o último é melhor nesse caso.


Mas você precisa conversar com seu instituto educacional sobre esse cara. 10% para uma coisa simples como essa crença.

Você deve perguntar o que deve ser feito no caso em que você tem duas possibilidades, uma mais rápida e uma mais curta.

Então, uma vez que eles admitiram que existem diferentes maneiras de codificar, dependendo do que você está tentando alcançar, diga a eles que o que você está tentando alcançar é legibilidade e manutenção e seriamente não poderia dar um salto voador sobre um desperdiçado ciclo ou byte aqui ou ali*uma.

A otimização é algo que você geralmente faz se e quando tiver um problema de desempenho, depois que um código de código estiver em um estado quase completo-é quase sempre desperdiçado um esforço quando o código ainda está sujeito a uma probabilidade de mudança não significativa.

Pelo que vale a pena, sub ax,ax parece estar a par de xor ax,ax Em termos de ciclos de relógio e bytes, então talvez você possa jogar isso na mistura na próxima vez para causar um pouco mais de trabalho.

*a) Não, não, na verdade, mas é divertido desabafar ocasionalmente :-)

Outras dicas

Você está melhor com

mov ax, 1

No 8086. Se você estiver rastreando o conteúdo do registro, poderá fazer melhor se souber que, por exemplo, o BX já tem um 1:

mov ax, bx

ou se você sabe que ah é 0:

mov al, 1

etc.

Dependendo de suas circunstâncias, você poderá se safar ...

 sbb ax, ax

O resultado será 0 se o sinalizador de transporte não estiver definido ou -1 se o sinalizador de transporte estiver definido.

No entanto, se o exemplo acima não for aplicável à sua situação, eu recomendaria o

xor  ax, ax
inc  ax

método. Deve satisfazer seu professor por tamanho. No entanto, se o seu processador empregar qualquer alinhamento, eu esperaria que houvesse algum atraso semelhante ao acoplamento entre as duas instruções (eu poderia muito bem estar errado nisso). Se esse acoplamento existir, a velocidade poderá ser ligeiramente melhorada, reordenando levemente suas instruções para ter outra instrução entre eles (uma que não usa AX).

Espero que isto ajude.

eu usaria mov [e]ax, 1 em qualquer circunstância. Sua codificação não é mais do que o hackier xor Sequência, e tenho certeza de que é mais rápido em qualquer lugar. 8086 é estranho o suficiente para ser a exceção e, como isso é tão lento, uma microtimização como essa faria mais diferença. Mas em qualquer outro lugar: a execução de 2 instruções "fáceis" sempre será mais lenta do que a execução 1, especialmente se você considerar riscos de dados e tubulações longas. Você está tentando ler um registro na próxima instrução depois de modificá -lo, portanto, a menos que sua CPU possa ignorar o resultado do estágio n do pipeline (onde o xor está sendo executado) para fazer o estágio N-1 (onde o INC está tentando carregar O registro, não importa adicionar 1 ao seu valor), você terá barracas.

Outras coisas a considerar: Fetch de instrução Fetch Bandwidth (discutível para o código de 16 bits, ambos são 3 bytes); mov evita a mudança de sinalizadores (com maior probabilidade de serem úteis do que forçá -los a zero); Dependendo de quais valores outros registros podem conter, você talvez possa fazer lea ax,[bx+1] (também 3 bytes, mesmo em código de 32 bits, sem efeito nos sinalizadores); Como outros disseram, sbb ax,ax Pode funcionar também em circunstâncias - também é mais curto em 2 bytes.

Quando confrontado com esses tipos de micro otimizações, você realmente deveria a medida As alternativas, em vez de confiar cegamente, mesmo nos manuais do processador.

PS Novo dever de casa: é xor bx,bx qualquer mais rápido que xor bx,cx (em qualquer processador)?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top