Самый простой способ удалить что-то из стека FPU

в последнее время у меня возникли проблемы с переполнением стека FPU. Мне удалось отследить его до функции библиотеки багги, которая толкает значение мусора в стек FPU каждый раз, когда он вызывается, и никогда не очищает его.

к счастью, это легко воспроизводимая и я точно знаю, какие условия вызывают его. Я могу поместить блок встроенного ASM в процедуру, которая вызывает эту процедуру, чтобы вытащить верхнее значение из стека FPU... только я не знаю, что писать. Мой ASM-fu справедлив к middlin', но не это сильный.

Итак, каков самый простой способ избавиться от верхнего значения в стеке FPU в сборке x86, предполагая, что это данные мусора, и меня не волнует значение?

4 ответов


если вы знаете, сколько вам нужно настроить стек, вы можете использовать fincstp. Вы также хотите ffree регистры, которые вы увеличиваете.

однако, вероятно, самым простым решением является использование одной из операций передачи данных popping, таких как fstp. Обычно вы храните результат в области памяти для последующего использования, например:

mem_area: defs 10         ; ten bytes for 80 bits
          fstp mem_area   ; pop it

но, если вы знаете, что просто хотите выбросить значение, вы можете использовать st(0) себя как назначение, сохранение требования к памяти:

fstp st(0)

посмотреть здесь для подробного руководства по инструкциям (в частности,этой).


для Delphi / BASM, на мой взгляд, самый простой способ поп-стека FPU один раз:

asm
 fstp st(0)
end;

если st0 является единственным используемым регистром x87, вы можете очистить его с помощью:

ffree st0

но это отличается от обычного pop, если используется несколько регистров стека, потому что он не настраивает указатель верхней части стека (верхнее поле в слове состояния x87).

посмотреть глава регистров учебника Simply FPU x87.

st1 все равно будет st1 после освобождения st0 вместо микрофона, так что это обычно не то, что вы хотите и не имеет существенного преимущества над fstp st0.


просто вытащите его из стека с любой (быстрой) инструкцией, которая всплывает. 8087 набор команд

Если это не сработает, fucompp всплывает дважды.