Повторите инструкцию в сборке 8086 - PullRequest
1 голос
/ 08 января 2020

Я создал 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


1 Ответ

0 голосов
/ 09 января 2020

Некоторые важные наблюдения

  • Первое, что меня поражает, это то, что вы усложнили ситуацию, не используя описательные имена для переменных программы! Ниже приведены некоторые лучшие имена.

    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.

  • Ваша 1-я (синяя) коробка и ваша 2-я (желтая) коробка используют другую систему, чем 3-я (красная) коробка, когда речь идет о рисовании последней точки LowerRightCorner. Это почему? Зачем использовать дополнительную переменную kfinal db 51?

  • Код, в котором dr aws коробки заканчивается инструкцией ret, но он не был call -ed. Это не верно. Более того, код, заканчивающийся на DOS, недоступен, потому что он находится ниже другой инструкции ret.

  • Вместо того, чтобы повторять весь код рисования блока 3 раза, вы должны поместить его в подпрограмму и иметь его call -ed 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!

Подробнее о рисовании вы можете прочитать в этом посте Как создавать и рисовать спрайты в emu8086?

...