assembly 汇编语言中乒乓球游戏的模拟器输出错误

yeotifhr  于 5个月前  发布在  其他
关注(0)|答案(3)|浏览(51)

汇编语言的Pong游戏

我试图使一个小乒乓球游戏,为我自己的做法,在汇编语言,因为我是一个初学者在这方面。
我在我的x86 64位Windows PC上运行代码。我使用DOSBox模拟器运行我的游戏并测试它。
我遇到的问题是:当我试图为我的乒乓球游戏绘制球时,模拟器显示一条矩形水平线,我无法将其修复为方形块。
这是我到目前为止写的代码:

STACK SEGMENT PARA STACK
    DB 64 DUP (' ')
STACK ENDS

DATA SEGMENT PARA 'DATA'

    BALL_X DW 0Ah        ;current X position (column) of the ball
    BALL_Y DW 0Ah        ;current Y position (line) of the ball
    BALL_SIZE DW 04h     ;size of the ball (how many pixels does the ball have in width and height)

DATA ENDS

CODE SEGMENT PARA 'CODE'

    MAIN PROC FAR
    ASSUME CS:CODE,DS:DATA,SS:STACK ;assume as code, data and stack segments the respective registers
        PUSH DS         ; Push the DS segment to the stack
        SUB AX, AX      ; Clean the AX register
        PUSH AX         ; Push AX to the stack
        MOV AX, DATA    ; Load the DATA segment into AX
        MOV DS, AX      ; Set DS to the DATA segment
        POP AX          ; Release top item from stack
        POP AX          ; Release top item from stack
        
        MOV AH, 00h     ; Set the video mode configuration
        MOV AL, 13h     ; Choose the video mode (320x200 256-color VGA mode)
        INT 10h         ; Execute the configuration
       
        MOV AH, 0Bh     ; Set the background color
        MOV BH, 00h     ; Page number (usually 0)
        MOV BL, 00h     ; Choose black as the background color
        INT 10h         ; Execute the configuration

        CALL DRAW_BALL
        
        RET
    MAIN ENDP   

       
    DRAW_BALL PROC NEAR
    
       MOV CX,BALL_X ;set the column (X)
       MOV DX,BALL_Y ;set the line (Y)
       
    DRAW_BALL_HORIZONTAL:
        MOV AH,0Ch ;set configuration to writing a pixel
        MOV AL,0Fh ;set pixel color white
        MOV BH,00h ;set the page number
        INT 10h ;exec the config

        INC CX ;CX = CX+1
        MOV AX,CX ;CX - BALL_X > BALL_SIZE (Y-> We go to the next line, N-> We continue to the next column)
        SUB AX,BALL_X
        CMP AX,BALL_SIZE
        JNG DRAW_BALL_HORIZONTAL 

        MOV CX,BALL_X ;the CX register goes back to initial column
        INC DX ;DX = DX + 1

        MOV AX,DX ;DX - BALL_Y > BALL_SIZE (Y-> We got to the next line, N-> We continue to the next column)
        SUB DX,BALL_Y
        CMP AX,BALL_SIZE
        JNG DRAW_BALL_HORIZONTAL

    RET   
    DRAW_BALL ENDP

CODE ENDS

字符串
球的代码用 DRAW_BALL_HORIZONTAL 编写。
我已经尝试了不同的迭代来修复它,以代表一个正方形块,但我仍然无法做到这一点。
这里的问题是什么?我该如何解决?

ukqbszuj

ukqbszuj1#

我将draw_ball proc的最后一部分修改为以下代码:

mov ax,dx
    mov bx,BALL_Y   
    add bx,10
    cmp dx,bx        
    jng DRAW_BALL_HORIZONTAL

字符串
因为ball_y是代码开始画球的第一行,画球应该在ball_y + 10结束。

3vpjnl9f

3vpjnl9f2#

