Инструкции x87 FPOP и FCOM - как они работают? - PullRequest
5 голосов
/ 25 августа 2011

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

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

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

Но мои знания о 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-битное?Он сравнивает что к чему (от st0 до st1 или от st1 до st0?) И где я могу узнать, меньше ли это значение, равно ли оно или больше?

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

1 Ответ

5 голосов
/ 25 августа 2011

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

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

fldz
fcomp z
fnstsw ax
test ah, 041h; I *think* I've got the right flags there...
jp good
...