Проблема с сопроцессором

Discussion in 'WASM.ASSEMBLER' started by Max, Apr 25, 2005.

  1. Max

    Max Member

    Blog Posts:
    0
    Joined:
    May 22, 2003
    Messages:
    192
    Есть прога на делфях, так эта зараза, при некоторых обстоятельствах, начинает стабильно вылетать внутри функции trunc (взятие целого).



    разбор полетов в дизассемблере привел к следующему:



    имеем прогу:
    Code (Text):
    1.  
    2.      cwChop dw 1F32h
    3.      temp   dd ?
    4.      fldcw word ptr [cwChop]
    5.      fldz
    6.      fistp dword ptr [temp]
    7.  


    Эта прога нормально отрабатывает, если на момент вызова fldz регистры фпу следующие:
    Code (Text):
    1.  
    2.      CTRL = 1F72h
    3.      STAT = 4020h
    4.      TAGS = FFFFh
    5.  


    ...и уходит в эксепшн, если регистры следующие:
    Code (Text):
    1.  
    2.      CTRL = 1F72h
    3.      STAT = 81A7h
    4.      TAGS = FFFFh
    5.  


    как можно видеть, эти два состояния отличаются только значением STAT.



    Вопрос, че такого волшебного во втором значении STAT, что вылетает эксепшн?

    Интеловский мануал на команду fldz говорит, что floating-point exception может вылетать только если stack overflow occured, но на момент вызова fldz стек фпу чист для обоих случаев, так что это вроде не тот случай.



    Штуку эту я поборол (переписал trunc :), но вот разобраться охота...

    если хто знает - подскажите.
     
  2. Max

    Max Member

    Blog Posts:
    0
    Joined:
    May 22, 2003
    Messages:
    192
    получается вообще какая-то 屁股 - загрузка control word через fldcw приводит к тому, что в status word выставляется флаг FPU Busy, то есть:
    Code (Text):
    1.  
    2.      // CTRL = 127Fh
    3.      // STAT = 0127h
    4.      fldcw word ptr [cwChop]
    5.      // CTRL = 1F72h
    6.      // STAT = 81A7
    7.  


    после чего, любое обращение к фпу (даже fwait) приводит к эксепшену 8-|
     
  3. gloom

    gloom New Member

    Blog Posts:
    0
    Joined:
    Jul 23, 2004
    Messages:
    11
    Чтобы исключений не было, перед fldcw нужно выполнить fclex.
     
  4. leo

    leo Active Member

    Blog Posts:
    0
    Joined:
    Aug 4, 2004
    Messages:
    2,542
    Location:
    Russia
    Max



    Ес-но при размаскировании исключений нужен fclex.

    Младшие 6 бит CW и SW соответствуют исключениям FPU.

    Даже если исключения замаскированы в CW, тем не менее они контролируются и выставляются в SW и сидят там до тех пор пока не будут сброшены явно fclex,finit,fsave\frstor.

    Вот и получается, что ты или не сделал finit или успел нахватать почти полный комплект замаскированных эксепшенов в SW = x7h, а после fldcw они размаскируются и "волшебным образом" проявляются на первой же инструкции после fldcw.



    А то, что "зараза" вылетает на trunc, то это для твоей же пользы :) Значит число слишком большое и не умещается в целое и "зараза" тебя об этом предупреждает - примите уважаемый соответствующие меры :)