【问题标题】:Repeat instruction in assembly 8086在汇编 8086 中重复指令
【发布时间】:2020-01-07 21:02:24
【问题描述】:

我创建了 3 个看起来不错的正方形。我只想一遍又一遍地重复这个动画,我知道这并不难,但我找不到怎么做。解释是罗马尼亚语,对不起。

基本上我只是想清除屏幕并让它们一遍又一遍地出现。感谢大家的支持。

.stack 100
.data
y1 dw 70
x  dw 70
y2 dw 120

x2 dw 130
y3 dw 70
y4 dw 120

x3 dw 190
y5 dw 70
y6 dw 120

l db 50; lungime
k db 50;latime
kfinal db 51
n db 50

.code
mov ax,@data
mov ds,ax
mov ah,0h
mov al,13h; comutare in modul grafic 13h (320 x 200)
int 10h

desen:
mov dx,y1
mov cx,x
mov al,1; culoare
mov bl,l; lungime linie
mov ah,0ch; scriere pixel, cu culoare in al, cx=x, dx=y
mov bh,0
ciclu1: int 10h ; aprindere pixel de coordonate (cx,dx)
push dx
mov dx,y2
call delay
call delay
call delay
call delay
int 10h
pop dx
inc cx
dec bl
jnz ciclu1
mov bl,k; latime

ciclu2: int 10h ; aprinde pixel de coord (cx,dx)
push cx
mov cx,x
call delay
call delay
call delay
call delay
int 10h
pop cx
inc dx
dec bl
jnz ciclu2
int 10h
mov dx,y3
mov cx,x2
mov al,14; culoare
mov bl,l; lungime linie
mov ah,0ch; scriere pixel, cu culoare in al, cx=x, dx=y
mov bh,0

ciclu3: int 10h ; aprindere pixel de coordonate (cx,dx)
push dx
mov dx,y4
call delay
call delay
call delay
call delay
int 10h
pop dx
inc cx
dec bl
jnz ciclu3
mov bl,k; latime
ciclu4: int 10h ; aprinde pixel de coord (cx,dx)
push cx
mov cx,x2
call delay
call delay
call delay
call delay
int 10h
pop cx
inc dx
dec bl
jnz ciclu4
int 10h
mov dx,y5
mov cx,x3
mov al,4; culoare
mov bl,l; lungime linie
mov ah,0ch; scriere pixel, cu culoare in al, cx=x, dx=y
mov bh,0

ciclu5: int 10h ; aprindere pixel de coordonate (cx,dx)
push dx
mov dx,y6
call delay
call delay
call delay
call delay
int 10h
pop dx
inc cx
dec bl
jnz ciclu5
mov bl,kfinal; latime ultimul patratel

ciclu6: int 10h ; aprinde pixel de coord (cx,dx)
push cx
mov cx,x3
call delay
call delay
call delay
call delay
int 10h
pop cx
inc dx
dec bl
jnz ciclu6
ret

delay:
push cx
mov cx, 0ffffh
et1: dec cx
jnz et1
pop cx
ret


mov ah,4ch
int 21h
end


【问题讨论】:

    标签: assembly x86-16


    【解决方案1】:

    一些重要的观察

    • 首先让我印象深刻的是,您没有为程序变量使用描述性名称,从而使事情变得复杂!请参阅下面的一些更好的名称。

      y1 dw 70
      x  dw 70
      y2 dw 120
      
      x2 dw 130
      y3 dw 70
      y4 dw 120
      
      x3 dw 190
      y5 dw 70
      y6 dw 120
      
      Box1Left    dw 70
      Box1Top     dw 70
      Box1Bottom  dw 120
      
      Box2Left    dw 130
      Box2Top     dw 70
      Box2Bottom  dw 120
      
      Box3Left    dw 190
      Box3Top     dw 70
      Box3Bottom  dw 120
      
    • 虽然您已将宽度和高度都设置为 50 (l db 50 ;lungime k db 50 ;latime),但您绘制的框的表面为 51x51。

    • 在绘制最终的 LowerRightCorner 点时,您的第一个(蓝色)框和第二个(黄色)框使用与第三个(红色)框不同的系统。这是为什么? 为什么要使用额外的变量kfinal db 51

    • 绘制方框的代码以ret 指令结尾,但它不是call-ed。这是错误的。此外,终止到 DOS 的代码无法访问,因为它位于另一个 ret 指令之下。

    • 你应该把它放在一个子程序中,并让它call-ed 3 次,而不是重复整个盒子绘制代码 3 次。

          mov  al, 1        ; Blue
          mov  cx, Box1Left
          mov  dx, Box1Top
          mov  bp, Box1Bottom
          call DrawBox
          mov  al, 14       ; Yellow
          mov  cx, Box2Left
          mov  dx, Box2Top
          mov  bp, Box2Bottom
          call DrawBox
          mov  al, 4        ; Red
          mov  cx, Box2Left
          mov  dx, Box2Top
          mov  bp, Box2Bottom
          call DrawBox
      
          mov  ax, 4C00h    ; DOS.Terminate
          int  21h
      
      DrawBox:
          mov  ah, 0Ch      ; BIOS.WritePixel
          mov  bh, 0        ; DisplayPage
          push cx           ; (1)
      
          mov  bl, 50       ; Width = Length of the horizontal line
      ciclu1:
          int  10h
          xchg dx, bp
          int  10h
          xchg dx, bp
          inc  cx
          dec  bl
          jnz  ciclu1
      
          pop  bp           ; (1)
          mov  bl, 51       ; Height = Length of the vertical line
      ciclu2:
          int  10h
          xchg cx, bp
          int  10h
          xchg cx, bp
          inc  dx
          dec  bl
          jnz  ciclu2
          ret
      

    你的问题的答案

    基本上我只是想清除屏幕并让它们一遍又一遍地出现。

    如果这就是你想要的,那么你只需要重新启动你的程序。您的程序已经通过清除屏幕开始,因为它将视频模式设置为 13 小时。
    请给用户一个机会来停止你的程序。在下面的示例代码中查看我是如何做到的:

        mov  ax, @data
        mov  ds, ax
    
    Again:
        mov  ah, 00h
        mov  al, 13h; comutare in modul grafic 13h (320 x 200)
        int  10h
    
        ; Here you draw the boxes! Use the above code snippet...
    
        mov  ah, 00h      ; BIOS.WaitKey Wait for the user to press any key
        int  16h          ; -> AX
        cmp  al, 27       ; Did the user press <ESC> ?
        je   Exit         ; Yes
        jmp  Again        ; No, restart the program (this could be a big jump)
    
    Exit:
        mov  ax, 4C00h    ; DOS.Terminate
        int  21h
    
    ; All subroutines go here, below the Exit to DOS!
    

    你可以在这篇文章中阅读更多关于绘画的信息 How to create and draw sprites in emu8086?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 2021-06-25
      • 2022-11-25
      • 1970-01-01
      • 2017-08-15
      相关资源
      最近更新 更多