Опубликован: 15.11.2010 | Доступ: свободный | Студентов: 643 / 18 | Оценка: 4.00 / 5.00 | Длительность: 17:30:00
Специальности: Программист
Лекция 2:

Прямой ввод-вывод: организация и функции. Вывод на дисплей. Часть 1

< Лекция 1 || Лекция 2: 123 || Лекция 3 >
Аннотация: Прямой ввод-вывод "на среднем уровне" позволяет вводить и выводить текстовые символы в файл, на консоль, модем, удалённый терминал. При этом в MS-DOS он организован при помощи механизма прерываний, а в Windows - эмулятора этих прерываний. Поскольку формат команд-прерываний отличается для клавиатуры и дисплея, мы будем их рассматривать по-отдельности. Для иллюстрации будут приведены функции прямого доступа на языке Ассемблере и Си.

"Среднеуровневый" ввод-вывод возможен только на консоль, работающую в "текстовом режиме", с помощью "базовых" прерываний MS-DOS и BIOS. Мы же пока пройдёмся по использованию этих функций в их "логическом" порядке.

2.1. Вывод символов на экран

Сразу следует отметить, что существуют три основных класса функций для вывода данных:

  1. Вывод одиночного символа на экран;
  2. Вывод последовательности символов на экран;
  3. Вывод форматированной последовательности символов на экран, включая преобразование двоичных форматов в текст.

Рассмотрим эти классы функций ниже:

2.1.1. Вывод одиночного символа

2.1.1.1. Реализация на языке Ассемблера

На языке Ассемблера возможен вывод одного байта информации. Для этого нужно воспользоваться функциями 09 и 0A прерывания BIOS 10H [1, 8]. Макет функции 9 прерывания 10H приведён на рисунке 2.1:

Вызов функции 09 прерывания 10H

Рис. 2.1. Вызов функции 09 прерывания 10H

В регистр AL должен быть помещён выводимый на экран символ. Значение в регистре CX определяет число повторений символа на экране. Вывод на экран последовательности различных символов требует организацию цикла.

В текстовом режиме символы автоматически выводятся на экран и переходят с одной строки на другую. Так как регистр CX занят в функции, нельзя использовать цикл: LOOP. Кроме того, при выводе каждого символа необходимо передвигать курсор в следующий столбец (функция 02 ).

ФУНКЦИЯ 0A ;

Эта функция выводит символ в текущую позицию курсора. Функция 0A не устанавливает атрибуты символа, а оставляет старый атрибут. Для иллюстрации функции см. рисунок 2.2.

Вызов функции 0AH прерывания 10H

Рис. 2.2. Вызов функции 0AH прерывания 10H
2.1.1.2. Реализация на языке ANSI C

Для стандарта ANSI C единственной функцией, осуществляющей вывод единичного символа на консоль прямым методом, является функция putch [3].

ФУНКЦИЯ: putch;
СИНТАКСИС:
void putch( sim );
int sim
где sim - выводимый на дисплей символ.
ОПИСАНА В: <conio.h> /* Используется только для описания функции */
ОПИСАНИЕ: Функция putch записывает символ, код которого задаётся значением параметра sim, на дисплей.
ВОЗВРАЩАЕТ: Функция не возвращает значения.

Смотри также функции ANSI C putc, putchar, fputc, fputchar.

2.1.1.3. Реализация на языке Ява

Вывод одиночного символа на языке Java соответствует выводу значения "примитивного символьного типа" char. Все типы данных выводятся на консоль с помощью двух системных методов: System.out.print и System.out.println [26]. Разница между этими методами состоит в том, что после вызова метода println происходит перевод курсора на новую строку, а при использовании метода print курсор остаётся после вывода на той же строке.

Алгоритм работы метода "print" следующий:

  1. Происходит перевод всех типов данных к типу данных String ;
  2. Выполняется конкатенация строк;
  3. Результирующая строка выводится на экран.

