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

MASM汇编骰子游戏异常排查:胜负判定错误及崩溃问题

问题排查与修复方案

核心问题分析

你的代码出现胜负判定错误(如玩家1点、电脑5点却显示"You Win!"),大概率是寄存器被意外修改导致的。虽然DOS中断int 21h的09h功能理论上会保留bx寄存器,但部分DOS兼容环境或汇编器可能存在异常,导致存储在bl、bh中的点数被意外篡改,进而让比较逻辑失效。

另外,随机数生成部分存在小瑕疵:使用16位除法div bx时,余数存储在16位寄存器dx中,虽然当前逻辑(取dl)能得到正确的0-5余数,但可以优化为更简洁的8位除法,避免潜在的寄存器混淆。

修复后的完整代码

.model small
.stack 100h

.data
    msg_sep    db 13,10,'----------------------',13,10,'$'
    msg1       db 13,10,'Your roll: $'
    msg2       db 13,10,'Computer roll: $'
    msg_win    db 13,10,'You Win!$'
    msg_lose   db 13,10,'You Lose!$'
    msg_draw   db 13,10,'Draw!$'
    ; 使用内存变量存储点数,避免寄存器被篡改
    user_roll  db ?
    comp_roll  db ?

.code
start:
    mov ax, @data
    mov ds, ax

loop_start:
    ; 输出分隔线
    lea dx, msg_sep
    mov ah, 09h
    int 21h

    ; 生成玩家点数
    call get_random
    mov user_roll, dl  ; 存储到内存变量
    lea dx, msg1
    mov ah, 09h
    int 21h
    mov dl, user_roll
    add dl, '0'
    mov ah, 02h
    int 21h

    ; 生成电脑点数
    call get_random
    mov comp_roll, dl  ; 存储到内存变量
    lea dx, msg2
    mov ah, 09h
    int 21h
    mov dl, comp_roll
    add dl, '0'
    mov ah, 02h
    int 21h

    ; 胜负判定(使用内存变量比较,不受寄存器修改影响)
    mov al, user_roll
    cmp al, comp_roll
    je  draw
    jb  user_lose
    ja  user_win

user_win:
    lea dx, msg_win
    mov ah, 09h
    int 21h
    jmp wait_key

user_lose:
    lea dx, msg_lose
    mov ah, 09h
    int 21h
    jmp wait_key

draw:
    lea dx, msg_draw
    mov ah, 09h
    int 21h
    jmp wait_key   
    
wait_key:
    mov ah, 08h    ; 无回显读取键盘输入
    int 21h
    jmp loop_start

; 优化后的随机数生成函数(8位除法,逻辑更简洁)
get_random:
    mov ah, 00h
    int 1Ah        ; 获取系统计时器:CX=高16位,DX=低16位
    mov al, dl     ; 取计时器低8位作为随机源
    xor ah, ah     ; 将AL扩展为16位AX(AH清零)
    mov bl, 6
    div bl         ; 8位除法:AX / BL,余数存AH(0-5),商存AL
    mov dl, ah
    add dl, 1      ; 转换为1-6的点数
    ret

end start

关键修复点

  1. 用内存变量存储点数:将原代码中存储在bl、bh的点数改为存储到user_roll、comp_roll内存变量中,彻底避免寄存器被意外修改导致的比较错误。
  2. 优化随机数生成:改用8位除法div bl,逻辑更清晰,减少16位寄存器操作带来的潜在问题。
  3. 保持原有功能不变:保留了原程序的所有交互逻辑,仅修复核心问题。

崩溃问题说明

程序崩溃大概率是由于寄存器异常修改导致的内存访问错误,修复上述问题后,崩溃情况应该会消失。如果仍出现崩溃,可检查DOS环境的兼容性,或尝试增大栈空间(将.stack 100h改为.stack 200h)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:52:02