You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

68k汇编中V标志置位但N、Z标志清零时BGT指令的问题

68k汇编二次方程判别式判断的溢出问题解决

问题本质

你碰到的核心问题是16位有符号数运算溢出导致标志位异常:

  • 变量b的值是9999,计算b²时结果为99980001,这远超出16位有符号数的最大值32767。
  • 虽然mulu.w指令会生成32位的乘积结果,但你后续用sub.w只对低16位做减法,完全丢弃了高16位的有效数据,导致减法运算触发溢出(V标志置位),而bgt指令的分支逻辑无法识别这种溢出后的正结果,因此出现“实际判别式为正但不分支”的矛盾情况。

修正方案:改用32位运算

既然判别式的计算结果大概率超出16位范围,直接用32位指令处理所有中间步骤,确保标志位能正确反映运算结果:

ORG $8000          
a dc.w 4000        
b dc.w 9999        
c dc.w 1000        
d dc.b 0           

START:
      clr.b d3     
      move.l #0,d0  ; 初始化d0为32位0
      move.w a,d0   ; 将a载入d0的低16位,高16位保持0
      move.l #0,d1  
      move.w b,d1   ; 将b载入d1的低16位
      move.l #0,d2  
      move.w c,d2   ; 将c载入d2的低16位
      
      ; 计算判别式b² - 4ac
      mulu.l d1,d1  ; d1 = b²(32位完整结果)
      
      mulu.l d2,d0  ; d0 = a * c(32位结果)
      mulu.l #4,d0  ; d0 = 4ac(32位结果)
      
      sub.l d0,d1   ; d1 = b² - 4ac(32位减法,正确更新标志位)
      
      ; 判断判别式是否大于0
      bgt VALID     ; 此时标志位正确,bgt会正确分支
      
      move.b d3,d   
      bra END       

VALID:
    addq.b #1,d    
    bra END        

END:
    SIMHALT        
    END     START

关键细节解释

  • 68k的mulu.w是16×16→32位乘法,结果会把目标寄存器扩展为32位,但如果后续用sub.w操作,只会取低16位计算,完全丢失高16位的有效数据,这是你之前代码的核心错误。
  • 改用sub.l做32位减法后,标志位会准确反映32位有符号数的运算状态:当判别式为正时,Z(零标志)、N(负标志)、V(溢出标志)都会清零,完美符合bgt的分支条件(Z=0且N=V),此时bgt会正确跳转到VALID分支。
  • 另外你代码里的注释有笔误(jump to VALIDS),修正后更严谨。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:44:55