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?