programas - ensamblador x86: punto flotante comparar
punto flotante en ensamblador 8086 (1)
Todo esto proviene del Volumen 2 de los manuales del desarrollador de software Intel 64 e IA-32 Architectures .
FCOMI establece solo algunos de los indicadores que CMP hace. Su código tiene %st(0) == 9 y %st(1) == 10 . (Dado que es una pila en la que están cargados), refiriéndose a la tabla de la página 3-348 del Volumen 2A, puede ver que este es el caso "ST0 <ST (i)", por lo que borrará ZF y PF y establecerá CF. Mientras tanto en la pág. 3-544 vol. 2A puede leer que JG significa "salto corto si es mayor (ZF = 0 y SF = OF)". En otras palabras, está probando el signo, el desbordamiento y las banderas cero, ¡pero FCOMI no establece el signo ni el desbordamiento!
Dependiendo de las condiciones en las que desee saltar, debe observar los posibles resultados de comparación y decidir cuándo desea saltar.
+--------------------+---+---+---+ | Comparison results | Z | P | C | +--------------------+---+---+---+ | ST0 > ST(i) | 0 | 0 | 0 | | ST0 < ST(i) | 0 | 0 | 1 | | ST0 = ST(i) | 1 | 0 | 0 | +--------------------+---+---+---+
He hecho esta pequeña tabla para que sea más fácil de entender:
+--------------+---+---+-----+------------------------------------+ | Test | Z | C | Jcc | Notes | +--------------+---+---+-----+------------------------------------+ | ST0 < ST(i) | X | 1 | JB | ZF will never be set when CF = 1 | | ST0 <= ST(i) | 1 | 1 | JBE | Either ZF or CF is ok | | ST0 == ST(i) | 1 | X | JE | CF will never be set in this case | | ST0 != ST(i) | 0 | X | JNE | | | ST0 >= ST(i) | X | 0 | JAE | As long as CF is clear we are good | | ST0 > ST(i) | 0 | 0 | JA | Both CF and ZF must be clear | +--------------+---+---+-----+------------------------------------+ Legend: X: don''t care, 0: clear, 1: set
En otras palabras, los códigos de condición coinciden con aquellos para usar comparaciones sin signo. Lo mismo ocurre si estás usando FMOVcc .
Si cualquiera (o ambos) operando a fcomi es NaN, establece ZF=1 PF=1 CF=1 . (Las comparaciones de PF tienen 4 posibles resultados: > , < , == o desordenados). Si le importa lo que hace su código con NaN, puede necesitar un jp o jnp . Pero no siempre: por ejemplo, ja solo es verdadero si CF = 0 y ZF = 0, por lo que no se tomará en el caso desordenado. Si desea que el caso desordenado tome la misma ruta de ejecución de abajo o igual, entonces ja es todo lo que necesita.
Aquí debe usar JA si desea que se imprima (es decir, if (!(f2 > f1)) { puts("hello"); } ) y JBE si no lo hace (corresponde a if (!(f2 <= f1)) { puts("hello"); } ). (Tenga en cuenta que esto puede ser un poco confuso debido al hecho de que solo imprimimos si no saltamos).
En cuanto a su segunda pregunta: de manera predeterminada, fcomi no fcomi nada. Quieres su primo cercano fcomip que aparece %st0 . Siempre debes borrar la pila del registro de fpu después del uso, así que todo en tu programa termina así suponiendo que quieres que se imprima el mensaje:
.section .rodata
msg: .ascii "Hallo/n/0"
f1: .float 10.0
f2: .float 9.0
.globl main
.type main, @function
main:
flds f1
flds f2
fcomip
fstp %st(0) # to clear stack
ja leb # won''t jump, jbe will
pushl $msg
call printf
addl $4, %esp
leb:
pushl $0
call exit
Como parte de un proyecto de compilación, tengo que escribir el código de ensamblador de GNU para x86 para comparar valores de coma flotante. He intentado encontrar recursos sobre cómo hacer esto en línea y por lo que entiendo funciona así:
Suponiendo que los valores a que quiero comparar son los únicos valores en la pila de coma flotante, entonces la instrucción fcomi comparará los valores y establecerá los indicadores de CPU para que se puedan usar las instrucciones je, jne, jl, ....
Lo estoy preguntando porque esto solo funciona a veces. Por ejemplo:
.section .data
msg: .ascii "Hallo/n/0"
f1: .float 10.0
f2: .float 9.0
.globl main
.type main, @function
main:
flds f1
flds f2
fcomi
jg leb
pushl $msg
call printf
addl $4, %esp
leb:
pushl $0
call exit
no imprimirá "Hallo" aunque creo que debería hacerlo, y si cambia f1 y f2, no será lo que es una contradicción lógica. je y jne sin embargo parecen funcionar bien.
¿Qué estoy haciendo mal?
PD: ¿el Fcomip muestra solo un valor o muestra ambos?