Обзор системных функций вывода на экран
Вся информация, выводимая на дисплей, должна быть представлена в ASCII кодах. BIOS обслуживает 3 функции (9, 10, 14) вывода символа на дисплей.
Функция 9 int 10h осуществляяет вывод символа с атрибутом в текущую позицию курсора. При вызове функции: BH – номер видеостраницы (текстовые режимы: 0-текущая страница), BL - атрибуты символа, CX - число повторений символа при выводе, AL - выводимый символ.
mov AH, 9h
mov BH, 0
mov BL, 07h
mov CX, 1
mov AL, 'a'
int 10h
Функция 10 INT 10h осуществляет вывод символа в текущую позицию курсора без изменения атрибута. При вызове функции: BH - номер видеостраницы, 0 - текущая страница. CX - число повторений символа при выводе. AL - выводимый символ.
mov AH, 10
mov BH, 0
mov CX, 1
mov AL, 'A'
int 10h
При использовании функции 09h и 10h следует помнить, что данные функции не перемещают курсор при выводе символа (или группы символов).
Функция 14 INT 10h осуществляет вывод символа на экран и перемещение курсора в следующую позицию. При вызове функции: AL - выводимый символ. BH - номер страницы.
mov AH, 14
mov AL, 'A'
mov BH, 0
int 10h
Функции вывода на экран средствами DOS:
Функция 2 INT 21h осуществляет вывод символа на дисплей с перемещением курсора.
При вызове: DL - символ.
mov AH, 2
mov DL, 'A'
int 21h
Функция 9 INT 21h осуществляет вывод строки на экран.
При вызове: DS:DX - адрес строки, которая должна заканчиваться знаком доллара. Курсор перемещается в конец строки.
; в сегментe данных
string DB 'Текстовая строка $'
; в сегментe кода
mov AH, 9
lea DX, string
int 21h
Функция 40h INT 21hосуществляет запись в файл или вывод данных на устройство.
При вызове: BX - логический номер файла или устройства. Экран имеет логический номер 01. CX - число выводимых символов, DS:DX - адрес буфера, откуда берутся данные.
При возврате: Если CF = 0, то в AX - число фактически записанных байтов. Если СF=1, то в AX - код возврата (код ошибки).
Обозначение DS:DX, описанное при вызове какой-либо функции, используется следующим образом. В сегменте данных или кодовом сегменте должна быть описана строка, адрес которой загружается в регистр DX с помощью команды:
lea DX, <имя строки> ; либо
mov DX, offset <имя строки>
Регистр DS должен содержать адрес сегмента, где расположена строка.
; в сегментe данных
string DB 'Текстовая строка '
stringlen EQU $-string
; в сегмент кода
mov AH, 40h
mov BX, 1 ; логический номер дисплея
mov CX, stringlen
mov DX, offset string
int 21h
Пример. Вывод горизонтальной линии.
mov CX, 10
m1: mov AH, 14
mov AL, 196 ; ASCII код '-'
mov BH, 0
int 10h
loop m1
Пример. Вывод горизонтальной линии со сменой атрибута. Желтые символы на синем фоне.
mov AH, 9
mov BH, 0 ; текущая страница
mov CX, 15
mov AL, '=' ; выводимый символ
mov BL, 0001111Ob
int 10h
При описании переменных в сегменте данных данные можно описывать с помощью псевдооператоров DB, DW, DD.
Например:
A DB 1, 2, 3, 4
B DW 1122h,344h
C DD 11223344h, 55667788h
Если требуется работа с байтами, то обращение к ним осуществляется с помощью оператора byte ptr:
mov AL, A ; AL = 1
mov AL, byte ptr B ; AL = 22h
mov AL, byte ptr C ; AL = 44h
Во втором и третьих примерах в регистр AL будут записаны младшие байты слов и двойных слов.
Для обращения к старшим байтам нужно к адресу добавить необходимое смещение:
mov AL, byte ptr B+1 ; AL = 11
mov AL, byte ptr C+3 ; AL = 11
Если требуется работа со словами, то обращение к ним осуществляется с помощью оператора word ptr:
mov AX, word ptr A ; AX = 0201h
mov AX, B ; AX = 1122h
mov AX, word ptr C ; AX = 3344h
При обращении к старшим словам нужно к адресу добавить смещение для слов (кратное 2):
mov AX, word ptr C+2 ; AX = 1122h
В программах могут использоваться константы, которые описываются с помощью псевдооператоров EQU или " = "
; в сегменте данных
К EQU 255
A DB ?
; в сегменте кода
mov A, K
В данном случае второй операнд является непосредственным, а первый операнд указывает адрес.
Массивы можно задавать следующим образом:
mas_A DB 1, 2, 3, 4, 5, 6, 7, 8, 9
mas_B DB 31h, 32h, ..., 39h
mas_C DB '1, 2, 3, 4, 5, 6, 7, 8, 9' ; данный массив занимает в памяти 17 байтов,
;т.к. включает в себя разделители (запятые)
mas_D DB 1B, 10B, 11B, 100B, 101B, 110B, 111B, 1000B ; Массив задан
; в двоичном коде
Массивы, заданные в двоичном и десятичном виде, перед выдачей на экран необходимо преобразовать в ASCII-коды.
mov AL, 2
mov DL, mas[SI]
add DL, 30h ; получение ASCII - кода
int 21h
Текстовые строки эадаются в ASCII-кодах, т.е. обязательно заключаются в кавычки.
string_A DB 'При использовании функции 9'
DB 'INT 21h текстовая строка', 10, 13
DB 'Должна заканчиваться символом '
DB 'доллара $'
string_B DB 'При использовании функции 40h'
DB 'INT 21h конец текстовой строки', 10, 13
DB 'Определяется по счетчику $ '
При выводе рамки на дисплей ее можно описать в сегменте данных в виде текстовой строки:
RAMKA DB 10,13, 10 DUP (20h), ' ' , 10, 13
DB 10 DUP (20h), ' ' , 10, 13
DB 10 DUP (20h), ' ', 10, 13
DB 10 DUP (20h), ' $'
или
RAMKA DB 10, 13, 10 DUP (20h), 218, 8 DUP (196), 191
DB 10, 13, 10 DUP (20h), 179, 8 DUP (20h), 179
DB 10, 13, 10 DUP (20h), 179, 8 DUP (20h), 179
DB 10, 13, 10 DUP (20h), 192, 8 DUP (196), 217, '$'
ASCII - коды псевдографики для рисования рамок:
-
218
196
191
179
192
217
При выводе символа на дисплей в регистр DL (функция 2 INT 21h) загружается ASCII-код символа:
mov DL, 41h ; ASCII-код символа 'A'
или
mov DL, 'A'
Пример.
sseg segment
DB 128 dup (?)
sseg ends
data segment
string DB 'текстовая строка'
stringln EQU $-string
data ends
code segment
assume DS:data, SS:sseg, CS:code
start:
mov AX, data
mov DS, AX
; вывод строки на экран
mov AH, 40h
mov BH, 1
mov CX, stringln
lea DX, string
int 21h
; завершение программы
mov AH, 4ch
int 21h
code ends
end start