Есть прога на делфях, так эта зараза, при некоторых обстоятельствах, начинает стабильно вылетать внутри функции trunc (взятие целого). разбор полетов в дизассемблере привел к следующему: имеем прогу: Код (Text): cwChop dw 1F32h temp dd ? fldcw word ptr [cwChop] fldz fistp dword ptr [temp] Эта прога нормально отрабатывает, если на момент вызова fldz регистры фпу следующие: Код (Text): CTRL = 1F72h STAT = 4020h TAGS = FFFFh ...и уходит в эксепшн, если регистры следующие: Код (Text): CTRL = 1F72h STAT = 81A7h TAGS = FFFFh как можно видеть, эти два состояния отличаются только значением STAT. Вопрос, че такого волшебного во втором значении STAT, что вылетает эксепшн? Интеловский мануал на команду fldz говорит, что floating-point exception может вылетать только если stack overflow occured, но на момент вызова fldz стек фпу чист для обоих случаев, так что это вроде не тот случай. Штуку эту я поборол (переписал trunc , но вот разобраться охота... если хто знает - подскажите.
получается вообще какая-то 屁股 - загрузка control word через fldcw приводит к тому, что в status word выставляется флаг FPU Busy, то есть: Код (Text): // CTRL = 127Fh // STAT = 0127h fldcw word ptr [cwChop] // CTRL = 1F72h // STAT = 81A7 после чего, любое обращение к фпу (даже fwait) приводит к эксепшену 8-|
Max Ес-но при размаскировании исключений нужен fclex. Младшие 6 бит CW и SW соответствуют исключениям FPU. Даже если исключения замаскированы в CW, тем не менее они контролируются и выставляются в SW и сидят там до тех пор пока не будут сброшены явно fclex,finit,fsave\frstor. Вот и получается, что ты или не сделал finit или успел нахватать почти полный комплект замаскированных эксепшенов в SW = x7h, а после fldcw они размаскируются и "волшебным образом" проявляются на первой же инструкции после fldcw. А то, что "зараза" вылетает на trunc, то это для твоей же пользы Значит число слишком большое и не умещается в целое и "зараза" тебя об этом предупреждает - примите уважаемый соответствующие меры