CPU执行除法指令的时候,是可能溢出的,这教材上写得很清楚。
要是被除数太大,或者除数太小,商就可能超出位数限制,这时候就会溢出。
特别是除数为0的时候,肯定报错:Divide overflow。
除法溢出这问题很严重,一旦发生系统就直接崩了。
(补码加减也会溢出,但不会让系统崩溃。)
王爽那本书里提了个不会溢出的编程思路,用来实现双字除以单字。
本来这个思路挺简单的,但他写得太乱了,根本看不懂。
比如字除法指令是DIV CX,CPU的操作就是把DX:AX整体除以CX,结果商放AX,余数放DX。
拿你举的例子来说:1000000 ÷ 10,也就是000F4240H ÷ 000A H。
如果用字除法来算,简单说就是先把高位字和低位字分别除以CX。
第一步:先用高位000F H ÷ 000A H,得到高位商是0001,余数是0005。
第二步:再用余数拼上低位,变成00054240H ÷ 000A H,得到低位商是86A0H,余数是0。
整个过程其实小学生都能看懂,就像小学列竖式那样:
(此处省略图示)
就这么个简单的操作,王爽非要搞得特别复杂:
他给的公式是:X/N = int(H/N)*65536 + L/N
其中:
X是被除数,范围是dword
N是除数,范围是word
H是X的高16位
L是X的低16位
int()表示取商
ram()表示取余数
功能是:做不会溢出的除法,输入是dword/word,输出也是dword
参数要求:
(AX)=被除数的低16位
(DX)=被除数的高16位
(CX)=除数
照你给的数据,程序应该这样写:
START:
要是被除数太大,或者除数太小,商就可能超出位数限制,这时候就会溢出。
特别是除数为0的时候,肯定报错:Divide overflow。
除法溢出这问题很严重,一旦发生系统就直接崩了。
(补码加减也会溢出,但不会让系统崩溃。)
王爽那本书里提了个不会溢出的编程思路,用来实现双字除以单字。
本来这个思路挺简单的,但他写得太乱了,根本看不懂。
比如字除法指令是DIV CX,CPU的操作就是把DX:AX整体除以CX,结果商放AX,余数放DX。
拿你举的例子来说:1000000 ÷ 10,也就是000F4240H ÷ 000A H。
如果用字除法来算,简单说就是先把高位字和低位字分别除以CX。
第一步:先用高位000F H ÷ 000A H,得到高位商是0001,余数是0005。
第二步:再用余数拼上低位,变成00054240H ÷ 000A H,得到低位商是86A0H,余数是0。
整个过程其实小学生都能看懂,就像小学列竖式那样:
(此处省略图示)
就这么个简单的操作,王爽非要搞得特别复杂:
他给的公式是:X/N = int(H/N)*65536 + L/N
其中:
X是被除数,范围是dword
N是除数,范围是word
H是X的高16位
L是X的低16位
int()表示取商
ram()表示取余数
功能是:做不会溢出的除法,输入是dword/word,输出也是dword
参数要求:
(AX)=被除数的低16位
(DX)=被除数的高16位
(CX)=除数
照你给的数据,程序应该这样写:
START: