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

使用MASM615汇编x86代码时playlevel1宏报错求助

MASM6.15汇编playlevel1宏错误修复方案

问题背景

以下是糖果消消乐游戏库文件中的playlevel1宏代码,使用MASM6.15汇编时仅该宏报错:

playlevel1 macro
mov ax,01
int 33h
 mov si,15
 .repeat
    mov ah,05
    int 33h
    mov ax,0
    
    .if bx==0
        mov clickedatx,cx
        mov clickedaty,dx
        add ax,1
    .endif
    .if bx==0 && ax==1
        .if cx+60 == clickedatx || cx-60 == clickedatx || dx+60 == clickedaty || dx-60 == clickedaty
            clicked_Candy
            print_a_shape 0,clickedatx,clickedatx
            mov clickedatx,cx
            mov clickedaty,dx
            clicked_Candy
            print_a_shape 0,clickedatx,clickedatx
            add score,5
        .endif
    .endif  
mov bx,1
 .until si==0
endm

错误分析与修复方案

1. 循环逻辑死循环

代码中.repeat/.until依赖si==0终止循环,但全程未修改si的值(初始为15),会导致无限循环,MASM会报循环条件无法满足的错误。
修复:在循环体末尾添加dec si,让si逐次递减到0。

2. int 33h功能调用参数缺失

int 33h功能05(获取鼠标按键状态)需要提前在bx中指定要检查的按键(0=左键,1=右键),原代码调用前未设置bx,导致返回的bx值不可靠,触发错误的条件判断。
修复:调用int 33h前添加mov bx,0指定检查左键。

3. MASM6.15不支持条件内直接算术运算

早期MASM版本(如6.15)不允许在.if条件中直接使用cx+60这类算术表达式,必须先将计算结果存入寄存器再比较。
修复:将偏移量计算放到寄存器中,再做相等判断。

4. 寄存器未保存/恢复

宏直接使用ax、bx、cx、dx、si等寄存器,会破坏调用者的寄存器状态,可能引发编译警告或运行时逻辑错误。
修复:在宏开头用push保存寄存器,结尾用pop恢复。

5. 明显的参数错误

print_a_shape的参数重复传入clickedatx,应该是clickedatx(x坐标)和clickedaty(y坐标),属于逻辑错误。
修复:修正参数为print_a_shape 0, clickedatx, clickedaty。

修复后的完整代码

playlevel1 macro
    ; 保存调用者寄存器环境
    push ax bx cx dx si
    mov ax,01h
    int 33h         ; 初始化鼠标驱动
    mov si,15       ; 循环计数器初始值
    
.repeat
    mov bx,0        ; 指定检查鼠标左键
    mov ah,05h
    int 33h         ; 获取鼠标按键状态
    mov ax,0
    
    .if bx == 0     ; 左键被按下
        mov clickedatx,cx
        mov clickedaty,dx
        add ax,1
    .endif
    
    .if bx == 0 && ax == 1
        ; 计算cx+60并比较
        mov ax,cx
        add ax,60
        .if ax == clickedatx
            jmp @adjacent_match
        .endif
        ; 计算cx-60并比较
        mov ax,cx
        sub ax,60
        .if ax == clickedatx
            jmp @adjacent_match
        .endif
        ; 计算dx+60并比较
        mov ax,dx
        add ax,60
        .if ax == clickedaty
            jmp @adjacent_match
        .endif
        ; 计算dx-60并比较
        mov ax,dx
        sub ax,60
        .if ax == clickedaty
@adjacent_match:
            clicked_Candy
            print_a_shape 0, clickedatx, clickedaty
            mov clickedatx,cx
            mov clickedaty,dx
            clicked_Candy
            print_a_shape 0, clickedatx, clickedaty
            add score,5
        .endif
    .endif  
    
    dec si          ; 递减计数器,让循环能正常终止
.until si == 0

    ; 恢复调用者寄存器环境
    pop si dx cx bx ax
endm

内容的提问来源于stack exchange,提问作者i227435 Muhammad Irsam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:33:29