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
相关产品推荐
相关产品推荐