VGA mode 13h中对每个像素使用中断会使它慢得无法接受;最好直接写入位于段地址A000 h的视频存储器。此外,程序格式COM更适合初学者,因为您不必为堆栈和段寄存器初始化而烦恼。
我试着用€ASM写你的作业,用euroasm.exe Ayxux.asm组装它,它像预期的那样工作。

Ayxux PROGRAM Format=COM
        MOV AH, 00h     ; Set the video mode configuration
        MOV AL, 13h     ; Choose the video mode (320x200 256-color VGA mode).
        INT 10h         ; Execute the configuration
        MOV AX,0A000h
        MOV ES,AX        ; Let ES address videomemory
        CALL DRAW_BALL
        MOV AH,0
        INT 16h           ; Wait for keypress.
        MOV AX,0003h
        INT 10h           ; Restore text video mode 80*25 before termination.
        RET               ; Return to DOS.

DRAW_BALL PROC            ; Calculate address of the ball: DI=320*BALL_Y + BALL_X
       MOV AX,320         ; Size of one videoline.
       MUL [BALL_Y]
       ADD AX,[BALL_X]
       MOV DI,AX
       MOV AL,[BALL_COLOR]
       MOV BX,[BALL_SIZE]
       MOV DX,BX          ; Initialize row counter DX.
  DRAW_BALL_HORIZONTAL:
       MOV CX,BX          ; Initialize column counter CX.
       REP STOSB          ; Store CX pixels with color AL to videomemory at ES:DI, increment DI.
       SUB DI,BX          ; Return the pointer back to initial column.
       ADD DI,320         ; Point at the next row.
       DEC DX
       JNZ DRAW_BALL_HORIZONTAL ; The next ball row.
       RET
     ENDP DRAW_BALL

BALL_X     DW 0Ah          ;current X position (column) of the ball
BALL_Y     DW 0Ah          ;current Y position (line) of the ball
BALL_SIZE  DW 04h          ;size of the ball (how many pixels does the ball have in width and height)
BALL_COLOR DB 0Fh          ; Pixel color 0..255.
    ENDPROGRAM Ayxux

字符串

ohtdti5x

ohtdti5x3#

第1期

STACK SEGMENT PARA STACK
    DB 64 DUP (' ')
STACK ENDS

字符串
64字节对于一个堆栈来说太少了,如果你使用的是BIOS功能的话,我建议是512字节。

第2期

PUSH DS         ; Push the DS segment to the stack
SUB AX, AX      ; Clean the AX register
PUSH AX         ; Push AX to the stack
...
POP AX          ; Release top item from stack
POP AX          ; Release top item from stack


您需要删除这些pop。这两个被压入堆栈的项对于您的.EXE程序能够使用单个ret(far)指令退出到DOS是必不可少的。

第三期

INC CX
MOV AX,CX
SUB AX,BALL_X
CMP AX,BALL_SIZE
JNG DRAW_BALL_HORIZONTAL


著名的一次性错误!这将产生5像素,而BALL_SIZE等于4。简单地写:

JB  DRAW_BALL_HORIZONTAL

第四期

MOV CX,BALL_X ;the CX register goes back to initial column
INC DX ;DX = DX + 1
MOV AX,DX
SUB DX,BALL_Y         <<< typo
CMP AX,BALL_SIZE
JNG DRAW_BALL_HORIZONTAL


同样的一次性错误,但这次由于打字错误而加重!sub需要从临时寄存器AX中减去。

MOV AX,DX
SUB AX,BALL_Y
CMP AX,BALL_SIZE
JB  DRAW_BALL_HORIZONTAL

第五期

MOV AH, 0Bh     ; Set the background color
MOV BH, 00h     ; Page number (usually 0)
MOV BL, 00h     ; Choose black as the background color
INT 10h         ; Execute the configuration


这是多余的代码。在设置了320 x200 256色图形模式13 h后,背景已经默认为黑色。

相关问题