回 帖 发 新 帖 刷新版面

主题:error 200 division by zero 问题 急!

我有个程序用到crt单元,出现上面的错误,什么原因呢?
有人说是因为需要补丁,请问哪里下载补丁啊?很急,希望大家帮帮忙。谢谢

回复列表 (共6个回复)

沙发

看看下面的文章:
http://jtchang.51.net/data/crtbug.htm
回答了你的所有问题。

我最早发表在这个论坛。贴了不止一次,就是希望更多的人知道这个bug.
----------------------------

TP7提供的CRT单元,有很多有用的函数。但是如果你没有打CRT补丁的话我不保证你的程序能够正确运行。测试你的TP7是否需要打补丁,用下面三行程序就够了:

uses crt;
begin
end.

如果运行时出现下面的错误提示而中止程序,就说明你引用CRT单元需要打补丁:

Error 200: Division by zero。

本义是:运行时出错,错误代码200:除零溢出。

这个问题在主频大约高于233 MHZ的CPU上都会存在。(现在都多少G了啊老兄,还M?)

太冤了吧?什么都没有做,除什么零?(^_^)

以前就有朋友问我:为什么我在486,586的机器上运行时,不会出现这个错误,现在更先进的机器上,却会出现这个错误?以前不会除零,现在说除零。既然是“除零”,那么到底谁在“除零”?

事实上,真正出错的原因并不是“除零溢出”,而是“除法溢出”。翻翻汇编语言的div指令:

DIV scr (AL) <- (AX)/(scr) 的商 8位reg
        (AH) <- (AX)/(scr)的余数 8位mem

        (AX) <- (DX,AX) /(scr)的商 16位reg
        (DX) <- (DX,AX)/(scr)的余数 16位mem

这是16位机器上的除法汇编指令。简单地说,如果使用第一条,一个16位数,除以一个8位数,那么商和余数都不能超过8位,否则CPU就会产生一个“除法溢出”的标志。同理,一个32位数除以一个16位数,商和余数不能超过16位。

我们作个测试:用第一条,333h / 33h

program test;
var
   a,b: byte;

begin
  asm
      mov ax, $333
      mov cx, $33
      div cl
      mov a, al
      mov b, ah
   end;
   writeln($333,'/',$33,' = ',a,'...',b);
end.

结果对了,819除以51,商为16余数为3。那么,333h/3h呢?商超过8位,就出问题了:

program test;
var
    a,b: byte;
begin
   asm
       mov ax, $333
       mov cx, $3
       div cl
       mov a, al
       mov b, ah
    end;
    writeln($333,'/',$3,' = ',a,'...',b);
end.

这个程序运行时出错,提示是:Error 200: Division by zero.(说我除零,尽管我根本就没有除零。)用windows 98 的debug就可以正确反映出错原因:

C:>debug
-a
128B:0100 mov ax,333
128B:0103 mov cx,3
128B:0106 div cl
128B:0108 ret
128B:0109
-g

Your program caused a divide overflow error.
If the problem persists, contact your program vendor.

(你的程序造成“除法溢出”错误。如果问题仍然存在请联系你程序的开发商。)

(晕!搞笑!叫我自己联系自己?)

我这个程序,是引用DIV指令的第一条规则时出现在了溢出的问题。而TP7的CRT产生的BUG是在引用第二条规则上出了问题。罪魁祸首就是在为了实现delay过程上。

delay(n); 程序暂停n毫秒。

想让程序停住还不简单?打循环啦!可是,各人的计算机速度不一样,打循环的次数自然也不一样。怎样使得在不同的机器上运行都能实现刚刚好1毫秒?

BOIS的系统时钟,一秒钟会产生18.2次定时器中断。这样相邻两次中断之间的间格大约是55毫秒。CRT单元初始化时,会先清零一个32位计数器,然后利用一个很短的时间,在一次定时器中断到来时,开始计数;在下一次中断到来时,停止计数。假设计数器计得N次循环,那么,N/55就是停留1毫秒需要打多少次循环。

可是没想到现在的计算机跑得太快了,N计出一个很大的数字。当这个数字除以55时,商还是超过了16位。于是,CPU便发出一个“除法溢出错误”。TP7系统在收到这一个除法错误后,理解成为用户“除零错误”,便发出除零错误提示并中止程序。

事实上,这个错误是TP7系统造成的而不是用户;而TP7系统也没有去除零,它除的是55。

(^_^)


相关链接:

[url=http://jtchang.51.net/data/t7tplfix.zip]Turbo pascal 7.0 & Borland pascal 7.0,7.01 CRT 补丁下载[/url]

板凳

我按照你的说法下载了crt补丁,可是还是不行啊

3 楼

是你不会弄吧?再给你弄简单一点:

如果你用的是Turno Pascal 7.0 ,

下载:
http://jtchang.51.net/data/tp7tpl.zip

把这个ZIP里的Turbo.tpl这个文件,覆盖掉你盘上的同名文件!重新启动TP7即可。

4 楼

是你不会弄吧?再给你弄简单一点:

如果你用的是Turno Pascal 7.0 ,

下载:
http://jtchang.51.net/data/tp7tpl.zip

把这个ZIP里的Turbo.tpl这个文件,覆盖掉你盘上的同名文件!重新启动TP7即可。

5 楼

解释的很详细
很好
对我的帮助很大

6 楼

我记得有一次,我的函数没有返回值,也出现了这个问题。
我没有进dos,没看清是20几。楼主还是先看看自己的程序是不是有问题吧。

我来回复

您尚未登录,请登录后再回复。点此登录或注册