1 回答

TA貢獻1786條經驗 獲得超11個贊
這個問題是其他部門相關失敗的變種。該x86
標簽的wiki有一些額外的鏈接:
idiv
/div
問題: 首先為零edx
,或者對其進行符號擴展eax
。。div
如果64b / 32b => 32b商實際上不適合32b,則為32位故障。
您的調試器似乎跳轉到的明顯隨機代碼是Arithmetic Exception處理程序(也與Divide by Zero相同)。發生的事情是你的代碼正在經歷一個Division Overflow
。你正在做一個16位/ 8位IDIV。從文檔:
符號除以AX / r8,結果存儲在:AL←商,AH←余數。
您會注意到,對于具有8位除數的除法(在您的情況下為BL),商的范圍是-128到+127。044c0h IDIV85是207(十進制)。207不適合帶符號的8位寄存器,因此會出現除法溢出和導致意外問題的原因。
要解決此問題,您可以升級到16位除數。因此,您可以將除數放在BX(16位寄存器)中。那就是mov bx, 85
。不幸的是,它并非如此簡單。當使用16位除數時,處理器假設被除數為32位,DX中為高16 位,AX中為低16位。
有符號劃分DX:AX乘以r / m16,結果存儲在AX←商,DX←剩余。
要解決此問題,您必須簽署擴展AX中的16位值。這很簡單,因為您只需在將值放入AX后使用CWD指令。從指令集引用
DX:AX←AX的符號擴展。
實際上,如果AX的最高有效位(MSB)為0,則DX將變為0.如果MSB為1,則DX將變為0ffffh(所有位設置為1)。數字的符號位是MSB。
考慮到所有這些,您的分區代碼可以調整為采用16位除數:
mov ax, 044c0h
cwd ; Sign extend AX into DX (DX:AX = 32-bit dividend)
mov bx, 85 ; Divisor is 85
idiv bx ; Signed divide of DX:AX by BX
添加回答
舉報