Курсор при этом расположится в конце первой строки, где необходимо
указать имя файла. Введите номер дисковода (если он не определен
умолчанием) и имя файла в следующем виде: B:EXASM1. Не следует набирать
тип файла ASM, так как ассемблер подразумевает это.
Во-втором запросе предполагается аналогичное имя файла (но можно его
заменить). Если необходимо, введите номер дисковода B:.
Третий запрос предполагает, что листинг ассемблирования программы не
требуется. Для получения листинга на дисководе B наберите B: и нажмите
Return.
Последний запрос предполагает, что листинг перекрестных cсылок не
требуется. Для получения листинга на дисководе B, наберите B: и нажмите
Return.
Если вы хотите оставить значения по умолчанию, то в трех последних
запросах просто нажмите Return. Ниже приведен пример запросов и ответов, в
результате которых ассемблер должен cоздать OBJ, LST и CRF-файлы. Введите
ответы так, как показано, за исключением того, что номер дисковода может
быть иной.
source filename [.ASM]:B:EXASM1 [Return]
object filename [filename.OBJ]:B: [Return]
source listing [NUL.LST]:B: [Return]
cross-reference [NUL.CRF]:B: [Return]
Всегда необходимо вводить имя исходного файла и, обычно, запрашивать
OBJ-файл - это требуется для компановки программы в загрузочный файл.
Возможно потребуется указание LST-файла, особенно, если необходимо
проверить сгенерированный машинный код. CRF-файл полезен для очень больших
программ, где необходимо видеть, какие команды ссылаются на какие поля
данных. Кроме того, ассемблер генерирует в LST-файле номера строк, которые
используются в CRF-файле.
В прил.4 "Режимы ассемблирования и редактирования" перечислены режимы
(опции) для ассемблера версий 1.0 и 2.0.
Ассемблер преобразует исходные команды в машинный код и выдает на
экран сообщения о возможных ошибках. Типичными ошибками являются нарушения
ассемблерных соглашений по именам, неправильное написание команд
(например, MOVE вместо MOV), а также наличие в опеpандах неопределенных
имен. Программа ASM выдает только коды ошибок, которые объяснены в
руководстве по ассемблеру, в то время как программа МASM выдает и коды
ошибок, и пояснения к ним. Всего имеется около 100 сообщений об ошибках.
Ассемблер делает попытки скорректировать некоторые ошибки, но в любом
случае следует перезагрузить текстовый редактор, исправить исходную
программу (EXASM1.ASM) и повторить ассемблирование.
На рис.4.1 показан листинг, полученный в результате асcемблирования
программы и записанный на диск под именем EXASM1.LST.
__________________________________________________________________________
1 page 60,132
2 TITLE EXASM1 (EXE) Пример регистровых операций
3 ;-----------------------------------------------
4 0000 STACKSG SEGMENT PARA SACK 'Stack'
5 0000 0C [ DB 12 DUP('STACKSEG')
6 53 54 41 43
7 4B 53 45 47
8 ]
9
10 0060 STACKSG ENDS
11 ;-----------------------------------------------
12 0000 CODESG SEGMENT PARA 'Code'
13 0000 BEGIN PROC FAR
14 ASSUME SS:STACKSG,CS:CODESG,DS:NOTHING
15 0000 1E PUSH DS ;Записать DS в стек
16 0001 2B C0 SUB AX,AX ;Записать ноль
17 0003 50 PUSH AX ; в стек
18
19 0004 B8 0123 MOV AX,0123H ;Записать шест.0123 в AX
20 0007 05 0025 ADD AX,0025H ;Прибавить шест.25 к AX
21 000A 8B D8 MOV BX,AX ;Переслать AX в BX
22 000C 03 D8 ADD BX,AX ;Прибавить BX к AX
23 000E 8B CB MOV CX,BX ;Переслать BX в CX
24 0010 2B C8 SUB CX,AX ;Вычесть AX из CX
25 0012 2B C0 SUB AX,AX ;Очистить AX
26 0014 90 NOP
27 0015 CB RET ;Возврат в DOS
28 0016 BEGIN ENDP ;Конец процедуры
29
30 0016 CODESG ENDS ;Конец сегмента
31 END BEGIN ;Конец программы
-------------------------------------------------------------------------
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 0016 PARA NONE 'CODE'
STACKSG. . . . . . . . . . . . 0060 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0016
__________________________________________________________________________
Рис.4.1. Листинг ассемблирования программы.
В начале листинга обратите внимание на реакцию ассемблера на
директивы PAGE и TITLE. Никакие директивы, включая SEGMENT, PROC, ASSUME и
END не генерируют машинных кодов.
Листинг содержит не только исходный текст, но также слева
транслированный машинный код в шестнадцатиричном формате. В самой левой
колонке находится шест.адреса команд и данных.
Сегмент стека начинается с относительного адреса 0000. В
действительности он загружается в память в соответствии с адpесом в
регистре SS и нулевым смещением относительно этого адpеса. Директива
SEGMENT устанавливает 16-кратный адрес и указывает ассемблеру, что это
есть начало стека. Сама директива не генерирует машинный код. Команда DB,
также находится по адресу 0000, содержит 12 копий слова 'STACKSEG';
машинный код представлен шест.0C (десятичное 12) и шест. представлением
ASCII символов. (В дальнейшем можно использовать отладчик для просмотра
результатов в памяти). Сегмент стека заканчивается по адресу шест.0060,
который эквивалентен десятичному значению 96 (12х8).
Сегмент кода также начинается с относительного адреса 0000. Он
загружается в память в соответствии с адресом в pегистре CS и нулевым
смещением относительно этого адреса. Поскольку ASSUME является директивой
ассемблеру, то первая команда, которая генерирует действительный машинный
код есть PUSH DS - однобайтовая команда (1E), находящаяся на нулевом
смещении. Следующая команда SUB AX,AX генерирует двухбайтовый машинный код
(2B C0), начинающийся с относительного адреса 0001. Пробел между байтами
только для удобочитаемости. В данном примере встречаются одно-, двух- и
трехбайтовые команды.
Последняя команда END содержит операнд BEGIN, который имеeт отношение
к имени команды PROC по смещению 0000. Это есть адрес сегмента кодов, с
которого начинается выполнение после загрузки программы.
Листинг ассемблирования программы EXASM1.LST, имеет по директиве PAGE
шиpину 132 символа и может быть распечатан. Многие принтеры могут печатать
текст сжатым шрифтом. Включите ваш принтер и введите команду
MODE LPT1:132,6
Таблица идентификаторов
-------------------------
За листингом ассемблирования программы следует таблица
идентификаторов. Первая часть таблицы содержит определенные в программе
сегменты и группы вместе с их размером в байтах, выравниванием и классом.
Вторая часть содержит идентификаторы - имена полей данных в сегменте
данных (в нашем примере их нет) и метки, назначенные командам в сегменте
кодов (одна в нашем примере). Для того, чтобы ассемблер не создавал эту
таблицу, следует указать параметр /N вслед за командой MASM, т.е. MASM/N.
Двухпроходный ассемблер
-------------------------
В процессе трансляции исходной программы ассемблер делает два
просмотра исходного текста, или два прохода. Одной из основных причин
этого являются ссылки вперед, что происходит в том случае, когда в
некоторой команде кодируется метка, значение которой еще не определено
ассемблером.
В первом проходе ассемблер просматривает всю исходную прогpамму и
строит таблицу идентификаторов, используемых в программе, т.е. имен полей
данных и меток программы и их относительных aдресов в программе. В первом
проходе подчитывается объем объектного кода, но сам объектный код не
генерируется.
Во втором проходе ассемблер использует таблицу идентификаторов,
построенную в первом проходе. Так как теперь уже известны длины и
относительные адреса всех полей данных и команд, то ассемблер может
сгенерировать объектный код для каждой команды. Ассемблер создает, если
требуется, файлы: OBJ, LST и CRF.
КОМПАНОВКА ПРОГРАММЫ
________________________________________________________________
Если в результате ассемблирования не обнаружено ошибок, то cледующий
шаг - компановка объектного модуля. Файл EXASM1.OBJ содержит только
машинный код в шестнадцатеричной форме. Так как программа может
загружаться почти в любое место памяти для выполнения, то ассемблер может
не определить все машинные адреса. Кроме того, могут использоваться другие
(под) программы для объединения с основной. Назначением программы LINK
является завершение определения адресных ссылок и объединение (если
требуется) нескольких программ.
Для компановки ассемблированной программы с дискеты, вставьте дискету
DOS в дисковод A, а дискету с программой в дисковод B. Пользователи
винчестерского диска могут загрузить компоновщик LINK прямо с дисковода C.
Введите команду LINK и нажмите клавишу Return. После загрузки в память,
компоновщик выдает несколько запросов (аналогично MASM), на которые
необходимо ответить:
Запрос компоновщика Ответ Действие
Object Modules [.OBJ]: B:EXASM1 Компонует EXASM1.OBJ
Run file [EXASM1.EXE]: B: Создает EXASM1.EXE
List file [NUL.MAP]: CON Создает EXASM1.MAP
Libraries [.LIB]: [Return] По умолчанию
Первый запрос - запрос имен объектных модулей для компановки, тип OBJ
можно опустить.
Второй запрос - запрос имени исполнимого модуля (файла), (по
умолчанию A:EXASM1.EXE). Ответ B: требует, чтобы компоновщик создал файл
на дисководе В. Практика сохранения одного имени (при разных типах) файла
упрощает работу с программами.
Третий запрос предполагает, что LINK выбирает значение по yмолчанию -
NUL.MAP (т.е. MAP отсутствует). MAP-файл содержит таблицу имен и размеров
сегментов и ошибки, которые обнаружит LINK. Типичной ошибкой является
неправильное определение сегмента стека. Ответ CON предполагает, что
таблица будет выведена на экран, вместо записи ее на диск. Это позволяет
сэкономить место в дисковой памяти и сразу просмотреть таблицу
непосредственно на экране. В нашем примере MAP-файл содержит следующую
информацию:
Start Stop Length Name
00000H 00015H 0016H CODESG
00020H 0007FH 0060H STACKSG
Для ответа на четвертый запрос - нажмите Return, что укажет
компоновщику LINK принять остальные параметры по yмолчанию. Описание
библиотечных средств можно найти в руководстве по DOS.
На данном этапе единственной возможной ошибкой может быть yказание
неправильных имен файлов. Исправить это можно только перезапуском
программы LINK. В прил.4 перечислен ряд pежимов компоновщика LINK.
ВЫПОЛНЕНИЕ ПРОГРАММЫ
________________________________________________________________