Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Assembly x86 > Re: help spot t...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 9 of 9 Topic 4580 of 4710
Post > Topic >>

Re: help spot the error in this floating point code

by Jentje Goslinga <spamtrap@[EMAIL PROTECTED] > Apr 18, 2008 at 07:08 PM

Bin Xin wrote:
> On Apr 17, 9:25 pm, Jentje Goslinga  <spamt...@[EMAIL PROTECTED]
> wrote:
>> Bin Xin wrote:
>>> On Mar 19, 9:02 am, Terje Mathisen  <spamt...@[EMAIL PROTECTED]
> wrote:
>>>> Tim Roberts wrote:
>>>>> I admit that I lost track part way through, but it looks to me like
you
>>>>> aren't cleaning up thefloatingpointstack when you are done.  If you
>>>>> leave stuff on the stack, sooner or later the stack will overflow
(there
>>>>> are only 8 entries, after all), which
triggersfloatingpointexceptions.
>>>> The easy way to check this is to call your my_pow() function in a
loop,
>>>> preferably while inside the debugger, and watch the x87 stack
contents.
>>> Thanks for replying.
>>> So I try to follow the stack state after each call to my_pow,  it
>>> looks ok for a few calls (9), then I see a weird thing: when "fld1" is
>>> executed at somepoint, it loads a "nan" instead of "1" into st0:
>> As Terje says, check for FPU stack overflow.
>>
>> If you are using normal calling conventions (as enforced by
>> compilers), your FPU stack should be empty upon entering any
>> function, and upon exit should be either empty (I) or contain
>> a single entry (II), in the case where the function returns
>> afloatingpointnumber:
>>
>> void myfunc(...)    (I)
>>
>> double myfunc(...)  (II)
>>
>> To find out how many entries out off the available eight of the
>> FPU stack are used, inspect the FPU TAGS word with your debugger.
>> (NB: The TAGS word; NOT the FPU CONTROL OR STATUS word).
>> The TAGS word should read FFFF upon entry to the function (just
>> prior to the hardware call instruction) and upon exit should read
>> FFFF in case (I) and 3FFF in case (II), if I am not mistaken.
>> This is because the coding is from left to right and is 11 for an
>> empty register and 00 for a used register, so 3FFF means
>> 0011 1111 1111 1111
>> which means that the first FPU register "st0" is in use and
>> st1...st7 are empty. Note that some debuggers display garbage even
>> in empty registers, so do not rely on the debugger FPU stack display.
>>
>> This is as much as I know; I am not sure whether the used registers
>> should be contiguous, or what happens upon stack rotation, I haven't
>> investigated that.
> 
> Thanks, Jen.  This is informative.  Is there an existing tool that can
> check a piece of assembly code,  for registers not cleaned up?
> 
> bin
> 

There is no existing tool per se but the FPU STATUS word reflects
the results of FPU operations and it contains a stack overflow bit.

Let's start simple and create a FPU stack overflow

finit  ; initialize processor, setting control word to 0x0037
fldz
fldz
fldz
fldz
fldz
fldz
fldz
fldz
fldz   ; trying to load a ninth element on the stack

The finit instruction initializes the FPU and sets the CONTROL
WORD to 0x0037. This means that all exceptions except overflow
are "masked". Masked means that the corresponding bit is 1 and
not 0 which would be unmasked. If an exception is masked then
the processor "takes a default internal action" which means that
execution merrily continues... almost certainly infecting your
data with Inf's and Nan's; if an exception is unmasked, then a
software exception handler is called. I don't know how this works
and it may be later, possibly MUCH later. I would stay away from
OS generated interrupts.

The lower bits in the FPU CONTROL WORD are
0 invalid operation
1 denormalized operand
2 zerodivide
3 overflow
4 underflow
5 precision
6 RESERVED
7 interrupt enable, 8087 only
8-9 rounding control 00=nearest etc

The bits in the FPU STATUS WORD are
0 invalid operation
1 denormalized operand
2 zerodivide
3 overflow
4 underflow
5 precision
6 STACK FAULT
7 interrupt request 8087, otherwise error summary status
8-10,14 condition code bits

We are not concerned here with the higher bits which relate
to arithmetic condition codes, much like the flags on the CPU.
Note that bit 6 in the CONTROL WORD is reserved, obviously
because stack faults should never be masked, since they are
programmer errors, not the result of "unlucky data".

Stepping through this sequence of instructions with a debugger
shows that on the 9-th FPU load, the status word is set to
0x3A41 which equals 00111010 01000001 in binary.
                               ^     ^
[It also seems that st0 contains infinity].
The lower eight bits indicate that the "invalid operation"
and the "stack fault" bits are set, see table.
There are probably other conditions which generate an
"invalid operation", so we should concentrate on the "stack
fault" condition as reflected by the stack fault bit.

One way would be to write a function which tests the stack
fault bit something like:

int stack_fault()
{
__asm {
   fstsw     ax           ; FPU status word to ax
   and       eax, 0x0040  ; isolate the stack fault bit
   shr       eax, 6       ; ****ft to least significant
   };

   /* return code is in eax as per C convention */
   /* hope compiler accepts this; otherwise write */
   /* asm function */
}

I am using inline assembler for clarity, not recommending it
and hope I haven't made a mistake but you get the idea. I
have no time to test this right now, have to go to work.
[I hope you have at least a 386, otherwise you have to store
the FPU status word to memory (presumably a word on the CPU
stack) and from there move it to ax.]
Now you can call this test function following some suspect
test code to see if there was a stack fault.

One more thing: The FPU exception status codes are "sticky"
and will remain set until someone clears FPU exceptions using
FCLEX or resets the FPU with FINIT.

Jen
 




 9 Posts in Topic:
help spot the error in this floating point code
Bin Xin <spamtrap@[EM  2008-03-18 15:26:40 
Re: help spot the error in this floating point code
Tim Roberts <spamtrap  2008-03-19 05:13:52 
Re: help spot the error in this floating point code
Terje Mathisen <spamt  2008-03-19 14:02:16 
Re: help spot the error in this floating point code
nbaker2328 <spamtrap@[  2008-03-18 23:08:55 
Re: help spot the error in this floating point code
Bin Xin <spamtrap@[EM  2008-04-16 15:23:00 
Re: help spot the error in this floating point code
"Wolfgang Kern"  2008-04-17 13:28:18 
Re: help spot the error in this floating point code
Jentje Goslinga <spam  2008-04-17 18:25:15 
Re: help spot the error in this floating point code
Bin Xin <spamtrap@[EM  2008-04-18 13:47:00 
Re: help spot the error in this floating point code
Jentje Goslinga <spam  2008-04-18 19:08:18 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sun Jul 6 20:04:10 CDT 2008.