Вопрос № 29958: Доброе время суток, уважаемые эксперты!!
Объясните мне, чайнику, почему моя прога не работает. Только не очень заумно и сильно не смейтесь, я ещё в начале пути!
C уважением, Macshm...
Вопрос № 29.958
Доброе время суток, уважаемые эксперты!!
Объясните мне, чайнику, почему моя прога не работает. Только не очень заумно и сильно не смейтесь, я ещё в начале пути!
C уважением, Macshm
Приложение:
Отправлен: 21.11.2005, 18:26
Вопрос задал: Macshm (статус: Посетитель)
Всего ответов: 3 Мини-форум вопроса >>> (сообщений: 0)
Отвечает: Евгений Иванов
Здравствуйте, Macshm!
поставь
sub di,di
mov es:[di],ax
--------- Что имеем - не храним, потерявши - плачем
Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 21.11.2005, 18:48
Отвечает: Юра Устинов
Здравствуйте, Macshm!
.model small
.code
org 100h
start:
xor di,di
call Fi ; в ax нажатая клавиша?
cmp al,32
je con
push ax ;сохраняем
mov ax,03h
int 10h
mov ax,0b800h
mov es,ax
pop ax
mov ah,1 ;извлекаем
mov es:[di],ax ;печатаем в
jmp start ;видеобуфер,правильно?
con:
ret
Fi proc
mov ah,10h
int 16h
ret
Fi endp
end start
--------- Спасём Россию!!!
Ответ отправил: Юра Устинов (статус: 6-ой класс)
Отправлен: 21.11.2005, 19:19
Отвечает: Ayl
Здравствуйте, Macshm!
Мда, два ответа - и оба наполовину :-(
Если ты объединишь идеи из них, то получишь правильную программу.
Объясняю твои недочеты.
1. При старте программы из ДОСа (не из-под отладчика!) регистры не обнуляются, а инициализируются определенными значениями. В частности, регистр DI имеет значение FFFE. При попытке записи в видеобуфер без изменения значения этого регистра ты выводишь информацию по адресу B800:FFFE, т.е. за пределы отображаемой части буфера (для нулевой страницы в 3-ем режиме видеобуфер отображается в диапазоне адресов от B800:0000 до B800:07FF. Т.е. перед выводом нужно установить новое значение регистра DI из этого диапазона,
например, обнулить его. Сделать это можно так, как предложил эксперт Евгений Иванов:
sub di, di
Подойдут также команды:
xor di, di
mov di, 0
and di, 0
и т.п.
2. После выполнения функции 10h прерывания 16h в регистр AX будет записана следующая информация:
AL - ASCII-код нажатой клавиши или 0 для расширенных кодов
AH - скен-код нажатой клавиши
При выводе на экран в текстовом режиме записываются 2 байта: по четному адресу - код символа, по нечетному - аттрибут. Аттрибут представляет собой байт следующего вида:
BFFFICCC, где B - бит мерцания/повышенной интенсивности фона, FFF - три бита, задающие цвет фона, I - бит повышенной интенсивности цвета символа, CCC - три бита, задающие цвет символа.
Использовать в качестве аттрибута скен-код нажатой клавиши, конечно, можно, но результат может быть неожиданным. От не очень удачного сочетания цветов до вывода символа с тем же цветом, что и фон (т.е. символ станет неразличим от фона). То есть, нужно использовать какой-нибудь определенный аттрибут. Например, стандартный 0fh - белый текст на черном фоне. Предлагаемый экспертом Юрой Устиновым аттрибут 1 на мой взгляд не очень удачен, т.к. он соответствует темно-синим символам на черном фоне, что не очень хорошо
для глаз.
При нажатии на клавиши, которые порождают расширенные коды (F1-F12, Alt+символ, клавиши управления курсором и т.п.) в регистре AL будет находиться 0. Выводить на экран символ с кодом 0 немного странно, т.к. он будет пустым. В этом случае лучше выводить скен-код.
В приложении см. поправленный код.
Кстати, установку режима и сегментного регистра, указывающего на видеопамять, я вынес за цикл, т.к. их не нужно каждый раз переустанавливать. Т.к. вывод всегда будет производиться в левый верхний угол экрана, то очищать экран не нужно.
Приложение:
--------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени
Ответ отправил: Ayl (статус: Профессор)
Отправлен: 22.11.2005, 12:48