- •В.Ф. Гузик, с.М. Гушанский, в.А. Каляев, а.О. Пьявченко, а.И. Костюк основы программирования на языке «ассемблер»
- •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.10 Exe и com программы
Как известно, любая программа, в конце концов, транслируется в исполняемый файл, имеющий либо EXE, либо COM формат.
В EXE – программе создаются отдельные сегменты для кода, для данных и для стека, причем, если программа большая сегментов для данных и для кода может быть даже несколько. Все эти сегменты, так или иначе, описывает программист, при написании программы. Сегмент стека в принципе можно не описывать (не создавать), в этом случае программа будет работать со стеком DOS, хотя tlink при трансляции выдаст предупреждение (Warning: no stack), которое можно проигнорировать.
В COM – программе для кода, данных и стека отводится один общий сегмент. То есть COM формат используется при написании программ небольшого объема, полностью помещающихся в 64 Кбайта памяти. Мы в дальнейшем, в основном, будем придерживаться именно этого формата.
Загружая в память на исполнение как COM, так и EXE программу, DOS, помимо самой программы, размещает в памяти еще и так называемый «префикс программного сегмента» (PSP). Занимает PSP 256 байт памяти и в него DOS записывает различную служебную информацию. Для EXE программ DOS сама выделяет память под PSP, то есть программист об этом заботиться не должен. А вот для COM программ ситуация иная, здесь программист сам должен выделить память под PSP с помощью директивы org 100h (или org 256) .
Ситуация в памяти после загрузки на исполнение EXE программы показана на рис. 2.9.
Как видно из рисунка 2.9 сегментный регистр ds сразу после загрузки указывает «не туда куда надо» (ds указывает на первый байт PSP, а должен указывать на первый байт сегмента данных). Именно поэтому в начале EXE программы ds нужно настроить надлежащим образом.
-
ds; es
PSP
ss
сегмент
стека
ss:sp
сегмент данных
cs:ip
программа
(сегмент кода)
рис 2.9
Стандартно EXE программа пишется следующим образом:
stack segment stack ; описание сегмента стека
; Первое слово stack – название сегмента, можно было назвать сегмент и по другому, ; например, vasya. Кстати, транслятор нас предупредит, что мы используем ; зарезервированное слово stack не по назначению. Это предупреждение можно спокойно ; проигнорировать. Второе слово stack говорит транслятору, а потом и DOS ; что это сегмент стека.
db 100 dup (0) ; выделяем под стек 100 байт (можно больше, можно меньше)
stack ends ; конец сегмента стека
data segment ; описание сегмента данных
; здесь располагаются переменные и массивы
data ends
code segment ; описание сегмента кода
assume cs:code, ds:data
; Это директива для транслятора. Объяснять ее назначение долго и сложно. Проще ; поверить, что она необходима.
start: ; программа начинается с метки (любой!)
mov ax, data
mov ds, ax ; настраиваем ds на начало сегмента данных
; здесь пишется программа
mov ah, 4ch
int 21h ; стандартный выход из программы
code ends
end start ; start – метка, с которой мы начали программу
Дадим необходимые пояснения. Все что находится в строке программы после «точки с запятой» транслятор понимает как комментарий. Сегменты stack, data и code можно было назвать и другими именами, но тогда мы должны использовать в директивах ends и assume и команде mov ax, data эти другие имена. Изменять второе слово stack нельзя, тогда у нас не будет создан сегмент стека. Причины настройки ds на начало сегмента данных объяснялись в этом разделе выше. Остается выяснить, зачем нужен стандартный выход из программы.
Когда процессор выполняет нашу программу, он «понятия не имеет» где она кончается. Он просто выбирает команды из памяти и их выполняет. Выполнив последнюю команду нашей программы, процессор продолжит выбирать информацию из памяти и буде пытаться выполнять эту информацию в качестве команд. Поскольку после последней команды программы в памяти, скорее всего, «мусор», такая ситуация почти наверняка приведет к зависанию системы. Поэтому в конце программы организуется корректный возврат управления в ту среду (DOS NAVIGATOR или Far или ….), из которой была запущена наша программа.
Ситуация в памяти после запуска СОМ программы представлена на рис. 2.10.
-
cs; es; ds; ss
PSP
cs:ip
программа
ss:sp
рис. 2.10
Как видно из рисунка 2.10 DOS настраивает все сегментные регистры на первый байт PSP. В регистр ip программист, выделяя директивой org 100h место под PSP, заносит 100h. После этого пара cs:ip указывает на первую команду программы. В указатель стека sp DOS загрузит число fffeh. После этого пара ss:sp указывает на ячейку, отстоящую почти на 64К от начала PSP, с тем, чтобы стек располагался как можно дальше от программы и данных и не мог их испортить при своем росте в сторону младших адресов (во всяком случае, уменьшается вероятность такой ситуации).
Стандартно СОМ программа пишется таким образом:
code segment
assume cs: code, ds: code
org 100h
start:
jmp begin ; перепрыгиваем область данных
; здесь можно располагать переменные и массивы
begin:
; здесь располагается программа
mov ah, 4ch
int 21h ; стандартный выход из программы
; здесь можно располагать переменные и массивы
code ends
end start
Дадим необходимые пояснения. Здесь описывается только один сегмент. Поскольку внутри этого сегмента располагаются и данные и программа, программист обязан не допускать ситуации, в которой процессор начал бы выполнять данные как команды. Поэтому переменные и массивы либо перепрыгивают командой jmp, либо располагают после выхода из программы.