Изменение цветас строк при нажатии PrintScreen в ассемблере tasm
Нужна помощь с кодом, строки просто не выводятся при запуске, не говоря уже о изменении цвета. Вот код:
.model small
.stack 100h
.data
msg1 db 'This program is designed to display lines on the screen', 0
msg2 db 'And their color changes when you press PrintScreen', 0
msg3 db 'By changing their attribute in a cycle from 1 to 15', 0
msg4 db 'Each press of Print Screen changes the attribute', 0
attribute db 14
msg1_len = $ - msg1
msg2_len = $ - msg2
msg3_len = $ - msg3
msg4_len = $ - msg4
OLD_CS dw ? ; адрес сегмента старого вектора 1Сh
OLD_IP dw ? ; адрес смещения старого вектора 1Сh
.code
mCLS macro
push ax ; Сохранение регистров, используемых в макросе, в стек
push bx
push cx
push dx
mov ah, 10h
mov al, 3h
int 10h ; Включение режима видеоадаптора с 16-ю цветами
mov ax, 0600h ; ah = 06 - прокрутка вверх
; al = 00 - строки появляются снизу и заполняются нулями
mov bh, 00011110b ; 0001 - синий (фон), 1110 - желтый (текст)
mov cx, 0000b ; ah = 00 - строка верхнуго левого угла
; al = 00 - столбец верхнего левого угла
mov dx, 184Fh ; dh = 18h - строка нижнего правого угла
; dl = 4Fh - столбец нижнего правого угла
int 10h ; Очистка экрана и установка цветов фона и текста
mov dx, 0 ; dh - строка, dl - столбец
mov bh, 0 ; Номер видео-страницы
mov ah, 02h ; 02h - функция установки позиции курсора
int 10h ; Устанавливаем курсор на позицию (0, 0)
pop dx ; Перенос сохранённых значений обратно в регистры
pop cx
pop bx
pop ax
endm mCLS
ChangeAttribute macro attribute1
cmp attribute, 15
je resetattribute
cmp attribute, 15
jne incremattribute
resetattribute:
mov attribute1, 1
incremattribute:
INC attribute1
endm ChangeAttribute
NEW_5 proc far
push ax
push bx
push cx
push dx
push ds
push es
mov ax, @data
mov ds, ax ; Don't forget to initialize DS!
mov es, ax ; Segment needed for Int 10h/AH=13h
ChangeAttribute attribute
lea bp, msg1 ; ES:BP = Far pointer to string
mov cx, msg1_len ; CX = Length of string
mov bl, attribute ; green
call print
lea bp, msg2 ; ES:BP = Far pointer to string
mov cx, msg2_len ; CX = Length of string
mov bl, attribute ; blue
call print
lea bp, msg3 ; ES:BP = Far pointer to string
mov cx, msg3_len ; CX = Length of string
mov bl, attribute ; red
call print
lea bp, msg4 ; ES:BP = Far pointer to string
mov cx, msg4_len ; CX = Length of string
mov bl, attribute ; red
call print
back:
pop es
pop ds
pop dx
pop cx
pop bx
pop ax
iret
NEW_5 endp
print PROC ; Arguments:
; ES:BP Pointer to string
; CX Length of string
; BL Attribute (color)
push cx ; Save CX (needed for Int 10h/AH=13h below)
mov ah, 03h ; VIDEO - GET CURSOR POSITION AND SIZE
xor bh, bh ; Page 0
int 10h ; Call Video-BIOS => DX is current cursor position
pop cx ; Restore CX
mov ah, 13h ; VIDEO - WRITE STRING (AT and later,EGA)
mov al, 1 ; Mode 1: move cursor
xor bh, bh ; Page 0
int 10h ; Call Video-BIOS
ret
print ENDP
start:
mov ax, @data
mov ds, ax
mov ax, 0
;Очистить экран
mov ah, 06h
mov al, 0 ; Значение 0 очищает экран
int 10h
;Вывести строки с атрибутом 14
mov ah, 09h
lea dx, msg1
mov bh, 0 ; Страница
mov bl, attribute
int 21h
lea dx, msg2
mov ah, 09h
int 21h
lea dx, msg3
mov ah, 09h
int 21h
lea dx, msg4
mov ah, 09h
int 21h
; Перехватить прерывание печати экрана (Int 5h)
mov ah, 25h
mov al, 00h
mov dx, offset NEW_5
mov ax, seg NEW_5
int 15h
mCLS
mov dx, OLD_IP
mov ax, OLD_CS
mov ds, ax
mov ah, 25h
mov al, 1Ch
mov ax, 4c00h
int 21h
end start
end
Ответы (1 шт):
Автор решения: PRODIGY
→ Ссылка
Для печати текста в цвете лучше использовать "прямой вывод в видеобуфер", который в TXT-режиме в/адаптера находится в сегменте 0xB800. Для каждого символа в этом буфере отводится по 2-байта: первый = код символа, второй = цвет его фона/текста. У меня нет тасма, поэтому пример привожу на фасме. Перехват прерывания INT-5h не будет работать на вирт.машинах и эмуляторах - нужен только чистый дос. Восстановление вектора(5) здесь упущено:
org 100h ; *.com file
jmp start
msg db 'Hello World! 123456789' ; строка для вывода,
len = $ - msg ; ..и её длина.
;//-----------
PrintString: ; Процедура вывода строк в видео-буфер
push es 0xb800 ; сегмент в/буфера,
pop es ; ..в регистре ES.
xor di,di ; смещение в в/буфере = 0 (верхний/левый угол экрана)
mov si,msg ; адрес строки
mov cx,len ; её длина
@@: lodsb ; очередной символ из DS:SI
stosw ; записать как 2-байта в ES:DI (второй байт с цветом передаётся аргументом)
loop @b ; повторить СХ-раз..
pop es ; восстановить ES
ret ;
;//-----------
start: mov ax,3 ; текстовый режим: 80х25/16 цветов
int 10h ;
mov ah,0111b ; цвет символа/фона = серый на чёрном
call PrintString ; зовём процедуру печати оригин строки!
mov ax,0x2505 ; перехват прерывания INT-5h
mov dx,newInt5 ; адрес нового обработчика
int 21h ;
xor ax,ax ; ждать любую клавишу,
int 16h ; ..через сервис клавиатуры.
ret ; выход из com-программы.
newInt5: ; новый обработчик INT-5h "PrintScreen"
mov ah,0100b ; меняем цвет символа = красный на чёрном фоне
call PrintString ; печать!
iret ; interrupt return