天天看點

王爽《彙編語言》第十章實驗之——除法溢出問題

昨天看王爽老師的《彙編語言》,卡在第十章“乘法溢出問題“的實驗上了。準确的說是卡在書中給出的那個公式上了,今天把代碼分步調試了一下,我的疑惑全解開了。

一. 公式:

王爽《彙編語言》第十章實驗之——除法溢出問題

二. 為了更好的說明這個公式,下面給出 "手動" 版的計算過程 (以書中的 (F4240H / 0AH) 為例)。

1.  int(H/N)*65536 

     即:   000FH / 000AH = 0001H 餘 0005H 

     是以:int(H/N) = 1H ,  rem(H/N) = 0005H

                 int(H/N)*65536 = 10000H

2.  [rem(H/N)*65536 + L] / N

    即:    0005H * 65536 = 50000H

                50000H + 4240H = 54240H

    是以:[rem(H/N)*65536 + L] / N = 54240H / 0AH = 86A0H 餘 0000H

3. 最終結果:

               10000H + 86A0H = 186A0H  且餘數為0

4. 分析:

    由以上三個步驟可以看出:

    第一步中:除法的商為最終結果的商的高16位  ( int(H/N)*65536 )。

    第二步中:上一步除法的餘數(作為高16位)和被除數的低16位(作為低16位)共同參與32位的除法運算,所得的商為最終結果的商的低16位,所得餘數為最終結果的餘數。

5. 具體子程式:

mov ax,4240H
       mov dx,000FH
       mov cx,0AH
           
divdw:push bx
       push ax         ;将被除數的低16位入棧
       mov ax,dx       ;将被除數的高16位存入ax
       mov dx,0        
       div cx          ;即0000 000FH / 000AH,完成後ax為0001H, dx為0005H
       mov bx,ax       ;将上面除法結果的商存入bx
       pop ax          ;将被除數的低16位出棧,存入ax
       div cx          ;即54240H / 0AH,完成後ax860AH ,dx為0000H
       mov cx,dx       ;将餘數存入cx
       mov dx,bx       ;将結果的商的高16為存入dx
       pop bx           
       ret
           

Ps:

     1. 網上給出的答案給人的感覺好像是并沒有按照這個公式進行計算,但最終的答案是正确的。後來經過在Debug下單步執行,才發現問題所在。

     2. 有人說這就是王爽老師沒有給這本書配習題解答的原因就是希望讀者能夠獨立思考問題,然後通過一步步的調試最終能寫出正确的程式,真是用心良苦啊!

     3. 如果程式跑不起來或者跑起來有問題,最好先一步一步調試一遍,而不是直接去尋求“正确”答案。

繼續閱讀