Чтобы использовать оператор вывода "print", просто после выражения запишите элемент (или несколько элементов, объединённых знаком "+" ), заключив его в круглые скобки, а потом в конце поставьте точку с запятой.

Пример приложения, выводящего две строки на экран консоли, смотри в пункте 2.1.2.4.

2.1.1.4. Язык Пролог

Для вывода символа на экран в указанную позицию на языке Turbo Prolog используется функция scr_char [53]. Её описание смотри ниже.

ФУНКЦИЯ: SCR_CHAR
СИНТАКСИС: scr_char(Row,Column,Char), где Row - строка экрана в формате целого числа, Column - столбец экрана в формате целого числа, а Char - одиночный символ, выводимый на экран или считываемый с указанной позиции экрана;
НАЗНАЧЕНИЕ: Функция считывает символ с экрана или выводит его в указанную позицию;
ШАБЛОНЫ: (i,i,i) (i,i,o) ;
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Всегда успех;
ОШИБКИ: * 1001 Неверное значение позиции курсора.

2.1.2. Вывод строки на экран

2.1.2.1. Реализация на языке Ассемблер

Функция 9 прерывания 21H выводит строку [1]. Адрес DS:DX должен указывать на первый символ строки. Строка должна заканчиваться символом '$', что означает, что символ '$' не может входить в выводимую строку. Строка может быть любой длины. Функция не переводит автоматически курсор на начало следующей строки после завершения вывода. Чтобы это выполнялось, надо добавить в конец строки символы: CR (0DH, "возврат каретки") и LF (0AH, "перевод строки"). Для иллюстрации смотри следующий пример:

Пример 2.1.

; --- в сегменте данных:
FIR_STR	DB	'Это первая строка',0DH, 0AH,'$'
SEC_STR	DB	'а это вторая строка$'
; --- вывод строки
	MOV	AH, 9		;Номер функции
	LEA	DX, FIR_STR	;Загрузка адреса первой строки
	INT	21H
	LEA	DX, SEC_STR	;Загрузка адреса второй строки
	INT	21H

Интерпретируются следующие управляющие коды: (см. таблицу 2.2).

Функция 40H прерывания 21H [1, 8]предназначена для вывода в файл, поэтому она требует дескриптора файла или устройства. Дисплей имеет заранее предназначенный дескриптор #1. Надо поместить это число в BX, а число байтов в строке - в CX. Адрес: DS:DX должен указывать на выводимую строку. Функция выводит текст с нормальными (белый текст на чёрном фоне) атрибутами.

Пример 2.2.

; --- в сегменте данных
ABZATS	DB	100 DUP('A')

; --- вывод 100 байт текста абзаца
	MOV	AH, 40H			;Номер функции
	MOV	BX, 1			;дескриптор дисплея.
	MOV	CX, 100			;число выводимых символов
	LEA	DX, ABZATS		;адрес абзаца
	INT	21H

При выводе с помощью этой функции можно использовать escape - последовательности (см. таблицу 2.1).

