- •В.Ф. Гузик, с.М. Гушанский, в.А. Каляев, а.О. Пьявченко, а.И. Костюк основы программирования на языке «ассемблер»
- •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.9 Выделение памяти под переменные и массивы
Как правило, программист, пишущий на ассемблере первую программу стремиться работать только с регистрами. Однако довольно быстро он понимает, что регистров мало и под хранение некоторых данных надо использовать память. Вот тут у него и возникает вопрос: а как задать переменную в памяти и как потом с этой переменной работать? Задать переменную очень просто:
perem db 73
Мы задали переменную, назвав ее именем perem, попросили транслятор выделить для этой переменной байт памяти (директива db) и загрузить в этот байт число 73. То есть исходное значение нашей переменной – 73, по ходу работы программы это значение может меняться. Кроме директивы db (defined byte) есть еще директивы dw (defined word) (выделить в памяти слово), dd (defined double word) (выделить двойное слово) и другие. Например:
cursor db 12
x1 dw 542h
counter dd 37*14
Хорошо, переменные мы задали, а как теперь с ними работать? Это тоже несложно:
mov ax, x1 ; записываем в ах значение переменной х1
add cursor, 2 ; прибавляем двойку к значению переменной cursor
mov bl, byte ptr counter+3 ; записываем в bl значение старшего (третьего) байта ; переменной counter
Последняя команда требует более развернутого комментария. Переменная counter описана у нас как двойное слово (4 байта), а регистр bl имеет формат 1 байт. Для того чтобы транслятор не выдавал предупреждения о «несогласованности типов операндов», а понял, что программист точно знает, чего он хочет, и вставлена директива byte ptr. Если бы в команде было бы написано не counter + 3, а просто counter, мы бы обратились не к третьему, а к нулевому (младшему) байту нашего двойного слова.
Совершенно аналогично задаются массивы:
note db 40, 35, 27, 90 ; мы задали массив из четырех чисел
Обратиться, например, ко второму элементу нашего массива (число 27) можно одним из следующих способов:
mov dh, note+2
или
mov si, offset note ;после этого в si смещение нулевого элемента массива
mov dh, [si+2]
или
mov si, offset note
add si, 2 ; теперь в si смещение второго элемента массива
mov dh, [si]
Недостаток (или достоинство?) последнего варианта в том, что мы портим si и он теперь указывает не на начало нашего массива. Отметим также, что +2 во всех этих трех вариантах означает «смещение на два байта относительно начала массива» и далеко не всегда является смещением второго элемента массива. Так, например, если у нас задан массив слов:
sl dw 707, 12, 421, 0, 1234
для того чтобы обратиться к его второму элементу (число 421) надо написать, допустим, так:
mov ax, sl+4 ;начало массива плюс четыре байта
Можно задавать и символьные массивы. Делается это так:
strochka db ‘Это строка символов’
Транслятор сам переведет все символы, записанные между апострофами, в их ASCII коды и мы получим массив из 19 байт (17 букв и 2 пробела).
Иногда нужно задать большой массив, например, состоящий из 1000 элементов, причем исходное состояние элементов нас не интересует. То есть всем этим элементам можно присвоить значение 0 (или 117, или 66, …). Такая ситуация возникает, например, когда надо создать в памяти буфер, в который впоследствии будет записываться информация, допустим из какого-то файла. Не писать же нам тысячу нулей через запятую. На этот случай имеется директива dup (повторять):
mass dw 1000 dup (117) ;то что повторяется задается в скобках
Можно создавать и более сложные конструкции:
out_string db ‘nomber of files =’, 4 dup (?), 10,13,’$’
Это заготовка некой строки для вывода на экран. 4 dup (?) – выделяет 4 байта, в которые программа запишет ASCII коды цифр, из которых состоит найденное «число файлов» (вместо ? можно было написать 0, результат был бы тем же). 10 и 13 – управляющие коды, переводящие курсор в начало новой строки экрана. ‘$’ – означает конец выводимой строки.
В заключение приведем еще один пример массива, при задании которого часто встречаются ошибки:
pause db 11, 22, 33, 44, 55, 66, 77, 88
db 99, 100, 32, 0
Как видно из этого примера, если мы продолжаем массив на новой строчке, то надо начать эту строчку с директивы (у нас db), а на предыдущей строчке после последнего элемента запятая не ставится!