home *** CD-ROM | disk | FTP | other *** search
- ***** BUG REPORT *****
- ***** MAJOR BUG IN TURBO PASCAL V2.00 *****
- July 1,1984
-
-
- The runtime routines do not handle a floating-point
- (real) subtraction correctly. For some subtractions, the
- correct difference is returned; for others, a zero is
- returned. The following program demonstrates the bug:
-
- program test;
- begin
- writeln(9.+(-6.0)); { Wrong value returned }
- writeln(-1.0+(-1.0)); { Correct value returned }
- writeln(1-2); { Correct value returned }
- writeln(1.-2:10:2); { Wrong value returned }
- writeln(1.-2.0); { Wrong value returned }
- writeln(1-2.0); { Wrong value returned }
- writeln(456 - 123.0); { Correct value returned }
- end.
-
- A value of zero is returned on those lines marked as 'wrong'.
- The other lines return the correct difference.
-
-
- THE CAUSE
-
- After disassembling and tracing through a sample compiled
- program, the error was located in the following code:
-
- XXXX:12FA E84FFF CALL 124C ; Subtract
- XXXX:12FD 7306 JNB 1305
- XXXX:12FF 80F780 XOR BH,80 ; Handle negative
- XXXX:1302 E863FF CALL 1268 ; numbers
- XXXX:1305 8B4504 MOV AX,[DI+04] ; Is mantissa zero?
- XXXX:1308 0B4502 OR AX,[DI+02]
- XXXX:130B 0A4501 OR AL,[DI+01] ; ***** ERROR *****
- XXXX:130E 740D JZ 131D ; Yes
- XXXX:1310 F6450580 TEST BYTE PTR [DI+05],80 ; Normalize
- XXXX:1314 750C JNZ 1322
-
- (Comments have been added for clarity). This disassembled
- code is located in the routines that handle addition and
- subtraction (only the subtraction part is shown). The error
- occurs when the routine tests to see if the result of the
- subtraction is zero. It tests for a zero by "OR-ing" together
- the five bytes of the mantissa (the instructions that do this
- are at offsets 1305H to 130BH). If the mantissa is zero, then
- the result of this "multiple-or" will set the zero flag. The
- first of these instructions is a move of the word at [DI+4]
- to AX. The next instruction takes the logical OR of AX and
- [DI+2]. No problem so far. However, the last instruction is
- "OR AL,[DI+1]", an instruction that operates on a byte and
- not on a word. If the OR of the words at [DI+4] and [DI+2]
- results in a word whose UPPER byte is NONZERO but whose LOWER
- byte is ZERO, then the next instruction, the "byte-wise" OR,
- will SET the zero flag if the byte at [DI+1] is zero. Notice
- that the instruction at 130BH totally ignores the contents of
- the upper byte of AX; the flags are set according to the
- lower byte of AX only. This is what causes the error.
-
-
- THE FIX
-
- The fix to this bug is simple: simply exchange the order
- of the two "OR" instructions. This way, the zero flag is set
- according to a full 16-bit OR and not an 8-bit one.
- IMPORTANT: Only persons familiar with the operation of DEBUG
- should attempt the following. Using DEBUG, the following
- sequence of commands can be used to fix the bug:
-
- Assumptions and notes in the following:
- 1) ONLY WORK ON A COPY OF TURBO! DO NOT USE
- YOUR MASTER COPY!
- 2) The sequence of commands shown below writes
- out the fixed version to the file
- 'turbo.com'
- 3) Make sure that you have version 2.00
- 4) 'turbo.com' must be in the current
- directory on drive B.
- 5) DOS 2.00 or above is being used (the
- debugger in DOS 1.00 and 1.10 does not have
- the 'assemble' command).
- 6) Be sure to verify that the code in the
- compiler is the same as that shown below
- initially. After the changes are made, be
- sure to verify that the changes have been
- made correctly before writing the fixed
- version out to disk.
-
- B>debug turbo.com
- -u 12fa <- Verify the following locations
- XXXX:12FA E84FFF CALL 124C
- XXXX:12FD 7306 JNB 1305
- XXXX:12FF 80F780 XOR BH,80
- XXXX:1302 E863FF CALL 1268
- XXXX:1305 8B4504 MOV AX,[DI+04]
- XXXX:1308 0B4502 OR AX,[DI+02]
- XXXX:130B 0A4501 OR AL,[DI+01]
- XXXX:130E 740D JZ 131D
- XXXX:1310 F6450580 TEST BYTE PTR [DI+05],80
- XXXX:1314 750C JNZ 1322
- XXXX:1316 E8F9FE CALL 1212
- XXXX:1319 FE0D DEC BYTE PTR [DI]
- -a 1308 <- Make changes
- XXXX:1308 or al,[di+1]
- XXXX:130E or ax,[di+2]
- XXXX:1311 <- Press 'enter'
- -u 12fa <- Verify that the changes are correct
- XXXX:12FA E84FFF CALL 124C
- XXXX:12FD 7306 JNB 1305
- XXXX:12FF 80F780 XOR BH,80
- XXXX:1302 E863FF CALL 1268
- XXXX:1305 8B4504 MOV AX,[DI+04]
- XXXX:1308 0A4501 OR AL,[DI+01]
- XXXX:130B 0B4502 OR AX,[DI+02]
- XXXX:130E 740D JZ 131D
- XXXX:1310 F6450580 TEST BYTE PTR [DI+05],80
- XXXX:1314 750C JNZ 1322
- XXXX:1316 E8F9FE CALL 1212
- XXXX:1319 FE0D DEC BYTE PTR [DI]
- -w <- Save fixed version of turbo
- Writing 8E80 bytes
- -q
-
- B>
-
- <end of fix>
-
-
- OTHER NOTES ABOUT TURBO
-
- One cannot set breakpoints in TURBO using DEBUG. It
- seems that TURBO uses the breakpoint interrupt for some
- hideous reason. If one attempts to set breakpoints, the
- system will probably crash. Tracing, however, does seem to
- work. The above bug was tracked down only after hours of
- tracing (by maching and by hand) and disassembling.
-
-
- Additional remarks from CompuServe:
-
-
- #: 17310 Sec. 4 - High-Level Langs.
- Sb: #Turbo Pascal
- 04-Sep-84 20:50:42
- Fm: Borland International 71016,1573
- To: David J. Jones 72345,357
-
- The bug in version 2.00a did not occur in the cp/m 80
- version. Under MS DOS real # subtraction which should have produced a negative
- result always produced a zero for a result. People with this bug can get a
- return authorization number from us and we will swap their master disk for a
- ver. 2.00B. Operating under cp/m 80, your version 2.00A is the current version
- so you don't need a replacement.
- We don't yet know whether or not the C or the Modula 2 compiler will run under
- cp/m 80.
-
- #: 17317 Sec. 4 - High-Level Langs.
- Sb: Turbo Pascal 2.00
- 04-Sep-84 22:05:26
- Fm: Borland International 71016,1573
- To: Bill McArthur 75226,3142
-
- Sounds like you got the IBM version. If the label reads "MS DOS IBM PC then it
- is definitely the IBM PC version. You can call ((408) 438-8400) or write
- (address on cover of reference manual). You will then be given a return
- authorization number and we will arrange to swap your master disk for a generic
- MS DOS Turbo.
-
- And a test program:
-
- program turbotest;
-
- {by Larry Weiss, Garland, Tx}
-
- {There apparently was an early release of Turbo Pascal 2.0 for the IBM PC
- that had a flaw in the code generated to handle real arithmetic. Here
- is some information that can help owners determine if they need to patch
- or replace their copy. My copy is apparently OK (I have version 2.00B),
- so I have not had the opportunity to test a bad copy.}
-
- { From "Journal of Pascal,Ada & Modula-2" July-August 1984 (reader's forum)
- "Owners of an IBM PC who have bought a copy of Turbo Pascal should be aware
- of a serious bug in the "reals" arithmetic in some versions of Turbo Pascal.
- To see if your copy has this bug, run the following program. In the correct
- versions the value of C will be 1.0 until the value of A is (2.0)^40. The
- incorrect versions get C=0.0 when A=(2.0)^16."}
-
- var a,b,c :real; i:integer;
- begin a:=2.0; b:=a+1.0; c:=b-a;i:=1;
- repeat i:=i+1; a:=2.0*a; b:=a+1.0; c:=b-a until c<>1.0;
- if i>=40 then writeln('Good version of Turbo Pascal') else
- writeln('Bad version of Turbo Pascal');
- writeln('i=',I:2);
-
- end.
- 40 then writeln('Good version of Turbo