Таблица 2.1. Полный список escape-последовательностей
Escape последовательности по группам
Esc[=числоh Задание видеорежима
Параметр: число может быть одним из следующих:
0 40х25, 2-цветный текстовый режим
1 40х25, 16-цветный текстовый режим
2 80х25, 2-цветный текстовый режим
3 80х25, 16-цветный текстовый режим
4 320х200, 4-цветный графический режим
5 320х200, 2-цветный графический режим
6 620х200, 2-цветный графический режим
14 640х200, 16-цветный графический режим
15 640х350, 2-цветный графический режим
16 640х350, 16-цветный графический режим
17 640х480, 2-цветный графический режим
18 640х480, 16-цветный графический режим
19 320х200, 256-цветный графический режим
Примечание: приведённые последовательности вместо символа h можно завершать символом l.
Esc[число;числоm Выбор атрибутов символа
В последовательности может быть от одного до четырёх символов. Параметр:число может принимать следующие значения:
0 Нормальное изображение. Белые символы на чёрном поле.
1 Выделение яркостью текста
4 Выделение подчёркиванием (только для монохромных дисплеев)
5 Выделение мерцанием
7 Инверсное изображение (чёрные символы на белом поле).
8 Скрытый текст (только для монохромных дисплеев. Цветное изображение можно скрыть, установив одинаковые цвета фона и символа).
30 Чёрные символы
31 Красные символы
32 Зелёные символы
33 Коричневые символы
34 Синие символы
35 Символы цвета "магента" (пурпурные)
36 Символы цвета "циан" (бирюзовые)
37 Белые символы
40 Чёрный фон
41 Красный фон
42 Зелёный фон
43 Коричневый фон
44 Синий фон
45 Фон цвета "магента"
46 Фон цвета "циан"
47 Белый фон
Позиционирование курсора
Esc[стр;позH Установка позиции курсора. Параметр: стр обозначает Y координату курсора в пределах 1-25, параметр поз – X координату в пределах 1-80 (для видеорежима 80х25 символов).
Esc[стр;позf Установка позиции курсора. Параметр: стр обозначает Y координату курсора в пределах 1-25, параметр поз – X координату в пределах 1-80 (для видеорежима 80х25 символов).
Esc[числоA Перемещение курсора на число строк вверх.
Esc[числоB Перемещение курсора на число строк вниз.
Esc[числоC Перемещение курсора на число позиций вправо.
Esc[числоD Перемещение курсора на число позиций влево.
Esc[6n Вывод текущих координат курсора в формате: Esc[стр;позR.
Esc[s Сохранение текущих координат курсора в специальном буфере.
Esc[u Восстановление позиции курсора из значения, сохранённом в буфере.
Esc[=7h Включение автоматического перевода курсора на следующую строку.
Esc[=7l Выключение автоматического перевода курсора на следующую строку.
Прочие последовательности
Esc[2J Очистка экрана и перемещение курсора в левый верхний угол.
Esc[K Очистка строки от курсора до конца строки.
Таблица 2.2. Список управляющих кодов при вводе-выводе
Управляющие и "пробельные" коды ASCII
Управляющий код ASCII Hex Символ в Си Назначение
NUL 0 0 '\0' "Пустой" символ, завершающий строку на языке Си
SOH 1 1 Символ: "Начало заголовка"
STX 2 2 Символ "Начало текста"
ETX 3 3 Символ "Конец текста" ("Снятие программы с выполнения")
EOT 4 4 Символ "Конец передачи"
ENQ 5 5 Символ "Запрос"
ACK 6 6 Символ "Подтверждение"
BEL 7 7 '\b' Символ, вызывающий "звуковой сигнал" динамика компьютера.
BS 8 8 Символ "Забой" (возврат на одну позицию)
HT 9 9 '\t' Символ "горизонтальная табуляция", вызывающий смещение позиции вывода символов к следующему из определённых программистом позиций. Обычно эти позиции определяют отступ в 8 символов от начала строки.
LF 10 0A '\n' Символ "перевод строки". Вывод следующего символа в MS-DOS начинается со следующего столбца следующей строки экрана.
VT 11 0B '\v' Символ "вертикальная табуляция".
FF 12 0C Символ "новая страница". Осуществляет "прогон страницы" на принтере, вызывая печать с начала новой страницы принтера. Количество строк на странице определяется программистом.
CR 13 0D '\r' Символ "возврат каретки", вызывающий вывод следующего символа с начала текущей строки.
SO 14 0E Символ "Переход в верхний регистр"
SI 15 0F Символ "Переход на нижний регистр"
DLE 16 10 Символ "Переключение когда"
DC1 17 11 Символ "Управление устройством 1"
DC2 18 12 Символ "Управление устройством 2"
DC3 19 13 Символ "Управление устройством 3"
DC4 20 14 Символ "Управление устройством 4"
NAK 21 15 Символ "Переспрос"
SYN 22 16 Символ "Режим синхронного ожидания"
ETB 23 17 Символ "Конец передачи блока"
CAN 24 18 Символ "Отмена"
EM 25 19 Символ "Конец носителя"
SUB (EOF) 26 1A Символ "Замена" ("Конец текстового файла")
ESC 27 1B Символ "Escape", начинающий escape-последовательность при выводе на экран дисплея.
FS 28 1C Символ "Разделитель файла"
GS 29 1D Символ "Разделитель группы"
RS 30 1E Символ "Разделитель записи"
US 31 1F Символ "Разделитель блока"
"Пробельные" коды клавиш
Управляющий код ASCII Hex Символ в Си Назначение
NUL 0 0 '\0'
HT 9 9 '\t' Символ "горизонтальная табуляция", вызывающий смещение позиции вывода символов к следующему из определённых программистом позиций. Обычно эти позиции определяют отступ в 8 символов от начала строки.
LF 10 0A '\n' Символ "перевод строки". Вывод следующего символа в MS-DOS начинается со следующего столбца следующей строки экрана.
VT 11 0B '\v' Символ "вертикальная табуляция".
FF 12 0C Символ "новая страница". Осуществляет "прогон страницы" на принтере, вызывая печать с начала новой страницы принтера. Количество строк на странице определяется программистом.
CR 13 0D '\r' Символ "возврат каретки", вызывающий вывод следующего символа с начала текущей строки.
EOL Символ "конец строки". Состоит из комбинации символов <CR><LF> в MS-DOS, <CR> в Mac OS и <LF> в UNIX.
Space 32 20 Символ пробела в кодировке ASCII (основной символ)

У ЭВМ IBM PC/AT и более современных есть ещё одна функция 13H прерывания BIOS 10H [8]. При выводе строки содержимое регистров ES:BP должно указывать на выводимую строку символов, а длина строки должна быть в CX. DX указывает на позицию курсора, откуда будет начинаться строка (вычисляется как смещение от начала страницы ES:BP, которая выводится, без учёта байтов-атрибутов). В BH должен быть указан номер страницы. Наконец, номер кода от 0 до 3, содержащийся в регистре AL, указывает способ вывода строки:

  • AL = 0 строка состоит только из символов, курсор неподвижен;
  • AL = 1 строка состоит только из символов, курсор двигается;
  • AL = 2 в строке чередуются символы и атрибуты, курсор неподвижен;
  • AL = 3 в строке чередуются символы и атрибуты, курсор двигается.

Когда значение AL равно 0 или 1, атрибуты должны находиться в регистре BL. Все символы будут выводиться с этими атрибутами. Данная функция будет воспринимать символы из таблицы 2.2, интерпретируя их как управляющие команды, а не печатные символы.

Пример 2.3.

; --- в сегменте данных
ABZATS	DB	100 DUP('A')

; --- вывод 100 байт текста абзаца
; --- подготовительные операции
	PUSH	BP		;Сохранение BP
	PUSH	ES		; Сохранение ES
	PUSH	DS
	POP	ES		; ES = DS
; --- вызов функции
	MOV	AH,13H	;Номер функции
	MOV	DX,0		;С начала абзаца
	MOV	CX, 100
	LEA	BP, ABZATS	;Адрес абзаца
	MOV	AL, 1
	MOV	BL, 07H	;Текст белый по чёрному фону
	MOV	BH, 0		;Экранная страница
	INT 	10H
; --- заключительные операции:
	POP	ES		;Возврат ES
	POP	BP		;Возврат BP
< Лекция 1 || Лекция 2: 123 || Лекция 3 >
Дмитрий Карпов
Дмитрий Карпов
Россия, Нижний Новгород
Олег Корсак
Олег Корсак
Латвия, Рига