汇编语言Pong游戏DOSBox模拟器中球绘制异常问题求助
问题:汇编Pong游戏中球显示为水平矩形,无法绘制方形块
我是汇编语言初学者,正在制作一款小型Pong游戏,在x86 64位Windows电脑上用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
问题根源
- 寄存器操作错误:在判断是否完成所有行的绘制时,错误执行了
SUB DX,BALL_Y,直接修改了存储当前Y坐标的DX寄存器,导致后续的Y位置完全错乱,无法正确逐行绘制。 - 循环逻辑混乱:仅使用单一循环标签,未区分行循环与列循环的逻辑,画完一行后,跳转逻辑错误,无法正确启动下一行的绘制流程。
修复方案
重新梳理绘制逻辑,拆分行、列循环,修正寄存器操作:
修复后的DRAW_BALL过程
DRAW_BALL PROC NEAR MOV DX, BALL_Y ; 初始化起始Y坐标(行) DRAW_BALL_ROW: MOV CX, BALL_X ; 初始化当前行的起始X坐标(列) DRAW_BALL_COL: MOV AH, 0Ch ; BIOS功能号:绘制单个像素 MOV AL, 0Fh ; 像素颜色设为白色 MOV BH, 00h ; 显示页码为0 INT 10h ; 调用BIOS中断完成像素绘制 INC CX ; 列坐标+1,准备绘制下一个像素 MOV AX, CX SUB AX, BALL_X CMP AX, BALL_SIZE ; 判断当前行是否已绘制完所有列 JNG DRAW_BALL_COL ; 未完成则继续绘制当前行的下一列 INC DX ; 行坐标+1,准备绘制下一行 MOV AX, DX SUB AX, BALL_Y CMP AX, BALL_SIZE ; 判断是否已绘制完所有行 JNG DRAW_BALL_ROW ; 未完成则继续绘制下一行 RET DRAW_BALL ENDP
修改说明
- 拆分循环标签:新增
DRAW_BALL_ROW(控制行循环)和DRAW_BALL_COL(控制列循环)两个标签,明确区分行、列的绘制逻辑,避免跳转混乱。 - 修正寄存器操作:判断行数时,使用
AX暂存当前Y坐标值,通过SUB AX, BALL_Y计算已绘制的行数,不再修改DX寄存器,保证Y坐标的正确性。 - 理顺循环流程:先完成一行内所有列的像素绘制,再递增行坐标,判断是否需要继续绘制下一行,完全符合方形逐行逐列绘制的逻辑。
内容的提问来源于stack exchange,提问作者Ayxux
相关产品推荐
相关产品推荐

