王爽老師的《匯編語言》在實驗10.2中提出了div
指令可能出現(xiàn)的除法溢出的問題负蠕。例如對于16位除以8位的情形敬惦,考慮被除數(shù)是0x1234,除數(shù)是0x01儡首。根據(jù)div
的約定蔬胯,商在AL中氛濒,余數(shù)在AH中迈勋。但是顯然計算結果的商是0x1234,8位的AL無法容納,因此會產(chǎn)生除法溢出馍惹。使用Bochs調(diào)試時,會在div
之后出現(xiàn)iret
窥突,即CPU產(chǎn)生了一個中斷返回指令努溃。
為了兼容32位對16位的除法硫嘶,設計一個雙字除法調(diào)用過程divdw:
- 輸入:
- 被除數(shù):一個32位的整數(shù)阻问,高16位在DX中,低16位在AX中
- 除數(shù):一個16位的整數(shù)沦疾,存儲在CX中
- 輸出:
- 商:32位的整數(shù)称近,高16位在DX中第队,低16位在AX中
- 余數(shù):16位整數(shù),儲存在CX中
因為商也是雙字長刨秆,因此divdw過程一定不會發(fā)生除法溢出凳谦。這是因為,考慮被除數(shù)最大是0xFFFFFFFF衡未,除數(shù)最小是0x0001尸执,則商最大為0xFFFFFFFF,不會超過雙字長缓醋。但是直接使用div
指令是無法辦到的如失,所以我們下面需要設計divdw的過程。首先給出一個數(shù)論中關于帶余數(shù)除法的引理:
(帶余數(shù)除法):設是兩個整數(shù)送粱,褪贵,則存在唯一的整數(shù)對,使得
我們接下來約定抗俄,符號表示實數(shù)除法脆丁,表示整數(shù)除法的商动雹,相當于上面的槽卫;表示整數(shù)除法的余數(shù)胰蝠,相當于上面的晒夹。例如,對于姊氓,我們有
現(xiàn)在來考慮雙字除法翔横。設被除數(shù)如下:如同我們可以把10進制數(shù)寫成读跷,16進制下的數(shù)可以寫為顯然和分別是寄存器DX
和AX
中的值。
現(xiàn)在設除數(shù)是禾唁,從而再次強調(diào)此時我們表示的是實數(shù)除法效览。根據(jù)整數(shù)帶余數(shù)除法引理,對于荡短,又存在唯一的如下表示其中丐枉,從而,于是因為是16位的掘托,因此除以的整數(shù)部分必然也不超過16位瘦锹。
對于括號中的部分,討論其取值范圍(設是正整數(shù))因為是16位整數(shù),故弯院,于是由此可知辱士,對其取整的結果:不超過16位。
現(xiàn)在听绳,令我們重新敘述結果:
換句話說
顯然是整數(shù)颂碘,并且。這是因為通過定義可知椅挣,是實數(shù)減去它的整數(shù)部分(即)头岔,因此結果就是該實數(shù)的小數(shù)部分,因此鼠证,從而切油,根據(jù)帶余數(shù)除法引理,這個余數(shù)是唯一的名惩。
因此我們有
因為均不超過16位澎胡,因此除法結果,商的高16位存儲在DX
中娩鹉,低16位存儲在AX
中攻谁,余數(shù)不能大于除數(shù),故而也可以安全存儲在CX
中弯予。