本帖最后由 jackz007 于 2022-3-10 00:32 编辑 mov ax , 4444h
mov bl,1
div bl
这是 8 位除法,被除数是 ax,除数是 bl,执行过除法指令后,正常情况下,商将被保存到 al 寄存器中,余数将被保存到 ah 中。目前的情况是,被除数 ax = 4444h,除数 bl = 1,那么,商应该是 4444h,余数应该是 0,但是,作为商的 4444h 对于一个 8 位的寄存器而言,数值实在太大,显然无法保存到 al 寄存器中,这时,就会触发溢出中断,而我们的代码又没有事先接管这个中断,从而导致 CS:IP 指针指向一个非预期的内存地址,具体表现就是单步执行过 div bl 指令过后,CS:IP 会完全脱离当前代码位置,进入完全陌生的 CS:IP 位置,通常情况下,新的 CS:IP 所指向的并非有意义的汇编指令。所以,如果是已经编译过的程序当中有这个代码,那么,执行到这里的时候,就会立即死机。
解决问题的方法,一是减小 ax 值,如果 bl 必须是 1 的话,那么,ax 的值就不得超过 0ffh,如果 ax 必须是 4444h 的话,那么,就必须保证 bl 的值不得小于 44h。当然,换用 16 位除法就可以完美解决问题:xor dx , dx ; 被除数高 16 位清零
move ax , 4444h ; 被除数低 16 位
mov cx,1 ; 除数
div cx
执行过 div cx 指令后,商会保存到 ax 寄存器中,其值为 4444h,余数会保存到 dx 寄存器中,其数值为 0。这样,就完美地解决了除法溢出的问题。 |