BUG: Incorrect Float/Double Value Returned in /AS or /AM Model

ID: Q115703

1.00 1.50 WINDOWS kbtool kbbuglist

The information in this article applies to:

SYMPTOMS

The value returned from a DLL function to the application which called it is incorrect. This occurs with functions that return either a double or a float, if either small memory model (/AS) or medium memory model (/AM) is used.

If the .EXE is large model (/AL), the correct code is generated.

CAUSE

The code generated incorrectly assumes that _fac, the location where a pointer to the float return value is stored, is near in the small and medium memory models. This causes the wrong value to be returned, since the data segment assumed for _fac is incorrect.

RESOLUTION

In order to work around the problem, compile the .EXE using the large memory model, rather than the medium or small memory models.

STATUS

Microsoft has confirmed this to be a problem in the C/C++ compiler for MS- DOS, versions 8.0 and 8.0c. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

For example, suppose a large model DLL exports the following function:

   double __export mul( double x, double y )
   {
      double z;
      z = x * y;
      return z;
   }

The compiler incorrectly generates the following code for a call to mul() in a small or medium model Windows-based application:

;|***     y = mul( x, z );             /* call to mul() */ 
; Line 104
     *** 00016e     ff 76 ec           push     WORD PTR [bp-20]
     *** 000171     ff 76 ea           push     WORD PTR [bp-22]
     *** 000174     ff 76 e8           push     WORD PTR [bp-24]
     *** 000177     ff 76 e6           push     WORD PTR
 [bp-26]     ;z
     *** 00017a     ff 76 fc           push     WORD PTR [bp-4]
     *** 00017d     ff 76 fa           push     WORD PTR [bp-6]
     *** 000180     ff 76 f8           push     WORD PTR [bp-8]
     *** 000183     ff 76 f6           push     WORD PTR
 [bp-10]     ;x
     *** 000186     9a 00 00 00 00     call     FAR PTR _mul
     *** 00018b     83 c4 10           add      sp,16     ;0010H
     *** 00018e     8d 7e ee           lea      di,WORD PTR
 [bp-18]     ;y
     *** 000191     8b f0              mov      si,ax     //only ax
 is moved
     *** 000193     16                 push     ss
     *** 000194     07                 pop      es
     *** 000195     a5                 movsw
     *** 000196     a5                 movsw
     *** 000197     a5                 movsw
     *** 000198     a5                 movsw

If large model is used, the following code is correctly generated:

;|***     y = mul( x, z );          /* call to mul() */ 
; Line 104
     *** 000178     ff 76 e4           push     WORD PTR [bp-28]
     *** 00017b     ff 76 e2           push     WORD PTR [bp-30]
     *** 00017e     ff 76 e0           push     WORD PTR [bp-32]
     *** 000181     ff 76 de           push     WORD PTR
 [bp-34]     ;z
     *** 000184     ff 76 f4           push     WORD PTR [bp-12]
     *** 000187     ff 76 f2           push     WORD PTR [bp-14]
     *** 00018a     ff 76 f0           push     WORD PTR [bp-16]
     *** 00018d     ff 76 ee           push     WORD PTR
 [bp-18]     ;x
     *** 000190     9a 00 00 00 00     call     FAR PTR _mul
     *** 000195     83 c4 10           add      sp,16     ;0010H
     *** 000198     1e                 push     ds
     *** 000199     8d 7e e6           lea      di,WORD PTR
 [bp-26]     ;y
     *** 00019c     8b f0              mov      si,ax
     *** 00019e     16                 push     ss
     *** 00019f     07                 pop      es
     *** 0001a0     8e da              mov      ds,dx  // the value
 of dx
     ASSUME DS: NOTHING         // is moved into ds
     *** 0001a2     a5                 movsw
     *** 0001a3     a5                 movsw
     *** 0001a4     a5                 movsw
     *** 0001a5     a5                 movsw
     *** 0001a6     1f                 pop      ds
     ASSUME DS: DGROUP

Additional reference words: 1.00 1.50 8.00 8.00c floating point error KBCategory: kbtool kbbuglist KBSubcategory: CodeGen Keywords : kb16bitonly

Last Reviewed: July 23, 1997