- •В.Ф. Гузик, с.М. Гушанский, в.А. Каляев, а.О. Пьявченко, а.И. Костюк основы программирования на языке «ассемблер»
- •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. Содержание
2.4. Оперативная память.
С точки зрения программиста оперативная память представляет собой линейный массив ячеек, размером один байт каждая. Каждой ячейке ставится в соответствие ее адрес (номер). Этот адрес принято называть абсолютным или физическим (принятое обозначение – Аф). Считается что адреса ячеек памяти, с которой работает DOS, лежат в диапазоне от 00000h до fffffh, как показано на рис 2.1. То есть DOS работает с памятью объемом 1 Мбайт.
Рис. 2.1
Чтобы прочитать байт информации из какой-то ячейки памяти или записать в эту ячейку новый байт, необходимо написать соответствующую команду и в этой команде задать необходимый адрес. Например, если в результате выполнения команды формируется физический адрес 00000h, процессор обращается к младшему байту памяти.
Информация в памяти может располагаться не только в виде отдельных байт, но и в виде слов (2 смежных байта), двойных слов (4 байта) и. т. д. При этом, адресом любой структуры в памяти считается физический адрес младшего байта этой структуры. То есть если слово занимает в памяти два байта с адресами 0002аh и 0002bh, это слово имеет физический адрес 0002ah.
2.5. Стек
Стек – это особый вид памяти. Если при обращении к обычной памяти мы должны тем или иным образом задавать в команде адрес ячейки, к которой мы обращаемся, то при обращении к стеку, никакие адреса в команде не задаются. Для того чтобы это было возможно в состав процессора введен специальный регистр sp, называемый указателем стека. Содержимое этого регистра и адресует некоторую ячейку памяти, которую называют вершиной стека. При выполнении стековой операции (команды), процессор берет из sp адрес вершины стека и записывает в нее (или считывает из нее) информацию. При этом процессор автоматически изменяет содержимое sp, изменяя тем самым месторасположение вершины стека.
Собственно существует две стековых операции:
затолкнуть информацию в стек (push)
вытолкнуть информацию из стека (pop).
Например, команда push bx (затолкнуть в стек содержимое двухбайтового регистра bx) выполняется следующим образом. Сначала процессор вычтет из содержимого регистра sp двойку (поскольку формат bx – 2 байта), изменив тем самым вершину стека, а затем в эту новую вершину загрузит содержимое регистра bx. Таким образом, при заталкивании стек растет в сторону младших адресов памяти.
Команда pop bx (вытолкнуть слово из вершины стека в регистр bx) выполняется в обратном порядке. Сначала процессор по содержимому sp определит вершину стека, считает из этой вершины слово и поместит его в bx, а затем прибавит к sp двойку, изменив тем самым вершину стека.
Приведем пример. Состояние стека на данный момент приведено на рис. 2.2.
-
00
00
00
00
00
00
sp
43h
15h
Рис. 2.2
Пусть в данный момент содержимое bx = 35c7h, а содержимое ax = 2233h. И пусть выполняется последовательность команд:
push bx
push ax
pop bx
Состояние стека и регистров, после выполнения каждой команды показано соответственно на рис. 2.3-2.5.
-
00
00
00
00
sp
с7h
35h
43h
15h
bx = 35c7h ax = 2233h
Рис. 2.3.
-
00
00
sp
33h
22h
с7h
35h
43h
15h
bx = 35c7h ax = 2233h
Рис. 2.4
-
00
00
33h
22h
sp
с7h
35h
43h
15h
bx = 2233h ax = 2233h
Рис. 2.5
Стек интенсивно используется практически во всех программах, хотя начинающий программист может и не подозревать, что его программа работает со стеком. Связано это с тем, что ряд команд работает со стеком неявным образом:
call - вызов подпрограммы (запоминает в стеке адрес возврата);
ret - возврат из подпрограммы (берет из стека адрес возврата);
int n – программное прерывание (запоминает в стеке адрес возврата и регистр флагов);
iret -возврат из прерывания (выталкивает из стека адрес возврата и восстанавливает флаги).
Стек очень удобно использовать, когда надо на время сохранить, а затем восстановить содержимое какого-либо регистра.
Самая распространенная ошибка при написании стековых команд заключается в использовании восьмиразрядных регистров, что не допускается системой команд. Со стеком всегда обмениваются словами, а не байтами. Например, команда push cx вполне допустима, а на команде push cl транслятор выдаст сообщение об ошибке.
Другая ошибка, не столь очевидная, но приводящая к куда более тяжелым последствиям, заключается в том, что программист не следит за положением указателя стека, а это его прямая обязанность. Если sp указывает не туда, куда рассчитывает программист, то команда, выталкивающая что-либо из стека, приведет к непредсказуемым для этого программиста последствиям.
Собственно, работая со стеком, полезно помнить два простых правила:
Если Вы решили сохранить содержимое какого-то регистра в стеке (командой push), а потом восстановить его (командой pop), но в промежутке между этими операциями Вы также используете стековые команды, Вы обязаны помнить: число заталкиваний в стек на этом промежутке обязательно должно быть равно числу выталкиваний из стека (количество команд push должно быть равно количеству команд pop). Если это условие не соблюдается, наш регистр будет восстановлен неправильно;
Если Вы последовательно затолкнули в стек содержимое ряда регистров, то восстанавливать эти регистры из стека надо в обратном порядке. Например:
push dx
push bx
push cx
.
.
.
pop cx
pop bx
pop dx