【问题标题】:Assembly - cmp instruction always passes汇编 - cmp 指令总是通过
【发布时间】:2019-10-17 13:51:47
【问题描述】:

我正在制作井字游戏,并在制作检查玩家是否获胜的功能时。 出于测试目的,我让程序在 A 玩家获胜时简单地退出。 刚开始我让程序只检查第一行:

0, 0, 0 ==> 这一行
0, 0, 0
0, 0, 0

我遇到了一个问题,每次我将 A 位置更改为 An X 或 O 时,程序都存在,除了当我选择程序检查的位置之一时(所以,如果我选择第一行的任何位置)。
函数代码在最后

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

.data
board   db 0,0,0
        db 0,0,0
        db 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
; mainloop
mainloop:
    ; check for exit button (ESC)...
    ; get mouse button and cursor position...
    ;;;;;;;;;;;;;;;;;;;;;;; Check if mouse is on one of the positions 

        box0:
        ; check if it got clicked...
        drawXplayer0:
        ; draw X
        jmp boxHitten
        drawOplayer0:
        ; draw o

        jmp boxHitten

    box1:
        ; check if it got clicked...
        drawXplayer1:
            ; draw X
            jmp boxHitten
        drawOplayer1:
            ; draw o

        jmp boxHitten

    box2:
        ; check if it got clicked...
        drawXplayer2:
            ; draw X
            jmp boxHitten
        drawOplayer2:
            ; draw o

        jmp boxHitten

    box3:
        ; check if it got clicked...
        drawXplayer3:
            ; draw X
            jmp boxHitten
        drawOplayer3:
            ; draw o

        jmp boxHitten

    box4:
        ; check if it got clicked...
        drawXplayer4:
            ; draw X
            jmp boxHitten
        drawOplayer4:
            ; draw o

        jmp boxHitten

    box5:
        ; check if it got clicked...
        drawXplayer5:
            ; draw X
            jmp boxHitten
        drawOplayer5:
            ; draw o

        jmp boxHitten

    box6:
        ; check if it got clicked...
        drawXplayer6:
            ; draw X
            jmp boxHitten
        drawOplayer6:
            ; draw o

        jmp boxHitten

    box7:
        ; check if it got clicked...
        drawXplayer7:
            ; draw X
            jmp boxHitten
        drawOplayer7:
            ; draw o

        jmp boxHitten

    box8:
        ; check if it got clicked...
        drawXplayer8:
            ; draw X
            jmp boxHitten
        drawOplayer8:
            ; draw o

        jmp boxHitten

    boxHitten:  
        ; Fix overdrawn borders
        call drawBoard

        ; set cursor position 
        mov  dl, 1
        mov  dh, 1
        mov  bh, 0    ;Display page     
        mov  ah, 02h  ;SetCursorPosition
        int  10h
        ;
        ; change player
        ; if player='x': player='O' else player=x'

        ; here im playing a sound that tells the user he clicked


        ; delay
        push 500 ; 0.5 secs
        call delay
        call checkIfWon
        jmp mainloop

    takenError:
        push 14000 ; frequency for bad answer
        push 200       ; duration milliseconds
        call play

        ; delay
        push 1000
        call delay
        jmp mainloop




程序没有退出(如我所愿): 存在(不是我想要的):

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

编辑:
我找到了解决方案,请参阅评论

【问题讨论】:

  • 您的代码与 cmets 不匹配。第二个比较是[board+0][board+2]。没关系,只有在找到[board+0] == [board+1] 后才能到达。无论如何,您不需要重新加载[board],在第一个 cmp/jne 失败后,您已经将其保存在寄存器中。你可以只做一个movsx load 然后cmp al, [board+1] / jne 然后cmp al, [board+2] / jne。或者甚至对[board+0][board+1] 进行一次word 比较,以并行检查0 与1 和1 与2。

标签: assembly x86-16 tasm


【解决方案1】:

我找到了解决问题的方法:
事情是,因为我将 board 定义为

板分贝 0,0,0
分贝 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    相关资源
    最近更新 更多