- •В.Ф. Гузик, с.М. Гушанский, в.А. Каляев, а.О. Пьявченко, а.И. Костюк основы программирования на языке «ассемблер»
- •1. Введение для кого написано это учебное пособие.
- •2. Предварительные сведения или азы, которые необходимо знать!
- •2.1. Ассемблер, что это такое?
- •2.2. Как писать ассемблерную программу, и какие программы нужны для ее последующей трансляции.
- •2.3. Системы счисления
- •2.4. Оперативная память.
- •2.5. Стек
- •Сегментация памяти.
- •Программная модель процессора.
- •Система команд.
- •Inc word ptr [bx]
- •2.9 Выделение памяти под переменные и массивы
- •2.10 Exe и com программы
- •2.11 Трансляция ассемблерной программы
- •Passes: 1
- •Примеры программирования на ассемблере.
- •3.1. Наша первая программа.
- •3.2. Работа с клавиатурой и экраном.
- •Прерывания dos для работы с клавиатурой.
- •Функция 7 прерывания int 21h
- •Функция 6 прерывания int 21h.
- •Функция 0ah прерывания int 21h.
- •Прерывания bios для работы с клавиатурой
- •1. Функция 0 прерывания int 16h
- •Входные параметры: нет
- •2. Функция 1 прерывание int 16h
- •Входные параметры: нет
- •Прерывания dos для работы с экраном
- •1. Функция 2 прерывания int 21h
- •2. Функция 9 прерывание int 21h
- •Прерывания bios для работы с экраном
- •Функция 1 прерывание int 10h
- •Функция 2 прерывание int 10h
- •Функция 3 прерывание int 10h
- •Функция 6 прерывание int 10h
- •Функция 9 прерывание int 10h
- •Функция 0eh прерывания int 10h
- •Задания к лабораторной работе «Клавиатура и экран»
- •Работа с гибкими дисками.
- •Inc nomber
- •3.4. Перехват прерываний и создание резидентных программ
- •Inst: mov ah, 9
- •Inst: mov ah,9
- •3.5. Работа со звуком.
- •Отладка программ.
- •Приложение
- •Сервисные прерывания dos.
- •Сервисные прерывания bios.
- •Int 10h, функция 07h. Инициализация или прокрутка окна вниз.
- •Int 10h, функция 08h. Чтение символа и атрибута в позиции курсора.
- •Int 10h, функция 09h. Запись символа и атрибута в позицию курсора.
- •Int 10h, функция 0ah. Запись символа в позицию курсора.
- •Int 10h, функция 0eh. Запись символа в режиме телетайпа.
- •Int 10h, функция 10h, подфункция 03h. Переключение бита «мерцание/яркость».
- •Int 10h, функция 13h. Запись строки в режиме телетайпа.
- •Int 15h, функция 86h. Программная задержка на заданное число микросекунд.
- •Int 16h, функция 00h (10h). Чтение символа с клавиатуры.
- •Int 16h, функция 01h (11h). Чтение символа с клавиатуры.
- •Int 16h, функция 02h (12h). Получение статуса клавиатуры.
- •Int 1ah, функция 0h. Число тиков таймера.
- •Коэффициенты пересчета для нот
- •Значение цветов в байте атрибута
- •Буфер клавиатуры.
- •Литература
- •7. Содержание
Функция 2 прерывание int 10h
Входные параметры: в dh номер строки, в dl номер столбца, в bh номер видеостраницы (для нас всегда 0).
Подпрограмма устанавливает курсор в заданную позицию.
ПРИМЕР: Установить курсор в центр экрана.
mov dx, 0c28h ; 12-я строка (0сh), 40-й столбец (28h).
mov bh, 0
mov ah, 2
int 10h
Функция 3 прерывание int 10h
Входные параметры: в bh номер видеостраницы (для нас 0)
Прерывание возвращает текущие координаты и конфигурацию курсора: в dh возвращается строка, в dl – столбец, в ch – верхняя строка развертки, в cl – нижняя строка развертки.
ПРИМЕР: запомнить текущую позицию курсора в переменной cursor
mov ah, 3
mov bh, 0
int 10h
mov cursor, dx
Функция 6 прерывание int 10h
Входные параметры: сх – координаты левого верхнего угла прямоугольной области экрана (ch – строка, cl – столбец), dx – координаты правого нижнего угла (dh – строка, dl – столбец), al – на сколько строк прокручивать заданное окно (при al = 0 все заданное окно очищается), bh - атрибуты для заполнения освобождающихся строк.
Прокрутка заданной прямоугольной области экрана (окна) на заданное число строк вверх. Такая процедура называется "скроллинг".
ПРИМЕР: Очистить экран.
mov cx, 0 ; левый верхний угол экрана. Строка=0, столбец=0.
mov dx, 184fh ; правый нижний угол экрана. Строка=24 (18h), столбец=79 (4fh)
mov bh,7 ; белый по черному mov ax, 600h ; функция 6. Очистить весь экран. int 10h
Функция 9 прерывание int 10h
Входные параметры: bh - номер видеостраницы (у нас 0), bl - атрибуты символа, al - ASCII-код выводимого символа, сх - число повторений.
Выводит заданный символ в текущую позицию курсора. Курсор при этом не перемещается. В сх помещается число х ( х >=1 ). При выводе символ распространяется на х позиций вправо от курсора. То есть если х =1, то будет напечатан один символ, при х =2 - два символа (одинаковых) и. т. д. Если cx =0, ничего выводиться не будет!!! Коды 7, 8, 0ah и 0dh являются управляющими.
ПРИМЕР: Забить верхнюю строку экрана символом "*". Вывод произвести черным по белому.
mov ah, 2 ; устанавливаем курсор
mov bh, 0 ; видеостраница 0
mov dx, 0 ; левый верхний угол экрана (строка = столбец =0)
int 10h
mov ah, 9 ; вывод символа
mov bh, 0 ; видеостраница 0
mov bl, 70h ; черным по белому
mov al, '*'
mov cx, 80 ; заполняем всю строку
int 10h
Функция 0eh прерывания int 10h
Входные параметры: al - ASCII-код выводимого символа
Выводит символ в текущую позицию курсора, после чего курсор сдвигается на позицию вправо. Символ выводится с текущими атрибутами.
Очень часто в программах приходится программным образом организовывать задержку. Например, если у нас по экрану летает символ, без задержки он будет летать настолько быстро, что мы увидим только некое мерцание. Есть несколько способов организации такой задержки.
Способ 1. Пустой цикл.
mov cx, 0ffffh ; в cx максимально возможное число
zero_loop: loop zero_loop
Увы, для современных процессоров эта задержка окажется слишком мала, мы ее даже не заметим. Приходиться делать вложенный пустой цикл. Например, так:
mov bx, 400
m1: mov cx, 0ffffh
m2: loop m2
dec bx
jnz m1
Недостаток заключается в том, что здесь время задержки зависит от производительности процессора. То есть, для конкретного компьютера ее приходится подбирать, уменьшая или увеличивая наше число 400.
Способ 2.
mov ah, 86h
mov cx, 4
mov dx, 0
int 15h
Эта функция прерывания int 15h отрабатывает задержку, заданную (в микросекундах) в регистровой паре cx:dx. В приведенном выше примере задержка составит порядка 218 микросекунд, то есть примерно четверть секунды. Недостаток заключается в том, что некоторые операционные системы (в частности, Windows NT) эту задержку «не понимают» (программа выполняется, а задержки нет).
Способ 3. Работа с системными часами, расположенными в области переменных BIOS.
Функция 0 прерывания 1ah возвращает в cx:dx текущее число тиков таймера. Таймер тикает примерно 20 раз в секунду. Отсюда, если мы реализуем такой фрагмент:
mov ah, 0
int 1ah
mov bx, dx
add bx, 10
mwait:
mov ah, 0
int 1ah
cmp dx, bx
jb mwait ; если меньше, снова идем на mwait
то получим задержку на полсекунды.
В качестве примера работы с экраном и клавиатурой, приведем программу, демонстрирующую тривиальное передвижение на экране принятого с клавиатуры символа. Программа очищает экран, ждет нажатия любой символьной клавиши, после чего принятый символ пролетает по 12-й строке от левого края экрана к его центру, где и останавливается. Затем программа снова ждет нажатия символьной клавиши и все повторяется сначала. Выход из программы по ESC.
code segment
assume cs:code, ds:code
org 100h
start:
jmp begin
x db 0 ;координата курсора по Х, исходный столбец 0
simb db 0
begin:
; прячем курсор
mov ah, 1
mov ch, 20
mov cl, 0
int 10h
; чистим экран красным цветом, символ будет черным
mov cx, 0
mov dx, 184fh
mov bh, 40h
mov ax, 600h
int 10h
m1:
; ждем нажатия клавиши
mov ah, 0
int 16h
; отсекаем функциональные клавиши
cmp al, 0
je m1
; проверяем на ESC
cmp al, 1bh
je exit
; сохраняем принятый символ
mov simb, al
; выводим пробел в центр экрана (стираем старый символ)
mov ah, 2
mov dx, 0c28h
mov bh, 0
int 10h
mov ah, 0eh
mov al, ' '
int 10h
m2:
; устанавливаем курсор для вывода символа
mov ah, 2
mov bh, 0
mov dh, 12 ; символ летит по 12-й строке
mov dl, x
int 10h
; выводим символ в текущую позицию курсора
mov ah, 9
mov cx, 1
mov bl, 40h
mov bh, 0
mov al, simb
int 10h
; задержка
mov ah, 0
int 1ah
mov bx, dx
add bx, 2
m3:
mov ah, 0
int 1ah
cmp dx, bx
jb m3
; увеличиваем Х координату курсора на единицу
inc x
; проверка на выход за центр экрана (40-й столбец)
cmp x, 41
jne m4
mov x, 0 ; восстанавливаем исходное значение Х координаты курсора
jmp m1 ; пошли на ожидание нажатия клавиши
m4:
; стираем символ в текущей позиции (пробелом)
mov ah, 0eh
mov al, ' '
int 10h
jmp m2 ; пошли на вывод символа в следующей позиции
exit:
mov ah, 4ch
int 21h
code ends
end start