Лабораторная работа № 11 (3)
Тема: Изучение способов трансляции, компоновки и отладки программ, написанных на языке Ассемблер Цель: Изучить способы трансляции и компоновки (сборки) программ с использованием 16-ти
разрядных транслятора и компоновщика, входящих в пакет Turbo Assembler. Освоить методы отладки и использование отладчика, входящего в пакет Turbo Assembler.
Краткая теория
Создание исполняемого модуля (COM или EXE программы) на основе программы написанной на языке Ассемблер (текстовый файл с расширением .asm) осуществляется в два этапа:
трансляция листинга программы в объектный код (файл с расширением .obj) – осуществляется программной tasm.exe, входящей в состав пакета Turbo Assembler;
компоновка (сборка) исполняемого модуля на основе объектного файла – осуществляется программой tlink.exe, входящей в состав пакета Turbo Assembler.
Текст программы на языке Ассемблер можно набрать в любом текстовом редакторе (файл должен содержать символы ASCII). Хотя в настоящее время существует достаточно большое количество IDE, позволяющих разрабатывать программы на языке Ассемблер, но в рамках первых четырех лабораторных работ (№№ 11 (3) – 12 (6)) программирование на языке Ассемблер будет изучаться под операционной системой MS-DOS (или ее эмуляторе DosBox, или в режиме консоли CMD ОС Windows), поэтому для набора текста программы будет использоваться простой текстовый редактор встроенный в FAR (для ОС Windows) или Norton Commander (для ОС MS-DOS).
В операционной системе MS-DOS возможно создание исполняемых модулей двух видов: COM и EXE. COM-файлы предназначены для создания небольших программ, весть код и данные которых умещаются в одном сегменте размером 64Kb. Структура программы на языке
Ассемблер для COM-программы как правило следующая:
.486 model tiny
Code SEGMENT use16
ASSUME cs:Code, ds:Code org 100h
start:
;------ Область команд -------------------------------
;сама программа, состоящая из команд процессора int 20h
;------ Область данных -------------------------------
;содержит описание данных
Code ENDS end start
Текст программы начинается с указания типа процессора (в данном случае 80386), который влияет на набор доступных для использования команд. Для указания процессора типа 80486 необходимо использовать .486, а процессора типа Pentium – .586. Далее указывается модель памяти: для COM-программ должна быть указана модель TINY. Так как вся программа целиком будет размещена в одном сегменте, то, как правило, описывается только сегмент кода программы. При его описании лучше указать использование 16-ти разрядной адресации (use16). После объявления сегмента можно с помощью директивы ASSUME указать транслятору, что с этим сегментом будут ассоциированы регистры CS и DS. Так как при загрузке COM-программы блок спецификации программы будет располагаться в начале сегмента, то транслятору
1
необходимо указать, что генерация адресов в сегменте будет осуществляться со смещением на 256 байт, что и делается с помощью директивы org (org 100h).
Метка начала выполнения программы start как правило располагается в самом начале сегмента. После нее идет сама программа, состоящая из процессорных команд. Завершение выполнения COM-программы осуществляется вызовом прерывания с номером 20h без каких либо параметров.
После команды завершения программы (INT 20h – прерывание MS-DOS 20h) можно объявлять данные программы с использованием операторов типов языка Ассемблер: db, dw, dd и т.д. Описание сегмента кода завершается строкой Code ENDS. В самом конце программы указывается строка, содержащая два слова: end start. Слово end указывает транслятору на конец программы, а слово start указывает на точку входа в программу (команду с которой начинается выполняться программа).
EXE-программы могут занимать более одного сегмента, поэтому при создании таких программ каждый сегмент описывается отдельно. В зависимости от используемой модели памяти количество сегментов в программе может быть различным (см. таблицу 1).
Таблица 1 |
– Модели памяти |
|
|
|
|
|
|
Модель |
Код |
Данные |
|
SMALL |
|
В одном сегменте |
В одном сегменте |
MEDIUM |
|
В нескольких сегментах |
В одном сегменте |
COMPACT |
В одном сегменте |
В нескольких сегментах |
|
LARGE |
|
В нескольких сегментах |
В нескольких сегментах |
В рамках лабораторных работ при создании EXE-программ будет в основном
использоваться модель SMALL. Структура типовой EXE-программы как правило следующая:
.486
model small
Stk SEGMENT STACK use16 ASSUME ss:Stk
db 100h dup(?) Stk ENDS
Data SEGMENT use16 ASSUME ds:Data
;Описание данных
Data ENDS
Code SEGMENT use16 ASSUME cs:Code
start:
;Команды процессора mov ax, 4c00h
int 21h Code ENDS end start
Завершение выполнения EXE-программы осуществляется с помощью функции 4ch прерывания MS-DOS 21h. Для вызова этой функции необходимо в регистр AX записать значение 4c00h. В данном случае код завершения программы (значение регистра AL) будет равен нулю. После этого необходимо вызвать прерывание 21h с помощью команды INT.
Для трансляции программы в объектный код для программ обоих типов используется программа tasm.exe, входящая в состав пакета TASM 5 и располагающаяся в каталоге BIN. Для трансляции ассемблерного файла необходимо просто вызывать эту программу передав в
качестве параметра имя файла с исходным текстом программы. Например: tasm.exe program.asm
2
Если ошибок в программе не будет, то на экране будет выведено следующее сообщение:
Assembling file: program.asm Error messages: None Warning messages: None Passes: 1 Remaining memory: 399k
Также в текущем каталоге будет создан файл с именем program.obj. Если в программе были ошибки, то на экран будет выведено сообщение о неуспешной компиляции программы и
список найденных ошибок, например, в следующем виде:
Assembling file: program.asm
**Error** program.asm(16) Illegal instruction Error messages: 1
Warning messages: None Passes: 1 Remaining memory: 399k
Сборка исполняемого модуля для COM- и EXE-программ выполняется с помощью программы tlink.exe, которая также входит в состав пакета TASM 5. В параметрах этой
программе передается имя объектного файла, например: tlink.exe program.obj
В таком случае будет создан исполняемый модуль EXE-программы. Для создания COMпрограммы необходимо вызвать программу tlink.exe, указав дополнительный параметр /t,
например:
tlink.exe program.obj /t
Для отладки программ можно использовать отладчик td.exe, входящий в состав пакета TASM 5. Для загрузки программы в режиме отладки необходимо запустить эту программу,
указав в качестве параметров имя отлаживаемой программы (COMили EXE-файл), например: td.exe program.com
На экране появится окно отладчика (рисунок 1). Основное место окна занимает текст программы с указанием кодов команд. При загрузке программы ее первая команда будет следующей командой для выполнения. Строка, в которой содержится команда, которая будет выполняться следующей, выделяется символом ►, расположенным между адресом команды и ее кодом.
Рисунок 1 – Окно отладчика td.exe
3
Вправой части окна отображаются значения регистров процессора (в шестнадцатеричной системе счисления) и состояния флагов регистра флагов. Значения, которые изменились при выполнении последней команды, выделяются белым цветом. Флаги обозначены следующими символами: c – флаг переноса, z – флаг нуля, s – флаг знака, o – флаг переполнения, p – флаг паритета, a – дополнительный флаг переноса, i – флаг разрешения прерываний, d – флаг направления.
Внижней части находится окно, отображающее сегмент данных и сегмент стека. Внешний вид окно программы может быть изменено: на нем могут быть отображены другие окна (регистры сопроцессора, дампы памяти и т.д.). Управление содержимым окна отладчика и его параметрами осуществляется с помощью команд подменю View и Window главного меню программы.
При отладке программ можно использовать команды подменю Run главного меню программы. В этом меню расположены следующие основные команды (пункты):
Run (F9) – запуск программы на выполнение до конца или до первой точки останова,
Go to cursor (F4) – запуск программы до положения курсора (выделенной строки программы),
Trace into (F7) – трассировка с входом внутрь процедур,
Step over (F8) – трассировка без входа внутрь процедур,
Execute to … (Alt-F9) – выполнить до определенного адреса (запрашивается при выборе этой команды),
Until return (Alt-F8) – выполнять до первой команды возврата из процедуры,
Arguments … - указать параметры командной строки,
Program reset (Ctrl-F2) – перезапуск программы.
Управление точками останова осуществляется с помощью команд подменю Breakpoints.
Хотя легче и быстрее использовать горячую клавишу F2: установка точки останова в текущей строке курсора, если ее там не было, или сброс точки останова, если она там была.
Ход работы
Уточните у преподавателя, как будет осуществляться написание программ на ассемблере под операционную систему MS-DOS. Возможны следующие варианты:
в эмуляторе DosBox,
на виртуальной машине VMvare с установленной ОС MS-DOS 6.22,
в командной строке Windows или FAR manager.
Если выполнение лабораторных работ будет осуществляться в DosBox или на виртуальной машине, то там будет присутвовать только один диск С, на котором в каталоге TASM будет установлен пакет TASM5 (к каталогу C:\TASM\BIN будут прописаны пути). Разработку программ лучше всего осуществлять в каталоге ASM, созданном в корневой папке диска C. Также будет установлена программа Norton Commander (каталог NC на диске C).
Если разработка лабораторных работ будет осуществляться в командной строке Windows или FAR manager, то уточните у преподавателя, где установлен TASM. Программы можно создавать в своем каталоге на диске D.
Врамках первой программы на языке Ассемблер рассмотрим программу вывода на экран сообщения «Hello world» с использованием прямого доступа к видеобуферу в текстовом режиме.
Вэтом режиме видеобуфер располагается по адресу B800h:0000h. Это начало видеобуфера – левый верхний угол экран. Сам экран состоит из 25 строк по 80 символов в каждой строке. Каждый символ кодируется двумя байтами: младший байт – ASCII-код символа, старший байт – параметры цвета отображения символа. Обычно для вывода в текстовый видеобуфер используются регистр AX, в котором AL – код символа, AH – параметры цвета.
4
|
Формат старшего байта: |
|
|||||||
|
Цвет фона |
|
|
Цвет символа |
|||||
7 |
6 |
5 |
|
4 |
3 |
|
2 |
1 |
0 |
I |
R |
G |
|
B |
I |
|
R |
G |
B |
Здесь прияты следующие обозначения: I – яркость (1 – яркий, 0 – нет), R – наличие красной составляющей цвета, G – наличие зеленой составляющей цвета, B – наличие синей составляющей цвета.
Вывод сообщения будет осуществляться на десятой строке по центру экрана, т. е. с 35 символа этой строки. Смещение этого символа относительно начала видеобуфера можно рассчитать по следующим образом:
OFFSET = (10×80+35)×2=1670.
где 10 – номер строки, 80 – количество символов в строке, 35 – смещение от начала строки, 2 – размер одного знакоместа (код символа + параметры цвета) на экране.
Листинг для COM-программы:
.486 |
|
;Указание набора команд |
model tiny |
|
;Модель памяти COM-программы |
Code SEGMENT use16 |
;Описание сегмента кода |
|
ASSUME cs:Code, ds:Code ;Ассоциации сегментных регистров |
||
org |
100h |
;Организация смещения от начала |
start: |
cs |
;Начальная метка программы |
push |
;Запись в стек регистра CS |
|
pop |
ds |
;Восстановление из стека регистра DS |
mov |
ax, 0b800h |
;В регистр AX заносим адрес сегмента видеобуфера |
mov |
es, ax |
;Устанавливаем регистр ES на видеобуфер |
xor |
ax, ax |
;Очищаем регистр AX |
mov |
di, ax |
;Записываем смещение в регистр DI |
mov |
cx, 2000 |
;Записываем в регистр CX количество повторений |
rep stosw |
;Заполняем видеобуфер нулями |
|
mov |
di, 1670 |
;Заносим в регистр DI смещение строки |
mov |
ah, 42h |
;Записываем в AH параметры цвета: символ зеленый, |
lea |
si, mess |
;фон - красный |
;Загружаем в SI смещение строки mess |
||
mov |
cx, 12 |
;Загружаем в CX количество символов в строке |
next0: |
|
;Метка цикла вывода сообщения |
lodsb |
|
;Записываем в AL следующий символ строки |
stosw |
next0 |
;Записываем в видеобуфер символ |
loop |
;Цикл вывода всей строки |
|
next1: |
al, 60h |
;Метка для перехода на ожидание |
in |
;Чтение кода нажатой клавиши на клавиатуре |
|
cmp |
al, 1 |
;Сравнение с 1 (код ESC) |
jne |
next1 |
;Переход если не равно |
int 20h |
;Завершение программы |
|
mess db |
'Hello world!',0 |
;Описание строки |
Code ENDS |
|
;Завершение описания сегмента кода |
end start |
|
;Конец программы |
Наберите текст этой программы и постройте исполняемый модуль COM-формата. Запустите программу. После выхода из программы видеобуфер рекомендуется очистить с помощью команды cls.
Запустите программу в отладчике. Выполните программу по шагам и с использованием точек останова. Когда освоите отладчик, переходите к следующей части лабораторной работы.
Листинг EXE-программы:
.486 |
small |
|
;Указание |
набора команд |
|
|
model |
|
;Модель памяти EXE-программы |
||||
Stk |
SEGMENT STACK use16 |
;Описание |
сегмента стека |
SS |
||
|
ASSUME ss:Stk |
;Ассоциирование |
регистра |
|||
|
db |
100h dup(0) |
;Резервирование |
256 байт |
для стека |
5
Stk |
ENDS |
|
;Завершение описания сегмента стека |
Data SEGMENT use16 |
;Описание сегмента данных |
||
mess |
ASSUME dc:Data |
;Ассоциирование регистра DS |
|
db |
'Hello world!',0 ;Описание строки |
||
Data ENDS |
|
;Завершение описания сегмента данных |
|
Code SEGMENT use16 |
;Описание сегмента кода |
||
|
ASSUME cs:Code |
;Ассоциирование регистра CS |
|
start: |
ax, seg mess |
;Метка начала программы |
|
|
mov |
;Загружаем в AX адрес сегмента данных |
|
|
mov |
ds, ax |
;Устанавливаем регистр DS на сегмент данных |
|
mov |
ax, 0b800h |
;Загружаем в AX адрес сегмента видеобуфера |
|
mov |
es, ax |
;Устанавливаем регистр ES на видеобуфер |
|
xor |
ax, ax |
;Очищаем регистр AX |
|
mov |
di, ax |
;Записываем в DI значение AX |
|
mov |
cx, 2000 |
;Записываем в регистр CX количество повторений |
|
rep stosw |
;Заполняем видеобуфер нулями |
|
|
mov |
di, 1670 |
;Заносим в регистр DI смещение строки |
|
mov |
ah, 42h |
;Записываем в AH параметры цвета: символ зеленый, |
|
lea |
si, mess |
;фон - красный |
|
;Загружаем в SI смещение строки mess |
||
|
mov |
cx, 12 |
;Загружаем в CX количество символов в строке |
next0: |
|
;Метка цикла вывода сообщения |
|
|
lodsb |
|
;Записываем в AL следующий символ строки |
|
stosw |
next0 |
;Записываем в видеобуфер символ |
|
loop |
;Цикл вывода всей строки |
|
next1: |
al, 60h |
;Метка для перехода на ожидание |
|
|
in |
;Чтение кода нажатой клавиши на клавиатуре |
|
|
cmp |
al, 1 |
;Сравнение с 1 (код ESC) |
|
jne |
next1 |
;Переход если не равно |
|
mov |
ax,4c00h |
;Записываем в AX номер функции завершения |
|
int |
21h |
;Вызов прерывания MS-DOS 21h |
Code ENDS |
|
;Завершение описания сегмента кода |
|
end start |
|
;Конец программы |
|
|
Наберите текст этой |
программы и постройте исполняемый модуль EXE-формата. |
Запустите программу. После выхода из программы видеобуфер рекомендуется очистить с помощью команды cls.
Запустите программу в отладчике. Выполните программу по шагам и с использованием точек останова. Когда освоите отладчик, переходите к следующей части лабораторной работы.
Необходимо переделать программу следующим образом: изменить цвет фона на желтый, а цвет символов на синий, вывод сообщения осуществлять через символ, т. е. надпись должна приобрести следующий вид: H e l l o w o r l d !
Построить исполняемые модули COM- и EXE-формата. Проверить их работоспособность. Положительный результат продемонстрировать преподавателю.
Контрольные вопросы
1.Какая программа из пакета TASM предназначена получения файла с объектным кодом?
2.Какая программа из пакета TASM предназначена получения исполняемого файла формата
COM или EXE?
3.Какая программа из пакета TASM предназначена для отладки COMили EXE-программ?
4.Опишите содержимое основных окон отладчика.
5.Какие команды для трассировки программы доступны в отладчике?
6.Что такое модель памяти и какие виды моделей используются в MS-DOS?
7.Опишите структуру COM-программы.
8.Опишите структуру EXE-программы.
6