You need to enable JavaScript to run this app. x86-16位ISA下16位DIV指令触发程序崩溃的原因分析
优惠活动
大模型
产品
解决方案
定价
更多

x86-16位ISA下16位DIV指令触发程序崩溃的原因分析

16位DIV指令崩溃问题排查

示例代码的溢出点定位

本次代码的崩溃是寄存器配置错误直接导致的,和你预期计算的10/2简单运算无关:
16位宽度的DIV指令,默认被除数是DX与AX拼接组成的32位无符号数——执行时会自动把DX的值作为被除数的高16位,AX的值作为被除数的低16位参与运算。
你的代码执行流程:

  • 给AX赋值10
  • 给DX赋值2
  • 执行div dx指令
    此时实际参与计算的被除数是 (DX << 16) + AX = (2 << 16) + 10 = 131082,除数是源操作数DX的值2,计算得到的商为65541。而AX寄存器仅能存储16位无符号数(最大范围0~65535),这个商已经超出AX的存储上限,直接触发除法溢出崩溃。

DIV指令的结果存储规则

16位操作数宽度的DIV执行完成后,结果确实拆分存储在DX和AX寄存器中,但分工是固定的:

  • AX 存放除法运算的商
  • DX 存放除法运算的余数
    不存在两个寄存器混合存储完整结果的逻辑。

DIV指令触发溢出异常的具体条件

满足以下任意一种情况,就会触发x86的0号除法错误中断,直接导致程序崩溃:

  • 除数的值为0,无有效运算意义
  • 无符号除法计算得到的商值,超过对应商寄存器的最大可表示范围:
    • 执行8位宽度DIV(r/m8)时,商存入AL寄存器,只要商值>255(8位无符号最大值)就触发异常
    • 执行16位宽度DIV(r/m16)时,商存入AX寄存器,只要商值>65535(16位无符号最大值)就触发异常
    • 执行32位宽度DIV(r/m32)时,商存入EAX寄存器,只要商值>4294967295(32位无符号最大值)就触发异常

修正提示:如果目标是计算10除以2的结果,需要在执行DIV前将作为被除数高位的DX寄存器清零(可用xor dx,dx实现),再把除数放到不涉及DX、AX的寄存器中(比如BX、CX)作为DIV的源操作数,避免污染被除数的高位段。

内容的提问来源于stack exchange,提问作者mattstack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 19:45:06