Мое первое впечатление от вашего кода и то, что вызвало мой первый комментарий, заключалось в том, что вы, возможно, использовали неправильный цвет переднего плана и фона. Ты имел:
MOV BH,07h
Который светло-серый на черном. Белое на синем было бы:
MOV BH,1fh
Информацию об атрибутах цвета BIOS можно найти здесь.
Ваш вопрос неоднозначен, однако код в этом примере обновит цвет фона текущего текстового режима, но сохранит цвет и символ переднего плана. Я предполагаю, что текстовый режим 80x25 перед запуском screen1
.
Эта программа обновляет память дисплея напрямую. Страница 0 текстовых режимов обычно начинается с физического адреса 0xB8000. Я установил для ES значение 0xB800, чтобы обновлять видео, потому что 0xB800:0x0000 пара сегмент:смещение совпадает с физическим адресом (0xB800‹‹4)+0x0000=0xB8000.
Каждый символ на экране занимает 2 байта (или одно 16-битное слово). Текстовый режим 80x25 — это 2000 ячеек (по 2 байта) или всего 4000 байт видеопамяти. Символ находится в первом байте, а атрибут — во втором байте. Дополнительную информацию об этом макете видео можно получить здесь.
Следующий код считывает каждый атрибут для каждого символа на экране, очищает цвет фона (старшие 4 бита), а затем устанавливает для этих старших 4 бит новый цвет фона. 0x01 — синий цвет. После обновления цвета фона код записывает новый атрибут обратно в видеопамять.
TITLE screen1.ASM
.MODEL SMALL
.STACK 0100h
.DATA
.CODE
start:
MOV AX,@DATA
MOV DS,AX
MOV AX,0B800h
MOV ES,AX ; Set ES to text video memory segment
MOV SI,1 ; Attributes are on odd addresses
MOV CX,2000 ; 2000 2-byte cells on an 80x25 display
L1:
MOV AL,ES:[SI] ; Get cell attribute
AND AL,0Fh ; Clear the current background
OR AL,10h ; Set the background to 1 (1=blue)
MOV ES:[SI],AL ; Update the attribute on screen with new background color
ADD SI,2 ; Go to next cell's attribute
DEC CX
JNZ L1 ; Loop for entire display
MOV AH,02h
MOV BH,00h
MOV DH,0Ch
MOV DL,28h
INT 10h ; Set cursor
MOV AH,02h
MOV DL,'x'
INT 21h ; Write character at cursor using the current
; foreground and background colors at that position
MOV AX,4C00h
INT 21h ; Exit Program
END start
Пример экрана перед запуском этой программы:
И после:
Весь текст (и цвета переднего плана) сохраняются, а цвет фона обновляется.
Цикл в коде, выполняющий обновление цвета фона, можно было бы записать так:
MOV AX,0B800h
MOV ES,AX ; Set ES to text video memory segment
MOV SI,4000 ; 4000 bytes with each screen cell on an 80x25 display
; taking 2 bytes each. 80*25*2 = 4000
L1:
MOV AL,ES:[SI-1] ; Get cell attribute
AND AL,0Fh ; Clear the current background color bits
OR AL,10h ; Set the background color bits to 1 (1=blue)
MOV ES:[SI-1],AL ; Update the attribute with new background color
SUB SI,2 ; Go to next cell (move backwards)
JG L1 ; Loop for entire display
Код в моем исходном примере может быть легче понять, если вы новичок в сборке x86.
Обновить цвета переднего плана и фона для всего экрана
Если вам не нужно сохранять цвет переднего плана для каждого символа на экране, вы можете просто обновить атрибуты новым значением и сохранить существующий символ. Цикл в моем первом примере кода можно изменить так, чтобы он выглядел так:
MOV AX,0B800h
MOV ES,AX ; Set ES to text video memory segment
MOV SI,4000 ; 2000 2-byte cells on an 80x25 display
L1:
MOV BYTE PTR ES:[SI-1],01Fh
; Set attribute to 1F (1=blue background, F=white foreground)
SUB SI,2 ; Go to next attribute(backwards)
JG L1 ; Loop for entire display
Это изменило бы все символы на экране на белые на синем и выглядело бы примерно так:
Очистить весь экран без прерывания BIOS
Для полноты картины также можно очистить весь экран персонажем. Символ пробел действует как символ очистки. Мы можем обновить символ и атрибут, используя REP STOSW. Мы хотим двигаться вперед по памяти с помощью STOSW, поэтому мы устанавливаем флаг направления вперед, используя КЛД. STD перемещался бы назад по памяти. STOSW описывается как:
REP STOS m16 Fill (E)CX words at ES:[(E)DI] with AX.
Код для очистки экрана с синим фоном и белым передним планом можно сделать примерно так:
MOV AX,0B800h
MOV ES,AX ; Set ES to text video memory segment
XOR DI,DI ; Starting offset = 0 for STOSW
MOV CX,2000 ; 2000 2-byte (16-bit WORD) cells on an 80x25 display
MOV AX,1F20h ; 20h = ASCII value for space character
; 1Fh = attribute (white on blue)
CLD ; Set direction flag forward (used by STOSW etc)
REP STOSW ; Copy AX (attribute and char) to ES:DI, Repeat CX (2000) times
Этот код эквивалентен вашему коду, который использовал службы видео BIOS:
MOV AX,0600h
MOV BH,1Fh
MOV CX,0000h
MOV DX,184Fh
INT 10h
Вывод программы с этим кодом выше будет выглядеть так:
person
Michael Petch
schedule
25.03.2016
MOV BH,17h
вместоMOV BH,07h
. Верхние 4 бита — цвет фона (1 = синий), нижние 4 бита — цвет переднего плана (символа). (7=белый) - person Michael Petch   schedule 25.03.2016video mode
не выбран. Независимо от того, какой цвет присутствует вbh
, он не будет отображаться, пока не будет выбран режим видео. - person Hamza Anis   schedule 25.03.2016int 10h
, если это текстовый режим. - person Hamza Anis   schedule 25.03.2016int 10h
отлично работает в текстовом режиме. Несмотря на то, что использование BIOS происходит медленно (по сравнению с непосредственным обновлением видеодисплея), оно все же вполне приемлемо. - person Michael Petch   schedule 25.03.2016