J'ai eu des problèmes récemment avec des débordements de pile FPU. J'ai réussi à le suivre dans une fonction de bibliothèque de buggy qui pousse une valeur détruite sur la pile FPU à chaque fois qu'elle s'appelle et ne le nettoie jamais. P>
Heureusement, cela est facilement reproductible et je sais exactement quelles conditions le causent. Je peux déposer un bloc d'Inline ASM dans la routine qui appelle cette routine pour faire sauter la valeur supérieure de la pile FPU ... sauf que je ne sais pas tout à fait quoi écrire. Mon asm-fu est juste à Middlin ', mais pas que em> fort. P>
Alors, quel est le moyen le plus simple de se débarrasser de la valeur supérieure de la pile FPU dans l'assemblage X86, en supposant que les ordures et je m'en fiche de la valeur? P>
4 Réponses :
Si vous savez combien vous devez ajuster la pile par, vous pouvez utiliser Cependant, la solution la plus simple est probablement d'utiliser l'une des opérations de transfert de données Popping, telles que mais, si vous savez que vous voulez juste jeter la valeur, vous pouvez utiliser voir FINCSTP code>. Vous souhaitez également
ffrae code> les registres que vous incrémentez-vous.
FSTP code>. Normalement, vous stockeriez le résultat dans une zone de mémoire pour une utilisation ultérieure, quelque chose comme: p>
ST (0) CODE> AS la destination, enregistrant l'exigence de la mémoire: p>
Notez que 'FSTP St (0)' nécessite une horloge. Ça ne va pas mieux que ça.
@ALBERTVANDERHORST: Les processeurs Superscalar peuvent facilement faire mieux que cela. FSTP / FST CODE> avec une destination d'enregistrement a un débit de 0,5C (I.e. 2 par horloge) sur HASWELL / SKYLAKE. agner.org/optimize . Enregistrer le renommage S'occupe de la dépendance via le pointeur haut de pile.
Poussez-la de la pile avec une instruction (rapide) qui apparaît.
Si cela ne fonctionne pas, FUCOMPP apparaît deux fois. p>
Si mais c'est différent d'une pop normale s'il y a plusieurs piles s'il y a plusieurs piles Les registres utilisés, car ils ne réglèrent pas le pointeur haut de pile (champ supérieur du mot d'état X87). p> voir ST0 code> est le seul registre X87 utilisé, vous pouvez le vider avec:
ST1 code> serait toujours
ST1 CODE> après libération
ST0 CODE> au lieu de sauter, il n'est donc normalement pas ce que vous voulez et n'a pas d'avantage significatif sur
FSTP ST0 code>. P> P> P> P> P> >
Cela ne fonctionne pas. ST0 est étiqueté comme vide, mais cela n'affecte rien, à l'exception du mot tag FPU.
Je ne sais pas quoi d'autre que vous voudriez affectés, car c'est la définition de ce qui est dans le registre.
Bien sûr, vous voulez que le pointeur de pile ait également changé. J'ai vérifié expérimentalement (par petits mots de code, mon quatrième, CIForth) que votre solution ne fonctionne pas comme prévu. Voir la réponse donnée par les this qui est correct.
Pourquoi voudrais-je que le SP a changé? La pile est vide, peu importe où vous commencez à le remplir.
Oh je l'obtiens, dans ma réponse, il dit "Top" de la valeur, c'est une mauvaise formulation. Je voulais dire si la valeur supérieure est la seule valeur sur la pile. "Bas" serait correct.
Si vous pensez que la modification de la valeur supérieure à la valeur inférieure rend votre réponse correcte, vous devez éditer cela. Je l'ai fait pour vous, mais vous vous êtes senti obligé de signaler une carence dans votre réponse. Selon mon autre commentaire, on peut assurer que cela est sauvegardé mon expérimentation. Albert
J'étais un peu surpris que quelqu'un avec votre réputation donnerait une réponse incorrecte. Maintenant, je vois que c'est littéralement correct, désolé. S'il n'y a qu'un seul élément sur la pile et la pile est autrement vide, puis avec le réglage de ce mot d'étiquette, tous les mots d'étiquette indiquent vide et en effet pour cette pile circulaire, cela ne compte pas où le pointeur de la piste pointe. Je ne peux pas voir Wheeler indiquer qu'il n'y a qu'un seul élément sur la pile, cependant. Groetjes Albert
Oui, la formulation dans la réponse n'était pas claire sur ce que je voulais dire.
@ Jensbjörnhager: Votre mise à jour était techniquement correcte, mais toujours facile à interpréter mal pour les personnes qui ne savaient pas assez d'environ X87 pour même penser à la seule-maladie à 1-registre-utilisation étant pertinente / importante. Je réécrit fondamentalement la réponse autre que le bloc de code à quelque chose qui vaut la peine d'être upvote.
Pour Delphi / Basm, à mon avis, le moyen le plus simple de sauter la pile FPU une fois:
asm fstp st(0) end;
C'est en fait la bonne réponse. La plupart des implémentations X87 sont optimisées pour ce boîtier et n'effectueront même pas le transfert, affichez simplement la valeur de la pile.
Pour l'enregistrement, X87 est obsolète. Le code moderne utilisera normalement les registres XMM, même pour Scalar FP Math, avec des instructions telles que
ajoute code> (scalaire unique de précision) ou
addsd code> (Double scalaire)
. Regardez le code généré du compilateur pour toute fonction FP pour des exemples.