
- •В.Ф. Гузик, с.М. Гушанский, в.А. Каляев, а.О. Пьявченко, а.И. Костюк основы программирования на языке «ассемблер»
- •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 Входные параметры: нет
- •1. Функция 2 прерывания int 21h
- •2. Функция 9 прерывание int 21h
- •Функция 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. Содержание
Inst: mov ah, 9
mov dx, offset soob2
int 21h
mov ah,4ch
int 21h
; Область данных загрузочной части.
soob2 db 'Программа уже установлена$'
code ends
end f10
ПРОГРАММА 2. Перехватывает прерывание BIOS int 16h. Это прерывание возвращает в ax из буфера клавиатуры СКЭН и ASCII коды нажатой клавиши. Основная ветвь резидентной части программы реализует схему 2. То есть, попадая в наш резидент, мы сразу вызываем стандартный обработчик int 16h. Этот обработчик возвращает нам в ax код клавиши, с которым мы и работаем. Поскольку при этом возврат управления фоновой программе осуществляет наш резидент, он и должен обеспечить передачу (в регистре ax) полученного кода клавиши фоновой программе. В резидентной части программы имеется побочная ветвь, реализующая схему 1. Связано это с тем, что прерывание int 16h имеет целый ряд функций, из которых нам интересны только две: 0 и 10h. Остальные функции как раз и отсекаются этой побочной ветвью.
; Заголовок СОМ-программы
code segment
assume cs:code,ds:code
org 100h
; Переход на загрузочную часть программы
f10: jmp start
; Область данных резидентной части.
key dw 5555h ; ключ расположен в ячейке
; со смещением 103h (100h байт
; PSP и 3 байта jmp start)
soob db 'нажата Alt/T'
oldvect dd 0 ; здесь запоминаем адрес
; системного обработчика
; Здесь начинается резидентная часть программы. Очень важным является
; то, что когда мы попадаем сюда из фоновой программы, все сегментные
; регистры, кроме CS, содержат данные фоновой программы. Поэтому там,
; где используются команды, по умолчанию берущие базовый адрес из DS,
; необходимо использовать префикс замены сегмента CS:.
newvect:
; Сохраняем в стеке все регистры, которые можем испортить
push es
push bx
push cx
push dx push si push di
; Это функция 0 ?
cmp ah, 0 je resid
; Это функция 10h ?
cmp ah, 10h jne exit1 ; если «не наши» функции, отдаем управление системному ; обработчику
resid:
; Вызываем стандартный обработчик
pushf call cs:oldvect
; Если в AH вернулось 14h, а в AL - 0 -это код Alt/t.
cmp ax, 1400h
jne exit mov di, ax ; сохраняем код клавиши, чтобы вернуть его фоновой программе
; Запоминаем позицию курсора (в SI).
mov ah,3
mov bh,0
int 10h mov si, dx
; Выводим сообщение, начиная с текущей позиции курсора, что Alt/t нажата.
mov cx,12
mov bx,offset soob
m1: mov ah,0eh
mov al,cs:[bx]
int 10h
inc bx
loop m1
; Вводим задержку секунд на 5, чтобы полюбоваться надписью.
mov ah, 0
int 1ah
mov bx, dx
add bx, 50
m2: mov ah, 0
int 1ah
cmp bx, dx
ja m2
; Восстанавливаем курсор в старой позиции. Старые координаты берутся из SI.
mov dx, si
mov ah,2
mov bh,0
int 10h
; Стираем нашу надпись пробелами. Курсор при этом не смещается,
; а остается в нужной (старой) позиции.
mov ah,0ah
mov al,' '
mov cx,12
mov bh,0
int 10h
mov ax, di ; восстанавливаем код клавиши, который надо вернуть фоновой ; программе
exit:
; Восстанавливаем в регистрах информацию фоновой программы.
pop di
pop si
pop dx
pop cx
pop bx
pop es
; Возвращаем управление фоновой программе.
iret
; Возвращаем управление стандартному обработчику
exit1: pop di
pop si
pop dx
pop cx
pop bx
pop es
jmp cs:oldvect
; Здесь кончается резидентная часть и начинается загрузочная часть
; программы.
start:
; Получаем вектор правильного (системного) обработчика (в ES:BX).
mov ah,35h
mov al, 16h
int 21h
; Производим проверку (сравнивая с ключом) на повторную установку программы.
cmp word ptr es:[103h],5555h
jz inst
; Запоминаем вектор правильного (системного) обработчика.
mov word ptr oldvect,bx
mov word ptr oldvect+2,es
; Устанавливаем вектор своего обработчика.
mov dx,offset newvect
mov ah,25h
mov al, 16h
int 21h
; Завершаем программу, оставляя резидентной в памяти ее часть,
; от начала PSP до метки start.
mov dx,offset start
int 27h
; Если программа уже установлена в памяти, выдаем сообщение об
; этом и завершаем программу, ничего не оставляя в памяти.