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
添加回答
举报