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