assembly 向左、向右、向上或向下移动字符,直到按下某个键

rbl8hiat  于 2022-12-13  发布在  其他
关注(0)|答案(2)|浏览(115)
dosseg
.model small
.386
.stack 0100H
.data
    col db 0CH
    row db 28H
.code
        main proc
            mov ax, @data
            mov ds, ax
            
            mov ax, 0003H
            int 10H
            
            call start2
            Call cls
            Mov cx, 0079H
A:          Call disp
            call get
            push cx         
            call dlay
            call cls    
            pop cx
            loop a 
            call finish
            
        main endp
        
        start2 proc
            mov ah, 02h
            mov bx, 0000h
            mov dx, 0c28h
            int 10h
                        
            mov ah, 02h
            mov dx, 0b2h
            int 21H
        start2 endp
        
        disp proc
            mov ah, 02h
            mov bx, 0000h
            mov dh, col
            mov dl, row
            int 10h
                    
            cont:
            MOV AH, 02H
            MOV DX, 0B2H                        
            INT 21H
            RET
        disp endp
        
        get proc
            mov ah, 07H
            int 21h
            mov bl, al
            
            cmp al, 'a'
            je Left
            cmp al, 'd'
            je Right
            cmp al, 'w'
            je Up
            cmp al, 's'
            je Down
            cmp al, 'q'
            je stop
            
            ret
                    
        get endp
        
        cls proc
            mov ax, 0600h
            mov bx, 0700h
            mov cx, 0000h
            mov dx, 2479H
            int 10h
        cls endp
        
        dlay proc
            mov cx, 0100H
        X:  PUSH cx
            mov cx, 0FFFFH
        Y:  Loop Y
            pop cx
            loop x 
            ret
        dlay endp
        
Left:   Dec DL
        mov col, DL
        jmp cont

Right:  Inc DL
        Mov col, DL
        jmp cont
            
Up:     Dec DH
        Mov row, DH
        jmp cont
            
Down:   Inc DH
        Mov row, DH
        jmp cont
        
        finish proc
stop:       mov ax, 4c00H
            int 21H
        finish endp
    
end

不管怎样
所以我试着做一个代码,把a字符向左、右、上、下移动,一直移动到w、a、s或d键被按下或碰到屏幕的边界。(尚未实现)与 Flink 的效果,从清晰的屏幕,但问题是时刻我按任一wasd程序崩溃,它的工作,如果我按q终止程序,但除此之外,它崩溃的时刻任何w,a,s,或D键被按下。
我做错了什么,是呼叫的顺序还是过程本身。

ig9co6j1

ig9co6j11#

col db 0CH
row db 28H

这些值将被反转。列位于40,行位于12。

mov dh, col
mov dl, row

这些寄存器的名称不匹配。DL是列,DH是行。

mov dx, 2479H

该值取小数点后的十六进制数。屏幕右下角为(79,24)或(4Fh,18h)或mov dx, 184Fh

  • 上 * 和 * 下 * 代码使用的DL和DH寄存器已被通过 disp 的通道乱码。
  • start2* 和 cls 过程缺少ret指令。我认为endp不会为您提供此功能。
  • start2* 过程是完全冗余的。由于紧接着的call cls,在一开始根本不需要它。

像在 get 中那样跳出一个proc,然后像在 disp 中那样(在标签 cont 处)跳到另一个proc,这是不规则的。接下来是一个更好的 get 过程。使用它修改主循环,读作... call dispcall getcall disp ...

get proc
  mov  ah, 07h
  int  21h
  cmp  al, 'a'
  je   Left
  cmp  al, 'd'
  je    Right
  cmp  al, 'w'
  je   Up
  cmp  al, 's'
  je   Down
  cmp  al, 'q'
  je   stop
  ret
Left:
  dec  col
  ret
Right:
  inc  col
  ret
Up:
  dec  row
  ret
Down:
  inc  row
  ret
get endp
6ojccjat

6ojccjat2#

我想您可能希望将cont标签移到那里:

get proc
            mov ah, 07H
            int 21h
            mov bl, al
            
            cmp al, 'a'
            je Left
            cmp al, 'd'
            je Right
            cmp al, 'w'
            je Up
            cmp al, 's'
            je Down
            cmp al, 'q'
            je stop
            
cont:       ret

以便函数调用从跳到键特定的case句柄之前干净地恢复。

相关问题