Simplest façon d'enlever quelque chose de la pile FPU
Question
J'ai eu quelques problèmes récemment avec les trop-pleins de FPU. J'ai réussi à le suivre revenir à une fonction de bibliothèque qui pousse bogué une valeur d'ordures sur la FPU pile chaque fois qu'il est appelé et ne nettoie vers le haut.
Heureusement, cela est facilement reproductible et je sais exactement quelles conditions la cause. Je peux laisser tomber un bloc de ASM en ligne dans la routine qui appelle cette routine pour faire apparaître la valeur de retour vers le haut de la pile FPU ... sauf que je ne sais pas quoi écrire. Mon ASM-fu est juste de Middlin', mais pas que forte.
Alors, quelle est la façon la plus simple de se débarrasser de la valeur supérieure sur l'ensemble pile FPU x86, en supposant ses données d'ordures et je ne se soucient pas de la valeur?
La solution
Si vous savez combien vous devez régler la pile par, vous pouvez utiliser fincstp
. Vous voulez également ffree
les registres que vous incrémenter sur.
Cependant, sans doute la solution la plus simple est d'utiliser l'une des opérations de transfert de données popping comme fstp
. Normalement, vous stocker le résultat dans une zone de mémoire pour une utilisation ultérieure, quelque chose comme:
mem_area: defs 10 ; ten bytes for 80 bits
fstp mem_area ; pop it
Mais, si vous savez que vous voulez juste jeter la valeur, vous pouvez utiliser lui-même st(0)
comme destination, l'exigence d'économie de mémoire:
fstp st(0)
Voir pour un guide détaillé sur les instructions (en particulier ce bit ).
Autres conseils
Pour Delphi / BASM, à mon avis, la façon la plus simple pour faire apparaître la pile FPU est une fois:
asm
fstp st(0)
end;
Si st0
est le seul registre x87 en cours d'utilisation, vous pouvez vider avec:
ffree st0
Mais ce qui est différent d'un pop normal s'il y a plusieurs registres de pile en cours d'utilisation, car elle ne règle pas le pointeur haut de la pile (champ TOP dans le mot d'état de x87).
Voir le chapitre registres du FPU x87 simplement tutoriel .
st1
serait encore st1
après avoir libéré st0
au lieu de sauter, c'est donc normalement pas ce que vous voulez et n'a aucun avantage significatif sur fstp st0
.
pop juste la pile avec un (rapide) instruction qui pops. 8087 jeu d'instructions
si cela ne fonctionne pas, FUCOMPP apparaît deux fois.