Инструкции x87 FPOP и FCOM - как они работают?

Мне было поручено написать простое приложение на смешанном C/ASM, в котором должен использоваться математический сопроцессор.

Функциональный цилиндр (с плавающей точкой x, с плавающей точкой y, с плавающей точкой z) возвращает 1, если заданная точка находится внутри цилиндра (у цилиндра есть основание при x=0,y=0, радиусе = 5 и высоте = 10), и 0 если это не так.

Итак, выглядит просто. Проверьте, находится ли z в пределах <0,10>, а затем проверьте, если x^2 + y^2 < 25.

Но мои знания о x87 ноль.

Там все, что я написал.

_cylinder PROC

push ebp
mov ebp, esp
sub esp,8 ; I can't use .data in the application, so I reserve some space on the stack for numbers 10 and 25
mov [esp],10
mov [esp+4],25

finit
fldz
fld [ebp+8]

    ;here i get stuck 

add esp, 8
pop ebp
_cylinder ENDP

Так что я застрял. Итак, я пытаюсь найти, какие инструкции я мог бы использовать в приложении. И там я застреваю, потому что каждый учебник / список инструкций, которые я нахожу в сети, написан так плохо, что я едва могу что-либо понять.

Вопрос в том, что происходит, когда я выскакиваю что-то из математического сопроцессора? Где я могу найти выбранное значение? Как он конвертирует из 80-битного значения в 32-битное (если это так, конечно)? Другой вопрос, как работает FCOM (FCOMP для поп-варианта)? Он сравнивает что к чему (от st0 до st1 или от st1 до st0?) И где я могу увидеть, меньше ли это значение, равно ли оно или больше?

Спасибо за любую помощь!

1 ответ

Сравнения с плавающей точкой являются своего рода болью. Вы можете выполнить сравнение на FPU, но прежде чем вы сможете что-либо сделать на его основе, вы должны передать слово состояния с плавающей запятой в CPU, проверить наличие нужных вам флагов, а затем отреагировать на основании этого.

Например, ваше первоначальное сравнение с z>=0.0 будет выглядеть примерно так:

fldz
fcomp z
fnstsw ax
test ah, 041h; I *think* I've got the right flags there...
jp good
Другие вопросы по тегам