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.
-
-