assembly x86 increment flags decrement

assembly - ¿Por qué las instrucciones INC y DEC*no*afectan al indicador de acarreo(CF)?



x86 increment (4)

¿Por qué la instrucción x86 INC (incremento) y DEC (decremento) no afectan la CF (indicador de acarreo) en FLAGSREGISTER?


  1. Las instrucciones inc y dec se utilizan normalmente para mantener la iteración o el recuento de bucles. Usando 32 bits, el número de iteraciones puede ser tan alto como 4,294,967,295. Este número es suficientemente grande para la mayoría de las aplicaciones. ¿Qué pasa si necesitamos una cuenta que es mayor que esto? ¿Tenemos que usar add en lugar de inc? Esto conduce a la segunda razón, y la principal.

  2. La condición detectada por el indicador de acarreo también puede detectarse mediante el indicador cero. ¿Por qué? Debido a que inc y dec cambian el número solo por 1. Por ejemplo, supongamos que el registro ECX ha alcanzado su valor máximo 4,294,967,295 (FFFFFFFFH). Si luego ejecutamos

    inc ECX

    normalmente esperaríamos que el indicador de acarreo se establezca en 1. Sin embargo, podemos detectar esta condición si notamos que ECX = 0, que establece el indicador cero. Por lo tanto, establecer la marca de acarreo es realmente redundante para estas instrucciones.


La pregunta de por qué firmar cuando tiene un indicador de cero establecido por inc / dec se aborda mejor con una pregunta: ¿preferiría prescindir de la opción a ?

a) for (n=7;n>=0;n--) // translates to `dec + jns` b) for (n=8;n>0;n--) // translates to `dec + jnz`

Como ya se aclaró Ira Baxter , la bandera de acarreo se usa en muchos algoritmos, no solo de aritmética multiprecisión, sino también para el procesamiento de mapas de bits en la era monocroma / cga / EGA: esto desplaza la fila de 80 píxeles de un píxel a la derecha ...

mov cx, 10 begin: lodsb rcr al,1 // this is rotate though carry: stosb // for the algorithm to work, carry must not be destroyed LOOP begin //

Pero entonces: ¿por qué la paridad?

Creo que la respuesta es por qué no. Este conjunto de instrucciones es de finales de los 70, cuando los transistores eran escasos. Negar el cálculo de la bandera de paridad para alguna instrucción en particular no hubiera tenido ningún sentido, sino que se agregó a la complejidad de la CPU.


Para comprender por qué es probable que tenga que recordar las CPUs "x86" actuales con valores de 32 y 64 bits, la vida comenzó como máquinas de 8 bits mucho más limitadas, volviendo a la Intel 8008. (Codifiqué en este mundo en 1973, todavía Recuérdalo (ugh)!).

En ese mundo, los registros eran preciosos y pequeños. Necesita INC / DEC para varios propósitos, siendo el control de bucle más común. Muchos bucles implicaron hacer "aritmética de precisión múltiple" (por ejemplo, ¡16 bits o más!) Al hacer que INC / DEC establecido el indicador Cero ( Z ), podría usarlos para controlar los bucles bastante bien; Al insistir en que las instrucciones de control de bucle no cambien el indicador de acarreo ( CF ), el arrastre se conserva en las iteraciones de bucle y puede implementar operaciones de multiprecisión sin escribir toneladas de código para recordar el estado de acarreo.

Esto funcionó bastante bien, una vez que te acostumbraste al conjunto de instrucciones feo.

En máquinas más modernas con tamaños de palabras más grandes, no necesita mucho, por lo que INC y DEC podrían ser semánticamente equivalentes a ADD ..., 1, etc. Eso es lo que uso cuando necesito el conjunto de acarreo: }

En su mayoría, me mantengo alejado de INC y DEC ahora, ya que hacen actualizaciones parciales del código de condición, y esto puede causar paradas divertidas en la tubería, y ADD / SUB no. Entonces, donde no importa (la mayoría de los lugares), uso ADD / SUB para evitar los puestos. Utilizo INC / DEC solo cuando mantengo el código sin importancia, por ejemplo, ajustando una línea de caché donde el tamaño de una o dos instrucciones hace la diferencia suficiente para importar. Esto es probablemente nano [¡literalmente!] - optimización, pero mis hábitos de codificación son bastante anticuados.

Mi explicación nos dice por qué INC / DEC establece la bandera de cero ( Z ). No tengo una explicación particularmente convincente de por qué INC / DEC establece el signo (y la bandera de paridad).

EDITAR en abril de 2016: Parece que el problema del bloqueo se maneja mejor en los x86 modernos. Ver instrucción INC vs ADD 1: ¿Importa?


Porque no hay necesidad de afectar. Es suficiente con comprobar la bandera de cero. Por lo tanto, después de las instrucciones inc y dec, la bandera de acarreo sigue siendo la misma y en algunos casos es útil.