- •В.Ф. Гузик, с.М. Гушанский, в.А. Каляев, а.О. Пьявченко, а.И. Костюк основы программирования на языке «ассемблер»
- •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. Содержание
Passes: 1
Remaining memory: 381k
D:\MY_DIR\ASSEMBL>d:\my_dir\assembl\tlink temp /t
Turbo Link Version 7.00 Copyright (c) 1987, 1994 Borland International
Fatal: Unable to open file 'temp.obj'
Обратите внимание, что транслятор для каждой ошибки написал в скобках номер строки, в которой он эту ошибку нашел. Так что обычно ошибка легко находится программистом. ERROR – это ошибки, их надо исправлять, WARNING – предупреждения, довольно часто (но не всегда!) их можно игнорировать. Объектный файл из-за ошибок создан не был, поэтому tlink выдал сообщения о фатальной ошибке.
Исправим в нашей программе все ошибки, кроме одной:
code segment ; (строка 1)
assume cs:code, ds:code ; (строка 2)
; пропущена директива org 100h
start: ; (строка 4)
jmp begin ; (строка 5)
mad db 100, 99, 98 ; (строка 7)
db 97, 96 ; (строка 8)
nic dw 380 ; (строка 10)
begin: ; (строка 12)
mov ah, 7 ; (строка 14)
mov al, byte ptr nic ; (строка 15)
int 21h ; (строка 16)
mov si, offset mad ; (строка 17)
mov byte ptr [si+3], 5 ; (строка 18)
mov ah, 4ch
int 21h
code ends
end start
и вновь запустим наш bat файл. Теперь мы получим:
Assembling file: temp.ASM
Error messages: None
Warning messages: None
Passes: 1
Remaining memory: 381k
D:\MY_DIR\ASSEMBL>d:\my_dir\assembl\tlink temp /t
Turbo Link Version 7.00 Copyright (c) 1987, 1994 Borland International
Fatal: Cannot generate COM file : invalid initial entry point address
Теперь tasm «доволен всем» и объектный файл создан, а вот tlink отказывается генерировать СОМ файл. Если мы теперь исправим оставшуюся ошибку (вставим org 100h), то после трансляции будем иметь сообщение:
Assembling file: temp.ASM
Error messages: None
Warning messages: None
Passes: 1
Remaining memory: 381k
D:\MY_DIR\ASSEMBL>d:\my_dir\assembl\tlink temp /t
Turbo Link Version 7.00 Copyright (c) 1987, 1994 Borland International
а наш СОМ файл будет создан.
Примеры программирования на ассемблере.
3.1. Наша первая программа.
В качестве первого примера программы на любом языке обычно используется программа, выводящая на экран надпись: HELLO, WORLD! Давайте и мы напишем такую же программу, но, что бы было интересней, несколько ее усложним.
Итак, вот что будет делать наша программа:
Очищать экран (белым цветом);
Устанавливать курсор, так чтобы надпись выводилась в центр экрана;
Выводить надпись в позицию курсора (черным цветом);
Ждать нажатия клавиши. Если нажата одна из клавиш b (blue), g (green) или r (red), цвет надписи меняется соответственно на синий, зеленый или красный. Если нажата клавиша ESC, программа завершает свою работу.
Приведем вначале текст программы:
; программа написана в СОМ формате
code segment
assume cs:code, ds:code
org 100h
start:
jmp begin
message db 'HELLO, WORLD!' ; надпись, которую мы будем выводить
attributes db 70h ; исходные атрибуты экрана и надписи ; экран – белый, надпись - черная
curs_x db 35 ; координата Х курсора (№ столбца)
curs_y db 12 ; координата Y курсора (№ строки)
begin:
; чистим экран
mov ch, 0 ; координата Y левого верхнего угла экрана (№ строки)
mov cl, 0 ; координата Х левого верхнего угла экрана (№ столбца)
mov dh, 24 ; координата Y правого нижнего угла экрана (№ строки)
mov dl, 79 ; координата Х правого нижнего угла экрана (№ столбца)
mov al, 0 ; чистить всю заданную область (то есть, у нас, весь экран)
mov bh, 70h ; атрибуты (черный символ на белом фоне)
mov ah, 6 ; функция
int 10h
m4:
; выводим надпись
mov di, 13 ; всего выводим 13 символов
mov si, offset message ; в si адрес первой буквы надписи
m1:
; позиционируем курсор
mov dh, curs_y ; в dh строка
mov dl, curs_x ; в dl столбец
mov bh, 0 ; в bh № видеостраницы (для нас начинающих всегда 0)
mov ah, 2 ; функция
int 10h
; собственно вывод надписи. Курсор при таком выводе (для нас, УВЫ!) не сдвигается
mov ah, 9 ; функция
mov bl, attributes ; атрибуты
mov cx, 1 ; коэффициент повторения (сколько раз выводить символ)
mov al, [si] ; в al выводимый (на экран в позицию курсора) символ
int 10h
inc si ; в si адрес следующей буквы надписи
inc curs_x ; сдвигаем координату Х на одну позицию вправо
dec di ; уменьшаем di на единицу
jnz m1 ; если в di «не ноль», идем на переустановку курсора ; и вывод следующей буквы надписи
mov curs_x, 35 ; восстанавливаем исходную координату курсора по Х
mov ah, 0 ; функция
int 16h ; здесь висим и ждем нажатия клавиши. Когда клавиша ; нажата ее скэн-код вернется в ah, а ASCII-код – в al.
cmp al, 1bh ; это ESC? (1bh - ASCII-код клавиши ESC)
je exit ; если «да», идем на выход. «Нет» - проверяем дальше
cmp al, 'r' ; это r?
jne m2 ; «нет» - проверяем дальше
mov attributes, 74h ; «да» - меняем атрибуты
jmp m4 ; и идем на вывод надписи сначала. Старую надпись мы ; не стираем, просто пишем поверх нее новую надпись ; с другими атрибутами
m2:
cmp al, 'g' ; далее аналогично
jne m3
mov attributes, 72h
jmp m4
m3:
cmp al, 'b'
jne m4 ; это вообще «не наша» клавиша, мы ее проигнорируем
mov attributes, 71h
jmp m4
; выход из программы. Мы сюда попадем, только если нажмем ESC
exit:
mov ah, 4ch
int 21h
code ends
end start
Не надо думать, что это оптимальная программа. Давайте, для примера, напишем другой вариант этой программы, теперь в EXE формате.
stack segment stack
db 100 dup (0)
stack ends
data segment
message db 'HELLO, WORLD!$' ; надпись, которую мы будем выводить
attributes db 70h ; исходные атрибуты экрана и надписи data ends
code segment
assume cs:code, ds:data
start:
mov ax, data
mov ds, ax
; чистим экран
m4:
mov ch, 0 ; координата Y левого верхнего угла экрана (№ строки)
mov cl, 0 ; координата Х левого верхнего угла экрана (№ столбца)
mov dh, 24 ; координата Y правого нижнего угла экрана (№ строки)
mov dl, 79 ; координата Х правого нижнего угла экрана (№ столбца)
mov al, 0 ; чистить всю заданную область (то есть, у нас, весь экран)
mov bh, attributes ; текущие атрибуты
mov ah, 6 ; функция
int 10h
;позиционируем курсор
mov dh, 12 ; в dh строка
mov dl, 35 ; в dl столбец
mov bh, 0 ; в bh № видеостраницы (для нас начинающих всегда 0)
mov ah, 2 ; функция
int 10h
; выводим надпись
mov ah, 9 ; функция
mov dx, offset message ; в dx адрес первой буквы надписи
int 21h ; выводим все до доллара
mov ah, 0 ; функция
int 16h ; здесь висим и ждем нажатия клавиши. Когда клавиша ; нажата ее скэн-код вернется в ah, а ASCII-код – в al.
cmp al, 1bh ; это ESC? (1bh - ASCII-код клавиши ESC)
je exit ; если «да», идем на выход. «Нет» - проверяем дальше
cmp al, 'r' ; это r?
jne m2 ; «нет» - проверяем дальше
mov attributes, 74h ; «да» - меняем атрибуты
jmp m4 ; и идем на новую очистку экрана, установку курсора ; и вывод надписи
m2:
cmp al, 'g' ; далее аналогично
jne m3
mov attributes, 72h
jmp m4
m3:
cmp al, 'b'
jne m4 ; это вообще «не наша» клавиша, мы ее проигнорируем
mov attributes, 71h
jmp m4
; выход из программы. Мы сюда попадем, только если нажмем ESC
exit:
mov ah, 4ch
int 21h
code ends
end start
Программа получилась несколько проще. При каждом нажатии любой клавиши (кроме ESC) мы заново очищаем экран с текущими атрибутами, а потом выводим на него надпись, начиная с позиции курсора, который мы все время устанавливаем в одно и тоже место. Недостаток этой программы заключается в постоянной очистке экрана. На медленных компьютерах человеку будет видно мерцание экрана.