TASM. Перехват прерывания 5h. Вывод на экран строк (сначала горизонтально, затем вертикально и т. д.)

нужна помощь. Не могу понять кусок кода программы. Программа выполняет следующее: Очистить экран. Вывести несколько строк произвольного текста. Перехватить прерывание экрана (Int 5h). Первый вызов этого прерывания располагает строки вертикально, следующий «нормально» и т.д. Код программы:

data segment
    VIDEO_BUF dw 2000 dup(0)    
    DIRECT db 0 
    string1 db 'An assembly language is a type'
    string2 db 'of low-level programming language'
    string3 db 'that is intended to communicate directly'
    string4 db 'with a computers hardware'
    OLD_CS dw ? 
    OLD_IP dw ? 
data ends

code segment 
    assume cs:code, ds:data
    
    NEW_5 proc far 
        push ax     
        push bx
        push cx
        push dx
        push ds
        push es

        mov ax, data    
        mov ds, ax      
        mov ax, 0B800h  
        mov es, ax      

        cmp DIRECT, 0   
        jnz vertical    
        
        mov cx, 2000    
        xor si, si      

    video:
        mov ax, VIDEO_BUF[si]   
        mov es:[si], ax         
        inc si                  
        inc si                  
        loop video                                                      
        inc DIRECT              
        jmp back                


    vertical: 
        xor si, si            
        mov bx, 1999*2     
        mov cx, 25         
    video_ext:
        push cx             
        sub bx, 1999*2      
        mov cx, 80          
    video_in:
        mov ax, VIDEO_BUF[bx]   
        mov es:[si], ax         
        inc si                  
        inc si                  
        add bx, 25*2            

        loop video_in           
        pop cx                  

        loop video_ext          

        dec DIRECT             

    back:
        pop es             
        pop ds
        pop dx
        pop cx
        pop bx
        pop ax
        iret                
    NEW_5 endp

    
    CLS proc near
        push cx             
        push ax
        push si
        xor si, si          
        mov ah, 7           
        mov al, ' '         
        mov cx, 2000        
    CL1:
        mov es:[si], ax     
        inc si              
        inc si             
        loop CL1            
        pop si             
        pop ax
        pop cx
        ret                
    CLS endp               

    
    start:
        mov ax, DATA       
        mov ds, ax          

       
        mov ah, 02h         
        mov dh, 25         
        int 10h            

        
        mov ah, 35h         
        mov al, 5h          
        int 21h            
        mov OLD_IP, bx      
        mov OLD_CS, es      
        
        
        push ds             
        mov dx, offset NEW_5    
        mov ax, seg NEW_5      
        mov ds, ax              
        mov ah, 25h            
        mov al, 5h             
        int 21h                 
        pop ds                 
        mov ax, 0B800h          
        mov es, ax              
        call CLS                
        mov ah, 00000111b       

        
        mov cx, 30              
        mov si, 0               
        xor bx, bx              

    first:
        mov al, string1[bx]     
        mov VIDEO_BUF[si], ax   
        inc si                  
        inc si                  
        inc bx                  
        loop first              

        
        mov cx, 33              
        mov si, 80*2            
        xor bx, bx             

    second:
        mov al, string2[bx]     
        mov VIDEO_BUF[si], ax   
        inc si                  
        inc si                  
        inc bx                  
        loop second             

        
        mov cx, 40              
        mov si, 160*2           
        xor bx, bx             
    
    third:
        mov al, string3[bx]     
        mov VIDEO_BUF[si], ax   
        inc si                  
        inc si                  
        inc bx                 
        loop third              

       
        mov cx, 25              
        mov si, 240*2           
        xor bx, bx              
    
    fourth:
        mov al, string4[bx]    
        mov VIDEO_BUF[si], ax   
        inc si                  
        inc si                  
        inc bx                  
        loop fourth             

    interrupt:
        int 5h                  
        mov ah, 0              
        int 16h                
        cmp al, 30h             
        jnz interrupt         

    quit:   
        call CLS                
        mov dx, OLD_IP          
        mov ax, OLD_CS          
        mov ds, ax              
        mov ah, 25h            
        mov al, 5h             
        int 21h                
        mov ax, 4c00h          
        int 21h               
        
CODE ends                       
end START

Не понимаю, как строки располагаются вертикально. Этот кусок кода:

    vertical: 
        xor si, si            
        mov bx, 1999*2     
        mov cx, 25         
    video_ext:
        push cx             
        sub bx, 1999*2      
        mov cx, 80          
    video_in:
        mov ax, VIDEO_BUF[bx]   
        mov es:[si], ax         
        inc si                  
        inc si                  
        add bx, 25*2            

        loop video_in           
        pop cx                  

        loop video_ext          

        dec DIRECT

Ответы (1 шт):

Автор решения: Виктор

В DOS разрешение в текстовом режиме по умолчанию 80×25

vertical: 
    xor si, si            
    mov bx, 1999*2     
    mov cx, 25         ;Количество строк
video_ext:
    push cx             
    ; На втором и последующих шагах
    ; смещаемся на один символ вправо
    ; в буфере из которого выводим
    sub bx, 1999*2     
    mov cx, 80         ;Количество столбцов 
video_in:
   ; Читаем из буфера значение символа (al) и его атрибут (цвет) (ah)
    mov ax, VIDEO_BUF[bx]
    ; Выводим на экран по адресу B800:si <- ax
    mov es:[si], ax
    ; Смещаем позицию на экране на одну вправо si = si + 2
    inc si                  
    inc si                  
    ; Cмещаем позицию в буфере, из которого выводим,
    ; на 25 символов 
    ; Попадаем на символ для второго столбца и т.д.
    ; отображаем всю строку
    ; (25*2 - так как в буфере лежат данные с атрибутами)
    add bx, 25*2            

    loop video_in           
    pop cx                  

    loop video_ext          

    dec DIRECT             

PS: В прерывании int 5 надо сохранять и восстанавливать регистр SI

→ Ссылка