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: