Zemskov_my_sppo1
.pdfЮ.В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
6.Распределённые вычислительные системы
Распределённая система (РС) (distributed system) — состоящая из нескольких взаимодействующих процессов.
Примеры РС: распределённая информационная система предприятия; World Wide Web; система электронной почты (SMTP); SETI@Home; сетевая игра.
Основная цель: обеспечить коммуникацию между пользователями и ресурсами.
Преимущества: оптимальное распределение ресурсов и, как следствие, экономичность; совместное использование информации.
Недостатки: требуется обеспечение безопасности и секретности.
Прозрачность: пользователю не надо знать архитектуру РС. Типы прозрачности: а) прозрачность доступа к ресурсу; б) прозрачность размещения ресурса; в) миграционная прозрачность (ресурс может перемещаться, в том числе во время его использования).
Переносимость: приложение может функционировать на другой системной (программной и/или аппаратной платформе).
Совместимость: различные приложения могут взаимодействовать друг с другом.
Гибкость: приложение должно состоять из отдельных небольших компонент, тогда эти компоненты легко адаптировать к параллельной среде и изменять.
Масштабируемость: возможность изменения размеров РС, её локализации, модификации аппаратных ресурсов.
Software Engineering: технология создания программных средств.
Основные стадии проектирования программного обеспечения: анализ, разработка (подробное опи-
сание архитектуры и взаимодействия программных компонентов), реализация (написание программного кода), испытание, эксплуатация.
Объектно-ориентированное и компоненториентированное программирование (повторное использование кода).
Пять правил Бертрана Мейера (B. Meyer): 1) прямое отображение (структура системы должна следовать структуре проблемной области); 2) минимум связей (каждый модуль должен взаимодействовать с минимально возможным числом других модулей); 3) минимум взаимодействий (если два модуля взаимодействуют друг с другом, то они должны обмениваться минимально возможным количеством информации); 4) явные связи (всякий раз, когда два модуля взаимодействуют, это должно быть очевидно из текста программного кода по крайней мере одного из них); 5) сокрытие информации (некоторые свойства программного модуля должны предоставлять информацию о том, как с ним можно взаимодействовать).
Пять требований Б. Мейера: 1) прозрачностиь типов (любая процедура должна проектироваться так, чтобы её можно было использовать для обработки данных других типов без изменения кода); 2) группирование процедур (связанные в том или ином смысле процедуры образуют программный модуль); 3) вариантность (различные возможности реализации алгоритмов должны покрываться семейством модулей); 4) независимость представления (клиент должен иметь возможность использовать сервисы модуля без знания того, как эти сервисы реализуются); 5) общность поведения (при реализации модулей должны по возможности использоваться одни и те же структуры данных и алгоритмы).
53
Ю.В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
7.Программирование операций ввода-вывода на ассемблере
7.1.Вывод на экран в текстовом режиме
7.1.1.Средства DOS
Операционная система DOS (а также Windows) представляет прикладным программам следующие сервисы по выводу символов на экран, доступные через прерывание 21h:
1. Функция DOS 02h. Запись символа на стандартное устройство вывода (STDOUT). Вход: AH = 02h; DL = ASCII-код символа.
Выход: AL = код последнего записанного символа (равен DL, кроме случая, когда DL=09h (табуляция), тогда в AL возвращается 20h).
Примечания: 1) при нажатии на Ctrl+Break генерируется прерывание 23h, обработчик которого по умолчанию осуществляет выход из текущей программы; 2) данная функция обрабатывает некоторые управляющие символы, например, при выводе символа BEL (07h) генерируется звуковой сигнал, BS (08h) — курсор перемещается влево на одну позицию, HT (09h) — табуляция (несколько пробелов), CR (0dh) — переход на начало текущей строки.
В листинге 7.1 приведён пример программы, осуществляющей вывод на экран всех ASCII-символов.
Листинг 7.1. Вывод на экран всех ASCII-символов с использованием функции DOS 02h
;ascii1.asm
;Вывод на экран таблицы ASCII-кодов
|
.model |
tiny |
|
; модель памяти для .COM-программ: всё в одном сегменте |
||
|
.code |
|
|
; начало сегмента кода |
||
|
org |
100h |
|
; начальный адрес кода для .COM-программ |
||
start: |
mov |
cx, |
256 |
; вывести 256 символов |
||
|
mov |
dl, |
0 |
; первый символ -- с кодом 0 |
||
|
mov |
ah, |
2 |
; номер функции DOS "вывод символа" |
||
lp1: |
int |
21h |
; вызов системной функции DOS (вывод символа на экран) |
|||
|
inc |
dl |
|
; код следующего символа |
||
|
test |
dl, |
0fh |
; если DL не кратен 16, |
||
|
jnz |
lp2 |
|
; |
то продолжить цикл |
|
|
push |
dx |
|
; иначе сохранить код текущего символа в стеке |
||
|
mov |
dl, |
0dh |
; код символа ‘переход в начало текущей строки’ |
||
|
int |
21h |
|
; вывод символа на экран |
||
|
mov |
dl, |
0ah |
; код символа ‘переход на новую строку’ |
||
|
int |
21h |
|
; вывод символа на экран |
||
|
pop |
dx |
|
; восстановили код текущего символа их стека |
||
lp2: |
loop |
lp1 |
|
; переход на начало цикла |
||
|
ret |
|
|
; завершить .COM-программу |
||
end |
start |
|
|
; конец программы |
|
|
; |
|
|
|
|
|
|
; Компиляция: tasm ascii1.asm |
или |
ml /c ascii1.asm |
||||
; Компоновка: tlink /t /x ascii1.obj |
link ascii1.obj,,NUL,,, |
|||||
; (/t --- COM; |
/x |
--- |
no MAP-file) |
exe2bin ascii1.exe ascii1.com |
||
; Для перенаправления вывода командная строка: ascii1.com > 1.txt |
||||||
|
|
|||||
2. Функция DOS 06h. |
Запись символа на стандартное устройство вывода (STDOUT). |
Вход: AH = 06h; DL = ASCII-код символа (кроме 0ffh). Выход: AL = код последнего записанного символа (равен DL).
Примечания: никакие управляющие символы не обрабатываются; нажатие на Ctrl+Break не проверяется.
Замените в листинге 7.1 номер функции с 02h на 06h и увидите изображения управляющих символов. 3. Функция DOS 09h. Запись строки на стандартное устройство вывода (STDOUT).
Вход: AH = 09h; DS:DX = адрес строки (сама строка должна оканчиваться символом “$”). Выход: AL = код последнего записанного символа (24h).
Примечания: работает аналогично функции 02h, но выводится строка, а не символ.
В листинге 7.2 приведён пример .COM-программы, осуществляющей вывод строки на экран, а в листинге 7.3 — пример .EXE-программы, делающей то же самое.
4. Функция DOS 40h. Запись строки на стандартное устройство вывода или в файл.
Вход: AH = 40h; BX = 1 для STDOUT или 2 для STDERR; DS:DX = адрес начала строки; CX = длина строки (байт).
Выход: CF = 0; AX = число записанных символов. Примечание: перенаправление вывода невозможно.
54
Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Листинг 7.2. Вывод строки на экран с использованием функции DOS 09h (программа типа COM)
;hello1.asm
;Выводит на экран сообщение "Hello World!" и завершается
.model tiny |
; модель памяти, используемая для .COM |
|
.code |
; начало сегмента кода |
|
org 100h |
; адрес начала кода для программ .COM |
|
start: |
|
|
mov ah,9 |
; номер функции DOS |
|
mov dx, offset msg |
; адрес строки |
|
int 21h |
; вызов системной функции DOS |
|
ret |
; завершение .COM-программы |
; сообщение, переход в начало строки, переход к новой строке, терминатор: msg db ’Hello World!’,0Dh,0Ah,’$’
end start |
; конец программы |
; |
|
; Компиляция: |
|
; TASM: |
tasm /m hello1.asm |
; |
tlink /t /x hello1.obj |
; |
|
; MASM: |
ml /c hello1.asm |
;link hello1.obj,,NUL,,,
;exe2bin hello1.exe hello1.com
; WASM: wasm hello1.asm
;wlink file hello1.obj form DOS COM
Листинг 7.3. Вывод строки на экран с использованием функции DOS 09h (программа типа EXE)
;hello2.asm
;Выводит на экран сообщение "Hello World!" и завершается
.model |
small |
; модель памяти, используемая для .EXE-программ |
|
.stack |
100h |
|
; размер сегмента стека в байтах |
.code |
|
|
; начало сегмента кода |
start: |
|
|
|
mov ax, DGROUP |
; вариант: mov ax, @data |
||
mov ds,ax |
|
; инициализировали регистр сегмента данных |
|
mov dx, offset msg ; адрес строки msg |
|||
mov ah,9 |
|
|
; функция DOS 09h "вывод строки" |
int 21h |
|
|
|
mov ax,4C00h |
|
; функция DOS 4ch "завершить программу" |
|
int 21h |
|
|
|
; |
|
|
|
.data |
|
; начало сегмента данных |
|
msg db ’Hello World!’,0Dh,0Ah,’$’ |
|||
end start |
; конец программы |
||
; |
|
|
|
; Компиляция: |
|
|
|
; TASM: |
|
tasm /m hello2.asm |
|
; |
|
tlink /x hello2.obj |
|
; |
|
|
|
; MASM: |
|
ml /c hello2.asm |
|
; |
|
link hello2.obj |
|
; |
|
|
|
; WASM: |
|
wasm hello2.asm |
|
; |
|
wlink file hello2.obj form DOS |
|
; |
|
|
|
|
|
|
|
55
Ю.В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Влистинге 7.4 приведён пример программы, которая выводит строку на экран. В самой строке может содержаться символ $, который служит терминатором (ограничителем) строки и не может быть выведен с помощью функции 09h.
Листинг 7.4. Вывод строки на экран с использованием функции DOS 40h
;str40h.asm
;Вывод на экран сообщения "Эта функция может выводить знак ‘$’ на экран"
|
.model |
tiny |
|
; модель памяти (для .COM-пограмм) |
|
|
.code |
|
|
; начало сегмента кода |
|
|
org 100h ; код всех COM-программ начинается с этого адреса |
||||
start: |
mov ah, |
40h |
; номер функции DOS для вывода на STDOUT или STDERR |
||
|
mov |
bx, |
2 |
; выводим на STDERR |
|
|
mov |
dx, |
offset msg ; адрес начала сообщения |
||
|
mov |
cx, |
msg_len |
; длина сообщения |
|
|
int 21h |
; вызов системной функции DOS (вывод строки на экран) |
|||
|
ret |
|
|
; конец .COM-программы |
|
msg |
db "Эта |
функция |
может выводить знак $" ; Текст сообщения |
||
msg_len |
= $ - msg ; |
длина сообщения в байтах |
|||
end |
start |
; |
конец программы |
||
|
|
|
|
|
|
7.1.2. Средства BIOS
Базовая система ввода–вывода (BIOS) представляет программам следующие сервисы по выводу на экран, доступные через прерывание 10h:
1. Функция BIOS 00h. Установка видеорежима.
Вход: AH = 00h; AL = номер видеорежима (младшие 7 бит); старший бит 0, если необходимо очистить экран, и 1 в противном случае.
Выход: нет.
Номера текстовых видеорежимов: 0 и 1 — 16-цветные текстовые режимы 40 25 (25 строк по 40 символов в каждой); 2 и 3 — 16-цветные текстовые режимы 80 25; 7 — монохромный режим 80 25. Обычный режим DOS — номер 3. Существуют и другие текстовые режимы. Графические режимы будут рассмотрены ниже.
2. Функция BIOS 4fh. Установка видеорежима SuperVGA.
Вход: AX = 4f02h; BX = номер видеорежима (младшие 13 бит); старший бит 0, если необходимо очистить экран, и 1 в противном случае.
Выход: нет.
Номера текстовых видеорежимов: 108h — 80 25; 109h — 132 25; 10ah — 132 43; 10bh — 132 50; 10ch — 132 60. Графические режимы будут рассмотрены ниже.
3. Функция BIOS 02h. Установка положения курсора.
Вход: AH = 02h; BH = номер страницы; DH = строка; DL = столбец. Выход: нет.
Отсчёт номера строки и столбца ведётся от верхней левой позиции (0; 0). Номера страниц: 0–3 для режимов 2 и 3; 0–7 для режимов 0 и 1 (страница — это область памяти, содержимое которой отображается в данный момент на экране). Текст можно выводить на неактивную страницу, а затем переключиться на неё, чтобы изображение появилось мгновенно.
4. Функция BIOS 03h. Узнать положение курсора. Вход: AH = 03h; BH = номер страницы.
Выход: DH = строка; DL = столбец; CH и CL = начальная и конечная строки, на которых может находиться курсор.
5. Функция BIOS 09h. Вывод символа с заданным атрибутом на экран (в текущую позицию курсора). Вход: AH = 09h; BH = номер страницы; AL = ASCII-код символа; BL = атрибут символа; CX =
сколько одинаковых символов вывести. Выход: нет.
Атрибут задаёт цвет фона и изображения: биты 0..2 — цвет символа;
бит 3 — символ яркого цвета или фон мигает (см. функцию 10h); биты 4..6 — цвет фона;
бит 7 — символ мигает или фон яркого цвета (см. функцию 10h). Номера цветов приведены в таблице 7.1.
6. Функция BIOS 08h. Считать символ и его атрибут в текущей позиции курсора.
56
Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Таблица 7.1. Кодирование цветов
Атрибут |
|
Обычный цвет |
Яркий цвет |
|
|
|
|
|
|
000 |
|
Чёрный |
Тёмно-серый |
|
001 |
|
Синий |
Светло-синий |
|
010 |
|
Зелёный |
Светло-зелёный |
|
011 |
|
Голубой |
Светло-голубой |
|
100 |
|
Красный |
Светло-красный |
|
101 |
|
Пурпурный |
Светло-пурпурный |
|
110 |
|
Коричневый |
Жёлтый |
|
111 |
|
Светло-серый |
Белый |
|
|
|
|
|
Вход: AH = 08h; BH = номер страницы.
Выход: AL = ASCII-код символа; AH = атрибут символа.
7.Функция BIOS 0ah. Вывести символ с текущим атрибутом на экран. Вход: AH = 0ah; BH = номер страницы; CX = число повторений символа. Выход: нет.
Выводимый символ будет иметь тот же атрибут, что и символ, ранее находившийся в данной позиции.
8.Функция BIOS 0eh. Вывести символ в режиме телетайпа.
Вход: AH = 0eh; BH = номер страницы; AL = ASCII-код символа. Выход: нет.
При достижении последней позиции нижней строки экран прокручивается вверх. Атрибуты символов остаются прежними. Символы CR, LF, BEL воспринимаются как управляющие.
9. Функция BIOS 13h. Вывести строку символов с заданными атрибутами.
Вход: AH = 13h; AL = режим вывода: бит 0: переместить курсор после вывода в конец строки; бит 1: строка содержит не только символы, но и атрибуты (т. е. каждый символ описывается двумя байтами); CX = длина строки (число символов); BL = атрибут (если строка содержит только символы); DH и DL = строка и столбец, с которых начнётся вывод строки; номер страницы; ES:BP = адрес начала строки.
Выход: нет.
Символы CR (0dh), LF (0ah), BS (08h), BEL (07h) воспринимаются как управляющие.
В листинге 7.5 приведена программа, которая выводит на экран все ASCII-символы, в том числе и изображения, соответствующие управляющим символам. При выводе используются только функции BIOS. Т. к. функция 09h сама не сдвигает курсор, то это приходится делать каждый раз специально.
7.1.3. Прямая запись в видеопамять
Видеопамять начинается с адреса 0b800h:0000h (для текстовых режимов) и заканчивается адресом 0b800h:0ffffh. Всё, что программа записывает в эту область памяти, немедленно пересылается в память видеоадаптера и отображается на экране. В текстовых режимах для хранения одного символа используются два смежных байта (сначала ASCII-код символа, затем его атрибут).
В листинге 7.6 приведён пример программы, которая выводит все ASCII-символы на экран путём прямой записи в видеопамять. Здесь используются две 32-разрядные команды: mov eax, data и stosd (запись 4-байтного слова eax в строку, адрес которой указан в ES:DI, с инкрементом или декрементом индексного регистра di; направление задаётся командной cld — инкремент или sld — декремент), поэтому указана директива .386. При формировании 4-байтной последовательности (два символа с атрибутами) используется тот факт, что в процессорах Intel в памяти сначала хранятся младшие байты, а затем старшие.
7.2.Ввод с клавиатуры
7.2.1.Средства DOS
1.Функция DOS 0ah. Считать строку символов из STDIN.
Вход: AH = 0ah; DS:DX = адрес буфера; в первом байте буфера — его длина в байтах (от 0 до 254 байт).
Выход: буфер (начиная с третьего байта) содержит введённую строку; во втором байте — длина введённой строки (без учёта CR, которым закончился ввод).
В листинге 7.7 приведён пример программы, которая вводит строку (десятичное число), используя функцию DOS 0ah, переводит это число в шестнадцатеричное и выводит его на экран.
2. Функция DOS 01h. Считать символ из STDIN (c эхом, ожиданием и проверкой на Ctrl+Break). Вход: AH = 01h.
57
Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Листинг 7.5. Вывод строки на экран с использованием функций BIOS
; biosout.asm --- выводит на экран все ASCII-символы без исключения
.model |
tiny |
|
.code |
|
|
org 100h |
|
; Начало .COM-программы |
start: |
|
|
mov ax, 0003h |
||
int 10h ; Видеорежим 3 (очистка экрана и установка курсора в 0, 0) |
||
mov dx,0 |
; DH и DL будут использоваться для хранения позиции курсора |
|
mov si, 256 ; SI будет счётчиком цикла |
||
mov al,0 |
|
; Первый символ - с кодом 00h |
mov ah,9 |
|
; Номер функции "вывод символа с атрибутом" |
mov cx,1 |
|
; Выводится один символ |
mov bl,00011111b ; атрибут символа - белый на синем фоне |
||
cloop: |
|
|
int 10h |
; Вывести символ на экран |
|
push ax |
; Сохранить текущий символ и номер функции |
|
mov ah,2 |
; Номер функции 2 - изменить положение курсора |
|
inc dl |
; Увеличить текущий столбец на 1 |
|
int 10h |
; Переместить курсор |
|
mov ax,0920h ; AH = 09, AL = 20h (ASCII-код пробела) |
||
int 10h |
; Вывести пробел |
|
mov ah,2 |
; Номер функции 2 |
|
inc dl |
; Увеличить номер столбца на 1 |
|
int 10h |
; Переместить курсор |
|
pop ax ; |
Восстановить номер функции в AH и текущий символ в AL |
|
inc al |
; Увеличить AL на 1 - следующий символ |
|
test al,0Fh |
; Если AL не кратен 16, |
|
jnz continue_loop ; то продолжить цикл, |
||
push ax |
; а иначе сохранить номер функции и текущий символ |
|
mov ah,2 |
; Номер функции 2 |
|
inc dh |
; Увеличить номер строки на 1 |
|
mov dl,0 |
; Столбец = 0 |
|
int 10h |
; Установить курсор на начало следующей строки |
|
pop ax |
; Восстановить номер функции и текущий символ |
|
continue_loop: |
|
|
dec si |
; Уменьшить SI на 1, если он не стал нулём - продолжить |
|
jnz cloop |
; CX используется внутри цикла, так что нельзя |
|
|
|
; использовать команду LOOP для его организации |
ret |
; Завершение COM-программы |
|
end start |
|
|
|
|
|
58
Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Листинг 7.6. Вывод на экран с использованием прямой записи в видеопамять
;dirout.asm
;Выводит на экран все ASCII-символы, используя прямую запись в видеопамять
.model tiny
.code
.386 ; будет использоваться регистр EAX и команда STOSD org 100h ; начало .COM-программы
start: |
|
|
mov ax,0003h |
||
int 10h |
; |
видеорежим 3 (очистка экрана) |
cld |
; |
будем обрабатывать строки в прямом направлении |
|
; Подготовка данных для вывода на экран: |
|||
|
mov eax,1F201F00h ; первый символ 00 с атрибутом 1Fh, затем пробел (20h) с атрибутом 1Fh |
|||
|
mov bx,0F20h |
; пробел с атрибутом 0Fh |
||
|
mov cx,255 |
; число символов минус 1 |
||
|
mov di,offset ctable |
; ES:DI - начало таблицы |
||
cloop: |
|
|
|
|
|
stosd |
; записать символ и пробел в таблицу ctable |
||
|
inc al |
; AL содержит следующий символ |
||
|
test cx, 0Fh |
; если CX не кратен 16, |
||
|
jnz continue_loop ; то продолжить цикл, |
|||
|
push cx |
; а иначе сохранить значение счётчика, |
||
|
mov cx,80-32 |
; число оставшихся до конца строки символов, |
||
|
xchg |
ax, bx |
|
|
|
rep stosw ; заполнить остаток строки пробелами с атрибутом 0F |
|||
|
xchg bx, ax |
; восстановить значение EAX |
||
|
pop cx |
|
; восстановить значение счётчика |
|
continue_loop: |
|
|
|
|
|
loop cloop |
|
|
|
|
stosd |
|
; записать последний (256-й) символ и пробел |
|
; собственно вывод на экран: |
; сегментный адрес видеопамяти |
|||
|
mov ax,0B800h |
|||
|
mov es, ax |
|
|
|
|
xor di, di |
; DI = 0, адрес начала видеопамяти в ES:DI |
||
|
mov si,offset ctable ; адрес таблицы в DS:SI |
|||
|
mov cx,15*80+32 ; 15 строк по 80 символов, последняя строка - 32 |
|||
|
rep movsw ; скопировать таблицу ctable в видеопамять |
|||
|
ret |
; завершение .COM-программы |
||
ctable: |
; Здесь будут готовиться данные для вывода на экран. |
|||
|
; В EXE-файле такие данные определяют в сегменте .data |
|||
|
end start |
|
|
59
Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Листинг 7.7. Перевод десятичного числа в шестнадцатеричное
; dosin1.asm -- переводит десятичное число в шестнадцатеричное
|
.model |
tiny |
|
|
.code |
|
для команды shr al,4 |
|
.286 |
; |
|
|
org 100h |
; |
начало .COM-программы |
start: |
mov dx, offset message1 |
||
|
mov ah,9 |
|
вывести приглашение к вводу message1 |
|
int 21h |
; |
|
|
mov dx,offset buffer |
||
|
mov ah,0Ah |
|
|
|
int 21h |
; считать строку символов в буфер |
|
|
mov dx, |
offset crlf |
|
|
mov ah, |
9 |
|
|
int 21h |
; перевод строки |
; перевод числа в ASCII-формате из буфера в бинарное число в AX:
xor |
di,di |
|
; DI = 0 - номер байта в буфере |
xor |
ax,ax |
|
; AX = 0 - текущее значение результата |
mov |
cl,blength |
||
xor |
ch,ch |
|
|
xor |
bx,bx |
|
; SI - длина буфера |
mov |
si,cx |
|
|
mov |
cl,10 |
|
; CL = 10, множитель для MUL |
asc2hex: mov |
bl, byte ptr bcontents[di] |
||
sub |
bl,’0’ |
|
; цифра = код цифры - код символа "0" |
jb |
asc_error |
; если код символа был меньше, чем код "0", |
|
cmp |
bl,9 |
|
; или больше, чем "9", |
ja |
asc_error |
; то выйти из программы с сообщением об ошибке, |
|
mul |
cx |
; иначе: умножить текущий результат на 10, |
|
add |
ax, bx ; добавить к нему новую цифру, |
||
inc |
di |
; увеличить счётчик |
|
cmp |
di,si |
; если счетчик+1 меньше числа символов, |
|
jb |
asc2hex |
|
; то продолжить (считать начинаем с 0) |
; вывод на экран строки message2: |
|||
push ax |
|
; сохранить результат преобразования |
mov ah,9
mov dx,offset message2 int 21h
pop ax
; вывод на экран числа из регистра AX:
|
push ax |
|
|
; поместить в AL старший байт |
|
|
xchg ah,al |
|
|||
|
call print_al |
; вывести его на экран (вызов процедуры) |
|||
|
pop ax |
|
|
; восстановить в AL младший байт |
|
|
call print_al |
; вывести его на экран |
|||
|
ret |
|
; завершение COM-программы |
||
asc_error: mov dx,offset err_msg |
|||||
|
mov ah,9 |
; вывести сообщение об ошибке |
|||
|
int 21h |
|
|||
|
ret |
|
|
; и завершить программу |
|
; Процедура print_al. Выводит на экран число в регистре AL в шестнадцатеричном формате: |
|||||
print_al: mov dh,al |
; DH - младшие 4 бита |
||||
|
and dh,0Fh |
||||
|
shr al,4 |
; AL - старшие |
|||
|
call print_nibble |
; вывести старшую HEX-цифру |
|||
|
mov al,dh |
; теперь AL содержит младшие 4 бита |
|||
print_nibble: |
|
; процедура вывода 4 бит (шестнадцатеричной цифры) |
|||
|
cmp al,10 |
; три команды, переводящие цифру из AL |
|||
|
sbb al,69h |
; в соответствующий ASCII-код |
|||
|
das |
|
|
; BCD-коррекция после вычитания |
|
|
mov dl,al |
; код символа в DL |
|||
|
mov ah,2 |
; номер функции DOS в AH |
|||
|
int 21h |
|
; вывод символа |
||
|
ret |
|
; возврат из процедуры; работает два раза: один раз для возврата из процедуры print_nibble, |
||
|
|
|
; вызванной для старшей цифры, и второй раз - для возврата из print_al |
||
message1 db ’Enter decimal number: $’ |
|||||
message2 db ’Hex number is: $’ |
|||||
err_msg db |
’Bad number entered’ |
||||
crlf |
db |
0Dh,0Ah,’$’ |
|
||
buffer |
db |
6 |
; максимальный размер буфера ввода |
||
blength db |
? |
; размер буфера после считывания |
|||
bcontents: |
|
; содержимое буфера располагается за концом .COM-программы |
|||
end start |
|
|
|
|
60
Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Выход: AL = ASCII-код символа.
Если нажата клавиша, не соответствующая какому-нибудь символу (клавиша управления курсором, функциональная клавиша и т. д. ), то в регистре AL возвращается 0 и данную функцию надо вызвать ещё раз для получения второго байта кода нажатой клавиши. В трёх следующих вариантах этой функции код символа возвращается в AL по такому же принципу.
3.Функция DOS 08h. Считать символ из STDIN (без эха, с ожиданием и проверкой на
Ctrl+Break). Вход: AH = 08h.
Выход: AL = ASCII-код символа.
4.Функция DOS 07h. Считать символ из STDIN (без эха, с ожиданием, без проверки на
Ctrl+Break). Вход: AH = 07h.
Выход: AL = ASCII-код символа.
5.Функция DOS 06h. Считать символ из STDIN (без эха, без ожидания, без проверки на
Ctrl+Break). Вход: AH = 06h.
Выход: DL = 0ffh; если не была нажата клавиша, то AL=0 и флаг нуля установлен; если клавиша была нажата, то AL = ASCII-код символа.
6.Функция DOS 0bh. Проверить состояние клавиатуры.
Вход: AH = 0bh.
Выход: AL = 0, если не была нажата клавиша; AL=0ffh, если клавиша была нажата. 7. Функция DOS 0ch. Считать символ и очистить буфер клавиатуры.
Вход: AH = 0ch; AL = номер функции DOS (01, 06, 07, 08, 0ah). Выход: зависит от выбранной функции.
7.2.2.Средства BIOS
1.Функции BIOS 0, 10h, 20h. Чтение символа с ожиданием.
Вход: AH = 00h (клавиатура 83/84-key), 10h (101/102-key) или 20h (122-key).
Выход: AL = ASCII-код символа, 0 или префикс скан-кода; AH = скан-код нажатой клавиши или расширенный ASCII-код.
2. Функции BIOS 1, 11h, 21h. Проверка буфера клавиатуры.
Вход: AH = 01h (клавиатура 83/84-key), 11h (101/102-key) или 21h (122-key).
Выход: флаг нуля ZF=1, если буфер пуст; ZF=0, если буфер не пуст, тогда AL = ASCII-код символа, 0 или префикс скан-кода; AH = скан-код нажатой клавиши или расширенный ASCII-код.
Сам символ при этом остаётся в буфере (бывают исключения для расширенных кодов, отсутствующих на 84-клавишных клавиатурах).
3. Функция BIOS 05h. Поместить символ в буфер клавиатуры. Вход: AH = 05h; CH = скан-код; CL = ASCII-код.
Выход: AL = 0, если операция выполнена успешно; если буфер клавиатуры переполнен, то AL = 1.
7.3. Графические видеорежимы
7.3.1. Средства BIOS
Описанная выше функция BIOS 00h позволяет устанавливать не только текстовый, но и графический режим: 11h — для монохромного графического режима с разрешением 640 пиксел по горизонтали и 480 по вертикали; 12h — для 16-цветного режима 640 480; 13h — для режима 320 200, имеющего 256 цветов. Существуют также и другие графические режимы.
1. Функция BIOS 10h. Вывести точку на экран.
Вход: AH = 0ch; BH = номер видеостраницы (игнорируется для режима 13h, поддерживающего только одну страницу); DX = номер строки; CX = номер столбца; AL = номер цвета (для режимов 10h и 11h, если старший бит равен 1, то номер цвета точки будет результатом операции XOR с текущим цветом данной точки на экране).
Выход: нет.
2. Функция BIOS 0dh. Считать точку с экрана.
Вход: AH = 0dh; BH = номер видеостраницы (игнорируется для режима 13h, поддерживающего только одну страницу); DX = номер строки; CX = номер столбца.
Выход: AL = номер цвета.
В листинге 7.8 показан пример управления с клавиатуры положением точки на графическом экране.
61
Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.
Листинг 7.8. Управление с клавиатуры положением точки на графическом экране
|
.model tiny |
|
|
|
|
.code |
|
|
|
|
org 100h |
; |
Это .COM-программа |
|
start: |
mov ax, |
0011h ; |
Графический режим 11h, номер функции BIOS 00h |
|
|
int 10h |
|
; |
установили графический режим и очистили экран |
|
mov dx, |
480/2 ; |
начальная y-координата |
|
|
mov cx, |
640/2 |
; |
начальная x-координата |
|
mov bh, |
0 |
; |
страница 0 |
lp: |
mov ax, |
0c01h ; |
Номер цвета 01; номер функции BIOS 0ch |
|
|
int 10h |
|
; |
вывели точку |
waitkey: |
|
|
|
|
|
mov ah, |
07h |
; |
Номер функции DOS |
|
int 21h |
|
; |
Ждём нажатия на клавишу (без эха) |
|
cmp al, |
27 |
; |
если нажато ESC, |
|
je quit |
|
; |
то выход |
|
or al, al |
|
|
|
|
jne waitkey |
; |
нажата не стрелка |
|
|
int 21h |
|
; |
прочитали расширенный ASCII-код |
|
cmp al, |
4dh |
; |
стрелка вправо |
|
je right |
|
|
|
|
cmp al, |
4bh |
; |
стрелка влево |
|
je left |
|
|
|
|
cmp al, |
48h |
; |
стрелка вверх |
|
je up |
|
|
|
|
cmp al, |
50h |
; |
стрелка вниз |
|
je down |
|
|
|
|
jmp waitkey |
; |
снова ждать клавишу |
|
right: |
call hide |
; |
стереть точку со старого места |
|
|
cmp cx, |
639-8 |
|
|
|
ja lp |
|
; |
уже упёрлись в правый край |
|
add cx, |
8 |
; |
сдвинуть точку |
|
jmp lp |
|
; |
нарисовать точку на новом месте и всё сначала |
left: |
call hide |
|
|
|
|
cmp cx, |
8 |
|
|
|
jl lp |
|
; |
уже упёрлись в левый край |
|
sub cx, |
8 |
|
|
|
jmp lp |
|
|
|
up: |
call hide |
|
|
|
|
cmp dx, |
8 |
|
|
|
jl lp |
|
; |
уже упёрлись в верхний край |
|
sub dx, |
8 |
|
|
|
jmp lp |
|
|
|
down: |
call hide |
|
|
|
|
cmp dx, |
479-8 |
|
|
|
ja lp |
|
; |
уже упёрлись в нижний край |
|
add dx, |
8 |
|
|
|
jmp lp |
|
; |
Всё сначала |
hide: |
; подпрограмма для стирания точки со старого места |
|||
|
mov ax, |
0c00h |
|
|
|
int 10h |
|
|
|
|
ret |
; возврат из подпрограммы |
||
quit: |
ret |
; выход из .COM-программы |
end start
62