主题:error 200 division by zero 问题 急!
绿儿
[专家分:0] 发布于 2005-02-28 10:13:00
我有个程序用到crt单元,出现上面的错误,什么原因呢?
有人说是因为需要补丁,请问哪里下载补丁啊?很急,希望大家帮帮忙。谢谢
回复列表 (共6个回复)
沙发
jtchang [专家分:5370] 发布于 2005-02-28 21:57:00
看看下面的文章:
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]
板凳
绿儿 [专家分:0] 发布于 2005-03-02 13:11:00
我按照你的说法下载了crt补丁,可是还是不行啊
3 楼
jtchang [专家分:5370] 发布于 2005-03-02 20:20:00
是你不会弄吧?再给你弄简单一点:
如果你用的是Turno Pascal 7.0 ,
下载:
http://jtchang.51.net/data/tp7tpl.zip
把这个ZIP里的Turbo.tpl这个文件,覆盖掉你盘上的同名文件!重新启动TP7即可。
4 楼
jtchang [专家分:5370] 发布于 2005-03-02 20:20:00
是你不会弄吧?再给你弄简单一点:
如果你用的是Turno Pascal 7.0 ,
下载:
http://jtchang.51.net/data/tp7tpl.zip
把这个ZIP里的Turbo.tpl这个文件,覆盖掉你盘上的同名文件!重新启动TP7即可。
5 楼
nicknumen [专家分:0] 发布于 2005-11-22 21:34:00
解释的很详细
很好
对我的帮助很大
6 楼
onasp [专家分:5600] 发布于 2005-11-26 09:04:00
我记得有一次,我的函数没有返回值,也出现了这个问题。
我没有进dos,没看清是20几。楼主还是先看看自己的程序是不是有问题吧。
我来回复