Assembly 汇编-cmp指令始终通过
我正在做一个Tic Tac Toe游戏,当我做这个功能来检查一个玩家是否赢了。 出于测试目的,我让程序在玩家获胜时退出。 只是为了开始,我让程序只检查第一行: 0,0,0==>此行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
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。