Инструкции 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