vectores punto programas lenguaje flotante explicados excepcion ensamblador ejemplos coma x86 floating-point compare assembly gas

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?