Assembly 汇编-cmp指令始终通过

Assembly 汇编-cmp指令始终通过,assembly,x86-16,tasm,Assembly,X86 16,Tasm,我正在做一个Tic Tac Toe游戏,当我做这个功能来检查一个玩家是否赢了。 出于测试目的,我让程序在玩家获胜时退出。 只是为了开始,我让程序只检查第一行: 0,0,0==>此行 0,0,0 0,0,0 我遇到一个问题,即每当我将一个位置更改为X或O时,程序都存在,除了当我选择程序检查的一个位置时(因此,如果我选择第一行中的任何位置)。 函数的代码在末尾 我不想包含整个代码,因为我不仅仅是在屏幕上打印,而是在图形模式下绘制(ah=13h int 10h) 我将向您展示主循环和checkIfWo

我正在做一个Tic Tac Toe游戏,当我做这个功能来检查一个玩家是否赢了。 出于测试目的,我让程序在玩家获胜时退出。 只是为了开始,我让程序只检查第一行:

0,0,0==>此行
0,0,0
0,0,0

我遇到一个问题,即每当我将一个位置更改为X或O时,程序都存在,除了当我选择程序检查的一个位置时(因此,如果我选择第一行中的任何位置)。
函数的代码在末尾

我不想包含整个代码,因为我不仅仅是在屏幕上打印,而是在图形模式下绘制(ah=13h int 10h) 我将向您展示主循环和checkIfWon函数,我只过滤了重要的内容。 代码如下: 董事会定义:

.data
配电盘db 0,0,0
分贝0,0,0
分贝0,0,0
CheckIfWon函数:

checkIfWon proc
    ; check rows
    ; Equal to: if (board[0] == board[1] && board[1] == board[2])
    movsx   eax, byte ptr [board]
    movsx   ecx, byte ptr [board+1]
    cmp     eax, ecx
    jne     cont

    movsx   eax, byte ptr [board]
    movsx   ecx, byte ptr [board+2]
    cmp     eax, ecx
    jne     cont

    mov ax, 4c00h
    int 21h

    cont:
    ret  

ret
endp checkIfWon
.386
; 主回路
主回路:
; 检查退出按钮(ESC)。。。
; 获取鼠标按钮和光标位置。。。
;;;;;;;;;;;;;;;;;;;;;;; 检查鼠标是否位于其中一个位置
框0:
; 检查它是否被点击。。。
drawXplayer0:
; 画X
jmp-boxHitten
绘图页0:
; 抽签
jmp-boxHitten
框1:
; 检查它是否被点击。。。
drawXplayer1:
; 画X
jmp-boxHitten
绘图页1:
; 抽签
jmp-boxHitten
框2:
; 检查它是否被点击。。。
drawXplayer2:
; 画X
jmp-boxHitten
绘图页2:
; 抽签
jmp-boxHitten
框3:
; 检查它是否被点击。。。
drawXplayer3:
; 画X
jmp-boxHitten
绘图页3:
; 抽签
jmp-boxHitten
框4:
; 检查它是否被点击。。。
drawXplayer4:
; 画X
jmp-boxHitten
绘图页4:
; 抽签
jmp-boxHitten
框5:
; 检查它是否被点击。。。
drawXplayer5:
; 画X
jmp-boxHitten
绘图页5:
; 抽签
jmp-boxHitten
方框6:
; 检查它是否被点击。。。
drawXplayer6:
; 画X
jmp-boxHitten
绘图页6:
; 抽签
jmp-boxHitten
框7:
; 检查它是否被点击。。。
drawXplayer7:
; 画X
jmp-boxHitten
绘图页7:
; 抽签
jmp-boxHitten
框8:
; 检查它是否被点击。。。
drawXplayer8:
; 画X
jmp-boxHitten
绘图页8:
; 抽签
jmp-boxHitten
博希滕:
; 固定透支边界
呼叫绞车
; 设置光标位置
mov dl,1
莫夫dh,1
mov-bh,0;显示页
mov-ah,02h;设置光标位置
int 10h
;
; 换人
; 如果player='x':player='O'否则player=x'
; 这里我播放一个声音,告诉用户他点击了
; 延迟
推500;0.5秒
呼叫延迟
打电话给切克芬
jmp主回路
错误:
推动14000人;错误答案的频率
推200;持续时间毫秒
呼叫播放
; 延迟
推1000
呼叫延迟
jmp主回路
程序未退出(如我所愿): 存在(不是我想要的):

程序跳过它的原因可能是什么

编辑:

我找到了解决方案,请参见注释

我找到了问题的解决方案:
问题是,既然我把董事会定义为

电路板db 0,0,0
db 0,0,0
分贝0,0,0

支票每次都是低谷,因为它们都是0。
当我点击某个位置时,电路板会变成

板X,0,0
0,0,0
0,0,0

那么它就不能通过检查。
解决方案代码:

checkIfWon proc
     ; check rows
     ; Equal to: if (board[0] != 0 && board[0] == board[1] && board[1] == board[2])
     movsx   eax, byte ptr [board]
     movsx   ecx, byte ptr [board+1]
     cmp     eax, 0
     je cont
     cmp     eax, ecx
     jne     cont

     movsx   eax, byte ptr [board]
     movsx   ecx, byte ptr [board+2]
     cmp     eax, ecx
     jne     cont

     mov ax, 4c00h
     int 21h

cont:
    ret  

ret
endp checkIfWon

您的代码与注释不匹配。第二个比较是
[board+0]
[board+2]
。这并不重要,只有在找到
[board+0]===[board+1]
后才能访问它。无论如何,您不需要重新加载
[board]
,在第一个cmp/jne失效后,您已经在寄存器中拥有了它。您只需执行一次
movsx
加载,然后
cmpal,[board+1]
/jne,然后
cmpal,[board+2]
/jne。或者甚至对
[board+0]
[board+1]
进行一个
字的比较,以并行检查0对1和1对2。