2010-12-22 41 views
6

Tengo un pequeño emulador 8086 y he tenido un error de larga data desde hace como 2 años que AF no se comporta correctamente dentro de sub y agrega instrucciones.¿Explicar cómo funciona el indicador de AF en las instrucciones x86?

mi actual forma de cálculo de su valor es este para los números de 8 bits y resta:

uint8_t base=... , subt=... 
base=base&0xF; 
subt=subt&0xF; //isolate bottom nibble 
if((int16_t)base-subt>7 || (int16_t)base-subt<-7){ 
    flags.af=1; 
}else{ 
    flags.af=0; 
} 

(suponiendo una instrucción como sub base,subt)

Y para añadir que es así:

uint8_t base=... , adder=... 
base=base&0xF; 
adder=adder&0xF; //isolate bottom nibble 
if(base+adder>7 || base+adder<-7){ 
    flags.af=1; 
}else{ 
    flags.af=0; 
} 

(para una instrucción como add base,adder)

¿Cómo calculo correctamente el indicador de AF en mi emulador para tales instrucciones?

Respuesta

4
flags.af = (((base-subt) & ~0xf) != 0); 

Comprueba si los bits superiores son cualquier cosa excepto cero, lo que indicaría un desbordamiento o subdesbordamiento de la parte inferior 4 bits.

Aquí hay una versión que está un poco más cerca de su original. Tenga en cuenta que la diferencia entre dos cantidades de 4 bits nunca será superior a 15. Del mismo modo la adición nunca será inferior a 0.

flags.af = ((int16_t)base-subt < -15); 

flags.af = ((int16_t)base+adder > 15); 

poner paréntesis alrededor de una expresión booleana es sólo una preferencia de estilo mío, lo sé son redundantes.

+0

Veo cómo la versión bit a bit es equivalente a las otras versiones. ¡Si hubiera sabido sobre el desbordamiento de pila cuando estaba escribiendo este emulador por primera vez! 7 líneas de código en 1. – Earlz

+0

@Earlz, dejé fuera las líneas donde estaba '& 0xf', ésas son todavía necesarias en esta versión. Sin embargo, puede ponerlos fácilmente en la expresión y aún así terminar con un solo liner. –

Cuestiones relacionadas