组装8086 tasm:横向蛇动的问题

时间:2017-05-27 10:13:08

标签: assembly x86-16 tasm

我的问题是,当我向左或向右移动蛇时,删除"追踪"在它没有改变之后,我已经调试了几天的代码,但仍然无法找到问题.... 我将删除轨迹更改为白色,以查看当x应该更改时它是如何移动的。

逻辑是我在数组中有x,y,最后一个数组将转到x_remove和y_remove,在那些像素中,它将删除它(用黑色绘制它,在这种情况下是白色,因为我想看看如何它正在移动。

这是我的代码:

%TITLE  "Project"

        IDEAL

;---------------------------------------
;Choice_Enter enters to the requested option (Game/Settings/Exit)
;---------------------------------------

;Input:

;           Y = y of the pointer
;Output:

;           None

;Registers:

;           AH

;---------------------------------------

MACRO Choice_Enter y

    cmp y,8

    je Choice_Enter_1

    cmp y,10

    je Choice_Enter_2

    cmp y,12

    je Choice_Enter_3

ENDM Choice_Enter

;---------------------------------------

;Pointer_up moves y of the object that points to the options in the main menu

;---------------------------------------

;Input:

;           Y = y of the pointer

;Output:

;           None

;Registers:

;           AH

;---------------------------------------

MACRO Pointer_up y

    cmp y,8

    je up_2

    cmp y,10

    je up_1

    cmp y,12


    je up_1

ENDM Pointer_up


;---------------------------------------

;Pointer_down moves y of the object that points to the options in the main menu

;---------------------------------------

;Input:

;           Y1 = y of the pointer

;Output:

;           None.

;Registers:

;           None.

;---------------------------------------

MACRO Pointer_down y

    cmp y,8

    je down_1

    cmp y,10

    je down_1

    cmp y,12

    je down_2

ENDM Pointer_down



;---------------------------------------

;Print Prints the object that given

;---------------------------------------

;Input:

;           X = x of the string,Y = y of the string,Object_to_print = string 

;that requested to print

;Output:

;           BX,AH,DX

;Registers:

;           DX,BX,AH

;---------------------------------------

MACRO Print x,y,object_to_print

    mov dl, x ; Column

    mov dh, y ; Row

    mov bx, 0 ; Page number, 0 for graphics modes

    mov ah, 2h

    int 10h 

    mov dx, offset object_to_print

    mov ah, 9h

    int 21h 

ENDM Print


        MODEL small

        P386


        STACK 256


        SPAN equ 500    ; interval 500 loops

        ENTER_KEY equ 01Ch

        UP_KEY equ 72

        DOWN_KEY equ 80

        KEY_RIGHT equ 77

        KEY_LEFT  equ 75

        ESC_KEY equ 1

        screen_RAM_graphics equ 0A000h


;-----  Equates



        DATASEG


        c_remove dw 1
        X_remove dw 0020h
        Y_remove dw 0008h
        Check_j dw 4
        Check_n dw 4
        check_i dw 0
        check_k dw 0
        Counter dw SPAN         
        X_object dw 18
        Y_object dw 12
        DeltaX  dw 0
        DeltaY  dw 0
        i dw 4
        k dw 4
        j dw 4 
        n dw 4
        Color db 11
        Del_Pointer db '  $'
        Main_Screen_Pointer db '->$'
        Main_Screen_Game db 'Start game$'
        Main_Screen_Settings db 'Settings$'
        Main_Screen_Exit db 'Exit$'
        Print_Settings db 'Who created the game ? ',13,10
                       db 'You can play in this game with the keys : ',13,10
                       db 'up,down,left,right',13,10,13,10
                       db 'press esc to exit$'
        Print_End db 'See you next time ;)',13,10
                   db 'press esc to exit$'
        x db 13
        y db 8
        ArrayX dw 0020h,0020h,0020h
        ArrayY dw 0012h,0012h,0012h


        CODESEG

Start:

        mov ax, @data

        mov ds, ax

;-------Changing to graphics mode.  

        call GraphicsMode

Return:

        call CleanScreenGraphicsMode

;-------Printing main_menu  

        Print 15,8,Main_Screen_Game

        Print 15,10,Main_Screen_Settings

        Print 15,12,Main_Screen_Exit

Pointer_reprint:

        Print [x],[y],Main_Screen_Pointer

;-------clearing keyboard buffer

        mov ah,0ch

        mov al,07h

        int 21h

;-------scanning code from keyboard

        in al,060h

;scan end               

        cmp al,UP_KEY

        je l2

        cmp al,DOWN_KEY

        je l1

        cmp al,ENTER_KEY

        je Ent

return_back:

        jne Pointer_reprint


;If the user chooses "Game" option.

Ent:

    Choice_Enter [y]


Choice_Enter_1:

    call CleanScreenGraphicsMode

    mov ah,8

    mov [y],ah ; Lines 189-190 are for bringing the pointer back to his place.

    call GraphicsMode                                                         

    jmp GamePlay

Return_GamePlay:

    jmp return


;If the user chooses "Settings" option.

Choice_Enter_2:

    mov ah,8

    mov [y],ah

    call CleanScreenGraphicsMode     

    call GraphicsMode

    mov ah,0

    Print 0,0,Print_Settings

re_scan_2:

;-------clearing keyboard buffer

    mov ah,0ch

    mov al,07h

    int 21h 

;return to main menu by getting input.

    in al,060h

    cmp al,ESC_KEY

    je Return

    jne re_scan_2



;If the user chooses "Exit" option.

Choice_Enter_3:

    jmp exit

;If the user presses down key in main menu in one of those options(Start 

;Game,Settings)

down_1:

    Print [x],[y],Del_Pointer

    mov ah,2

    add [y],ah

    jmp return_back


;If the user presses down key in main menu in this function(Exit)

down_2:

    Print [x],[y],Del_Pointer

    mov ah,4

    sub [y],ah

    jmp return_back

;If the user presses up key in main menu in one of those options(Settings,Exit) 

up_1:
    Print [x],[y],Del_Pointer

    mov ah,2

    sub [y],ah

    jmp return_back


;If the user presses up key in main menu in this function(Start Game)

up_2:

    Print [x],[y],Del_Pointer

    mov ah,4

    add [y],ah

    jmp return_back

;If the user presses down key, it updates it.

l1:
    Print [x],[y],Del_Pointer

    Pointer_down [y]

    jmp Pointer_reprint


;If the user presses up key, it updates it.

l2:

    Print [x],[y],Del_Pointer

    Pointer_up [y]

    jmp Pointer_reprint


GamePlay:  

;----- Read SCAN code and ASCII code from keyboard port     
        in al,060h

        push ax


;----- Checking key is pressed

        cmp al, UP_KEY

        je Up

        cmp al, DOWN_KEY

        je Down


        cmp al, KEY_RIGHT

        je Right


        cmp al, KEY_LEFT

        jne cont

        mov [deltaX], -2

        mov [deltaY],0

        jmp cont

Up:     mov [deltaY], -2

        mov [deltaX],0

        jmp Cont

Down:  

        mov [deltaY],2

        mov [deltaX],0

        jmp Cont

Right: 

        mov [deltaX],2

        mov [deltaY],0

        jmp Cont


Cont:

        mov dx, [deltaX]

        add [X_object], dx

        mov dx, [deltaY]

        add [Y_object], dx

        call WriteSnake <-- The problem is here

        call Move_Snake <-- And here

        dec [counter]

        jnz NoArrow     

        mov ax,[span]

        mov [counter],ax

NoArrow:

        pop ax

        dec al

        jz  Return_GamePlay

        jmp GamePlay 



;----------------------------------------------------------

; GraphicsMode sets the mode of the dosbox to Graphics mode

;----------------------------------------------------------


; Input:

;           AH

; Output:

;           AL,AH

; Registers:

;    

;----------------------------------------------------------

PROC GraphicsMode

    mov al,13h

    mov ah,0h

    int 10h

    ret

ENDP GraphicsMode

;----------------------------------------------------------

; GraphicsMode sets the mode of the dosbox to Graphics mode

;----------------------------------------------------------

; Input:

;           AL = first color,AH = second color, ES

; Output:

;           AX

; Registers:

;           AX

;----------------------------------------------------------

PROC CleanScreenGraphicsMode

    mov ax,screen_RAM_graphics

    mov es,ax          ; es:di - video memory

    xor di,di

    mov cx,320*200/2

    mov al,0d          ; color

    mov ah,0d            ; color

    rep stosw            ; mov es:[di],ax     add di,2 

    ret

ENDP CleanScreenGraphicsMode


;----------------------------------------------------------

; WriteSnake Drawing point

;----------------------------------------------------------

; Input:

;   CX = x, DX = y, AL = color 

; Output:

;   The point

; Registers

;    AX, BH, CX, DX,

;----------------------------------------------------------

PROC WriteSnake

    push cx

    push dx

    push bx

    push ax

keep_printing:

;----------------First pixel(left up)

        mov bh,0

        mov si,[check_i]

        mov cx,[ArrayX+si]

        mov si,[check_k]

        mov dx,[ArrayY+si]

        mov al,[color]

        mov ah,0ch

        int 10h

;----------------Second pixel(right up)

        mov bh,0

        mov si,[check_i]

        mov cx,[ArrayX+si]

        add cx,1

        mov si,[check_k]

        mov dx,[ArrayY+si]

        mov al,[color]

        mov ah,0ch

        int 10h

;----------------Third pixel(left down)

        mov bh,0

        mov si,[check_i]

        mov cx,[ArrayX+si]

        mov si,[check_k]

        mov dx,[ArrayY+si]

        add dx,1

        mov al,[color]

        mov ah,0ch

        int 10h

;----------------Fourth pixel(right down)

        mov bh,0

        mov si,[check_k]

        mov cx,[ArrayX+si]

        add cx,1

        mov si,[check_i]

        mov dx,[ArrayY+si]

        add dx,1

        mov al,[color]

        mov ah,0ch

        int 10h

        inc [check_i]

        inc [check_i]

        inc [check_k]

        inc [check_k]

        mov ax,[check_i]

        cmp ax,6

        jne keep_printing

;-----------------------Deleting:   

;-----------------------Delay

        mov dx,0C380h ;dx, right side of the miliseconds

        mov cx,01C9h    ; cx, left side of the miliseconds ex: cx = 5, dx = ; 
;       012DFh so it will wait 0512DFh seconds
        mov ah,86

        int 15h

    ;------------------------First pixel(left up)

        mov bh,0

        mov cx,[y_remove]

        mov dx,[x_remove]

        mov al,15

        mov ah,0ch

        int 10h

    ;----------------------Second pixel(right up)

        mov bh,0

        mov cx,[y_remove]

        mov dx,[x_remove]

        add cx,1

        mov al,15

        mov ah,0ch

        int 10h

    ;--------------------Third pixel(left down)

        mov bh,0

        mov cx,[y_remove]

        mov dx,[x_remove]

        add dx,1

        mov al,15

        mov ah,0ch

        int 10h

    ;--------------------Fourth pixel(right down)

        mov bh,0

        mov cx,[y_remove]

        mov dx,[x_remove]

        add cx,1

        add dx,1

        mov al,15

        mov ah,0ch

        int 10h


end_print_func:

        pop ax

        pop bx

        pop dx

        pop cx

        mov [check_i],0

        mov [check_k],0

        ret

ENDP WriteSnake

;---------------------------------------

;Move_Snake Changes the x and y array of the snake.

;---------------------------------------

;Input:

;           Y1 = new first y of the snake , X1 = new first x of the snake.

;Output:

;           None.
;Registers:

;           AH  

;---------------------------------------
PROC Move_Snake 

    push si

    push ax

    push bx

;---------------------Data of removing last pixel(last in array)

    mov bx,[ArrayX+6]
    mov [X_remove],bx
    mov bx,[ArrayY+6]
    mov [Y_remove],bx

re_func:

    cmp [Check_j],0

    je End_Func

;---------------------Transferring X of the snake.

    mov si,[Check_j]    ;Moving to register because can't compare memory to 
;memory.

    mov ax,[ArrayX+si]

    mov [ArrayX+si+2],ax

;---------------------Transferring in array Y of the snake(new to old).

    mov si,[Check_n]    ;Moving to register because can't compare memory to 

;memory.
    mov ax,[ArrayY+si]

    mov [ArrayY+si+2],ax

    dec [Check_j]

    dec [Check_j]

    dec [Check_n]

    dec [Check_n]

    jmp re_func

;---------------------First new coordinates of the snake.

End_Func:

    mov si,[Y_object]

    mov [ArrayY+0],si

    mov si,[X_object]

    mov [ArrayX+0],si

    add [Check_j],4

    add [Check_n],4

    pop bx

    pop ax

    pop si

    ret

ENDP Move_Snake


Exit:               

    call CleanScreenGraphicsMode

    mov ah,00

    mov al,03 ;text mode 3

    int 10h

    mov ax, 4C00h

    int 21h

    END start

1 个答案:

答案 0 :(得分:1)

没有出现的错误

由于 check_i check_k 变量在整个程序中具有相同的值(请参阅我的上一点),因此您不会在屏幕上看到此错误。

;----------------Fourth pixel(right down)
    mov bh,0
    mov si,[check_k]         <- WRONG
    mov cx,[ArrayX+si]
    add cx,1
    mov si,[check_i]         <- WRONG
    mov dx,[ArrayY+si]
    add dx,1
    mov al,[color]
    mov ah,0ch
    int 10h

WriteSnake 程序的这一部分中,您选择了错误的偏移变量!
第四个像素应该与其他三个像素没有区别。

;----------------Fourth pixel(right down)
    mov bh,0
    mov si,[check_i]         <- Corrected
    mov cx,[ArrayX+si]
    add cx,1
    mov si,[check_k]         <- Corrected
    mov dx,[ArrayY+si]
    add dx,1
    mov al,[color]
    mov ah,0ch
    int 10h

此外,您可以考虑简化绘制4个像素的代码:

;left up
    mov bh,0
    mov si,[check_i]
    mov cx,[ArrayX+si]
    mov si,[check_k]
    mov dx,[ArrayY+si]
    mov al,[color]
    mov ah,0ch
    int 10h
;right up
    inc cx
    int 10h
;right down
    inc dx
    int 10h
;left down
    dec cx
    int 10h

    add [check_i], 2
    add [check_k], 2

更正&#34;删除路径&#34;

;------------------------First pixel(left up)
    mov bh,0
    mov cx,[y_remove]      <- WRONG
    mov dx,[x_remove]      <- WRONG
    mov al,15
    mov ah,0ch
    int 10h

BIOS PlotPixel 功能0Ch需要CX中的X坐标和DX中的Y坐标。
在这里,您也可以采用与上述相同的方式优化代码:

;left up
    mov bh,0
    mov cx,[x_remove]      <- Corrected
    mov dx,[y_remove]      <- Corrected
    mov al,15
    mov ah,0ch
    int 10h
;right up
    inc cx
    int 10h
;right down
    inc dx
    int 10h
;left down
    dec cx
    int 10h

    mov [check_i], 0
    mov [check_k], 0

Move_Snake过程中的错误

mov bx,[ArrayX+6]
mov [X_remove],bx
mov bx,[ArrayY+6]
mov [Y_remove],bx

由于这两个字大小的数组只包含3个项目(= 6个字节),因此从偏移量+6读取将产生垃圾!

冗余变量

check_i check_k 变量
check_j check_n 变量

这些变量似乎总是在程序中一起变化。考虑通过不使用第二个实例进行简化。