Forma más sencilla de eliminar algo de la pila de fpu
Pregunta
He tenido algunos problemas últimamente con los desbordamientos de la pila de FPU. Me las arreglé para volver a una función de biblioteca de buggy que empuja un valor de basura a la pila de FPU cada vez que se llama y nunca la limpia.
Afortunadamente, esto es fácilmente reproducible y sé exactamente qué condiciones lo causan. Puedo dejar caer un bloque de ASM en línea en la rutina que llama a esta rutina para volver a sacar el valor superior de la pila de FPU ... excepto que no sé qué escribir. Mi ASM-FU es justo para Middlin ', pero no que fuerte.
Entonces, ¿cuál es la forma más sencilla de deshacerse del valor superior en la pila de FPU en el ensamblaje X86, suponiendo que sean datos de basura y no me importa el valor?
Solución
Si sabe cuánto necesita ajustar la pila, puede usar fincstp
. Tu tambien quieres ffree
Los registros sobre los que se incrementa.
Sin embargo, probablemente la solución más simple es usar una de las operaciones de transferencia de datos de estallido como fstp
. Normalmente almacenaría el resultado en un área de memoria para su uso posterior, algo así como:
mem_area: defs 10 ; ten bytes for 80 bits
fstp mem_area ; pop it
Pero, si sabes que solo quieres tirar el valor, puedes usar st(0)
en sí mismo como destino, guardando el requisito de memoria:
fstp st(0)
Ver aquí Para una guía detallada sobre las instrucciones (particularmente esta bit).
Otros consejos
Para Delphi/BASM, en mi opinión, la forma más sencilla de explotar la pila de FPU una vez es:
asm
fstp st(0)
end;
Si st0
es el único registro x87 en uso, puede vaciarlo con:
ffree st0
Pero esto es diferente de un POP normal si hay múltiples registros de pila en uso, porque no ajusta el puntero de la parte superior (campo superior en la palabra de estado x87).
Ver El capítulo de registros del tutorial simplemente FPU x87.
st1
todavía sería st1
Después de liberar st0
En lugar de explotar, por lo que esto normalmente no es lo que quieres y no tiene una ventaja significativa sobre fstp st0
.
Simplemente salga de la pila con cualquier instrucción (rápida) que establezca.Conjunto de instrucciones 8087
Si eso no funciona, Fucompp aparece dos veces.