【问题标题】:Move a pixel with arrow keys in assembly在装配中使用箭头键移动像素
【发布时间】:2017-04-15 07:50:34
【问题描述】:

这是代码:

IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
key db 0
locH dw 0  ;location horizontal
locV dw 0  ;location vertical
; --------------------------
CODESEG

UP_ON equ 48h
UP_OFF equ 0c8h
DOWN_ON equ 50h
DOWN_OFF equ 0d0h
LEFT_ON equ 4Bh
LEFT_OFF equ 0cBh
RIGHT_ON equ 4Dh
RIGHT_OFF equ 0cDh
ESCAPE equ 1

proc getKey
in al, 60h
mov [key],al
ret
endp getKey

start:
    mov ax, @data
    mov ds, ax
; --------------------------
;fullscreen
MOV AL, 13H
MOV AH, 0
INT 10H
;print red pixel
MOV AH,0Ch
MOV AL,4
MOV CX,160 ; 0 ≤ X ≤ 319
MOV DX,100 ; 0 ≤ Y ≤ 199
INT 10H
mov [locH],cx
mov [locV],dx

mainLoop:
call getKey
cmp [key],ESCAPE
jne next
jmp exit
next:
;checks if key is up
cmp [key],UP_ON
je up
;checks if key is down
cmp [key],DOWN_ON 
je down
;checks if key is left
cmp [key],LEFT_ON 
je left
;checks if key is right
cmp [key],RIGHT_ON 
jne next2
jmp right
next2:
jmp mainLoop
; --------------------------    

exit:
;exits full screen mode
MOV AL, 3H
MOV AH, 0
INT 10H
mov ax, 4c00h
int 21h

up:
;delete previous red pixel
MOV AH,0Ch
MOV AL,0
MOV CX,[locH] ; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H
inc [locV]
;print next red pixel
MOV AH,0Ch
MOV AL,4
MOV CX,[locH] ; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H

mov [locH],cx
mov [locV],dx

jmp mainLoop



down:
;delete previous red pixel
MOV AH,0Ch
MOV AL,0
MOV CX,[locH] ; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H
dec [locV]
;print next red pixel
MOV AH,0Ch
MOV AL,4
MOV CX,[locH] ; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H

mov [locH],cx
mov [locV],dx



left:
;delete previous red pixel
MOV AH,0Ch
MOV AL,0
MOV CX,[locH]; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H
dec [locH]
;print next red pixel
MOV AH,0Ch
MOV AL,4
MOV CX,[locH] ; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H

mov [locH],cx
mov [locV],dx


right:
;delete previous red pixel
MOV AH,0Ch
MOV AL,0
MOV CX,[locH]; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H
inc [locH]
;print next red pixel
MOV AH,0Ch
MOV AL,4
MOV CX,[locH] ; 0 ≤ X ≤ 319
MOV DX,[locV] ; 0 ≤ Y ≤ 199
INT 10H

mov [locH],cx
mov [locV],dx
jmp mainLoop



END start

好像代码有两个问题:

  1. 相对跳转超出范围 000Eh 字节。-已解决

  2. 代码无法正常工作。当我按下箭头键时,像素会吓坏并移动到屏幕上的不同位置。 我不知道为什么会出现问题,我尝试了所有我能想到的方法。

感谢您的帮助!

【问题讨论】:

  • 对于第一个问题,将指令JUMPS 添加到源代码的开头。 TASM 将自动改变错误的跳跃顺序,包括两个正确的跳跃(一个相对的和一个绝对的)。
  • @rkhb 对不起,我不明白。我该怎么做?
  • @Emil - 超出范围跳转的解决方案是将je exit 更改为更长的序列jne next / jmp exit / next:。如果您提出要求,显然 TASM 可以为您执行此操作。
  • 对于您的第二个问题,我怀疑保存cxdx 中断之后会保存一些随机值。通常不会通过调用保留寄存器。
  • @BoPersson 谢谢,第一个问题解决了。

标签: assembly graphics x86-16 tasm dosbox


【解决方案1】:

由于您遇到了第二个问题,以下是对当前程序的一些观察:

  • 您不应该通过直接读取某些键盘端口来了解按键。更好地使用相应的 BIOS 功能:

    proc getKey
        mov ah, 00h
        int 10h
        mov [key],al
        ret
    endp getKey
    
  • 当用户按下 UP 键时,他会期望红点在屏幕上向上移动。由于屏幕的坐标系不同于通常的数学 XY 坐标系,您需要在 up 例程中使用 dec [locV],在 down 例程中使用 inc [locV] .
    您的 leftright 例程是正确的。

  • BIOS 调用可能失败的一个原因是没有提供所有参数! 绘制像素的 BIOS 调用需要 BH 寄存器中的显示页面。您应该将其设置为零:

    mov bh, 0  ;Display page
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 2023-03-08
    • 2014-03-27
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多