Как менять цвет фона в консоли, нажатием клавиши? (TASM) - Assembler
Формулировка задачи:
Здравствуйте, уважаемые жители форума. Помогите пожалуйста с исправлением этой программы или написанием новой. Программа должна менять цвет фона консоли ( при этом не очищая консоль) по нажатию клавиши ( например пробела). В этом коде неправильно работает цикл ( он не работает как таковой), и цвет меняется не попорядку. Можете, пожалуйста, объяснить что исправить или как лучше вообще сделать? Крайне желательно сделать именно на TASM ибо в других я не работал и не понимаю их код.
MODEL small
stack 100h
.code
main:
;---установка 16 фоновых цветов в текстовом режиме 80*25
MOV AL,00000000B ;установка в 0 бита мигания
MOV DX,3D8H ;адрес регистра
OUT DX,AX ;посылаем в регистр
;---инициализируем весь экран в красный на светлосинем фоне
MOV AX,0B800H ;указываем на видеобуфер
MOV ES,AX ;
MOV CX,3000 ;записываем атрибут в 2000 ячеек
xor BX,BX
MOV BX,1 ;BX указывает на байт атрибутов
add AL,00010000B ;значение байта атрибутов
jmp NEXT_CHAR
NEXT_CHAR: MOV ES:[BX],AL ;посылаем атрибуты в буфер
INC BX ;увеличиваем указатель на атрибуты
INC BX ;
LOOP NEXT_CHAR ;пишем в следующую позицию
jmp cycle
cycle:
;xor AH,AH
;xor AL,AL
mov ah, 0 ; функция чтения с клавиатуры
int 16h ; прерывание dos- ждём нажатие
cmp ah, 01h ; esc нажата (сравнивание значений не нажатой клавиши с нажатой клавишей esc)
je stop ; если нажата - выход
cmp ah, 39h ; пробел нажат
jne cycle ; если не пробел - пропустить
;je main
add AL, 00010000b
;INC AL
;xor BX,BX
jmp NEXT_CHAR
stop:
mov ax, 4C00h ; выход в dos
int 21h ; прерывание dos-закрыть программу
end mainРешение задачи: «Как менять цвет фона в консоли, нажатием клавиши? (TASM)»
textual
Листинг программы
.model small .stack .code ; org 100h main: mov bl, 10h ;1 mov ax, 0B800h mov ds, ax mov es, ax again: xor ah, ah ; функция чтения с клавиатуры int 16h ; прерывание dos- ждём нажатие cmp ah, 01h ; esc нажата (сравнивание значений не нажатой клавиши с нажатой клавишей esc) jz gtfo ; если нажата - выход cmp ah, 39h ; пробел нажат jnz again ; если не пробел - пропустить ; xor si, si xor di, di mov cx, 80*25 next: lodsw mov ah, bl stosw loop next add bl, 10h ; inc bl jmp again gtfo: mov ax, 4C00h ; выход в dos int 21h ; прерывание dos-закрыть программу end main
Объяснение кода листинга программы
- Установка начального значения переменной BL - 10h.
- Установка сегментов данных и стека на сегментный адрес 0B800h.
- Проверка нажатия клавиши Esc (сравнение AH с 01h). Если это так, то переход к метке gtfo.
- Проверка нажатия клавиши пробел (сравнение AH с 39h). Если это не так, то переход к метке again.
- Установка начальных значений для SI и DI.
- Установка значения CX равным 80*25 (это 2000).
- Чтение пары байт из памяти в переменные AL и AH (LODSW).
- Установка значения AH равным значению BL.
- Запись пары байт в память (STOSW).
- Выполнение цикла 2000 раз (LOOP next).
- Увеличение значения BL на 10h (ADD BL, 10h).
- Инкремент значения BL (INC BL).
- Переход к метке again.
- Выход в DOS (AX = 4C00h), закрытие программы (INT 21h).
- Конец программы (END main).