__________________________________________________________________________
CODESG SEGMENT PARA 'CODE'
BEGIN PROC FAR
1. ASSUME CS:CODESG,DS:DATASG,SS:STACKG
2. PUSH DS ;Записать DS в стек
3. SUB AX,AX ;Установить ноль в AX
PUSH AX ;Записать ноль в стек
4. MOV AX,DATASG ;Занести адрес
MOV DS,AX ; DATASG в DS
.
.
.
5. RET ;Возврат в DOS
BEGIN ENDP
CODESG ENDS
END BEGIN
__________________________________________________________________________
Рис.3.1. Инициализация EXE-программы.
Теперь, даже если приведенная инициализация программы до конца не
понятна - не отчаивайтесь. Каждая программа фактически имеет аналогичные
шаги инициализации, так что их можно дублировать всякий раз при
кодировании программ.
ПРИМЕР ИСХОДНОЙ ПРОГРАММЫ
________________________________________________________________
Рис.3.2 обобщает предыдущие сведения в простой исходной программе на
ассемблере. Программа содержит сегмент стека - STACKSG и сегмент кода -
CODESG.
__________________________________________________________________________
page 60,132
TITLE EXASM1 (EXE) Пример регистровых операций
;------------------------------------------------
STACKSG SEGMENT PARA SACK 'Stack'
DB 12 DUP('STACKSEG')
STACKSG ENDS
;------------------------------------------------
CODESG SEGMENT PARA 'Code'
BEGIN PROC FAR
ASSUME SS:STACKSG,CS:CODESG,DS:NOTHING
PUSH DS ;Записать DS в стек
SUB AX,AX ;Записать ноль
PUSH AX ; в стек
MOV AX,0123H ;Записать шест.0123 в AX
ADD AX,0025H ;Прибавить шест.25 к AX
MOV BX,AX ;Переслать AX в BX
ADD BX,AX ;Прибавить BX к AX
MOV CX,BX ;Переслать BX в CX
SUB CX,AX ;Вычесть AX из CX
SUB AX,AX ;Очистить AX
NOP
RET ;Возврат в DOS
BEGIN ENDP ;Конец процедуры
CODESG ENDS ;Конец сегмента
END BEGIN ;Конец программы
__________________________________________________________________________
Рис.3.2. Пример исходной программы на ассемблере.
STACKSG содержит один элемент DB (определить байт), который
определяет 12 копий слова 'STACKSEG'. В последующих программах стек не
опpеделяется таким способом, но при использовании отладчика для просмотра
ассемблированной программы на экране, данное определение помогает
локализовать стек.
CODESG содержит выполняемые команды программы, хотя первая директива
ASSUME не генерирует кода. Директива ASSUME назначает регистр SS для
STACKSG и регистр CS для CODESG. В действительности, эта директива
сообщает ассемблеру, что для адресации в STACKSG необходимо использовать
адрес в регистре SS и для адресации в CODESG - адрес в регистре CS.
Системный загрузчик при загрузке программы с диска в память для выполнения
устанавливает действительные адреса в регистрах SS и CS. Программа не
имеет сегмента данных, так как в ней нет определения данных и,
соответственно, в ASSUME нет необходимости ассигновать pегистр DS.
Команды, следующие за ASSUME - PUSH, SUB и PUSH выполняют стандартные
действия для инициализации стека текущим адресом в регистре DS и нулевым
адресом. Поскольку, обычно, программа выполняется из DOS, то эти команды
обеспечивают возврат в DOS после завершения программы. (Можно также
выполнить программу из отладчика, хотя это особый случай).
Последующие команды выполняют те же действия, что показаны на pис.2.1
в предыдущей главе, когда рассматривался отладчик.
ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ
________________________________________________________________
- Не забывайте ставить символ "точка с запятой" перед комментариями.
- Завершайте каждый сегмент директивой ENDS, каждую процедуру -
директивой ENDP, а программу - директивой END.
- В директиве ASSUME устанавливайте соответствия между сегментными
регистрами и именами сегментов.
- Для EXE-программ (но не для COM-программ, см. гл.6) обеспечивайте
не менее 32 слов для стека, соблюдайте соглашения по инициализации стека
командами PUSH, SUB и PUSH и заносите в регистр DS адрес сегмента данных.
ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ
________________________________________________________________
3.1. Какие команды заставляют ассемблер печатать заголовок в начале
каждой страницы листинга и делать прогон листа?
3.2. Какие из следующих имен неправильны: а) PC_AT, б) $50, в) @$_Z,
г) 34B7, д) AX?
3.3. Какое назначение каждого из трех сегментов, описанных в этой
главе?
3.4. Что конкретно подразумевает директива END, если она завершает а)
программу, б) процедуру, в) сегмент?
3.5. Укажите различия между директивой и командой.
3.6. Укажите различия в назначении RET и END.
3.7. Для сегментов кода, данных и стека даны имена CDSEG, DATSEG и
STKSEG соответственно. Сформируйте директиву ASSUME.
3.8. Напишите три команды для инициализации стека адресом в DS и
нулевым адресом.
ГЛАВА 4 Ассемблирование и выполнение программ
__________________________________________________________________________
Ц е л ь: показать процессы ассемблирования, компановки и выполнения
программ.
ВВЕДЕНИЕ
________________________________________________________________
В данной главе объясняется, как ввести в компьютер исходный
ассемблерный текст программы, как осуществить ассемблирование, компоновку
и выполнение программы. Кроме того, показана генерация таблицы
перекрестных ссылок для целей отладки.
ВВОД ПРОГРАММЫ
________________________________________________________________
На рис.3.2 был показан только исходный текст программы,
предназначенный для ввода с помощью текстового редактора. Теперь можно
использовать DOS EDLIN или другой текстовый редактор для ввода этой
программы. Если вы никогда не пользовались программой EDLIN, то именно
сейчас необходимо выполнить ряд упражнений из руководства по DOS. Для
запуска программы EDLIN вставьте дискету DOS в дисковод A и
форматизованную дискету в дисковод B. Чтобы убедиться в наличии на дискете
свободного места для исходного текста, введите CHKDSK B:. Для винчестера
во всех следующих примерах следует использовать C: вместо B:. Для ввода
исходной программы EXASM1, наберите команду
EDLIN В:EXASM1.ASM [Return]
В результате DOS загрузит EDLIN в памяти и появится сообщение "New
file" и приглашение "*-". Введите команду I для ввода строк, и затем
наберите каждую ассемблерную команду так, как они изобpажены на рис.3.2.
Хотя число пробелов в тексте для ассемблера не существенно, старайтесь
записывать метки, команды, операнды и комментарии, выровненными в колонки,
программа будет более yдобочитаемая. Для этого в EDLIN используется
табуляция через каждые восемь позиций.
После ввода программы убедитесь в ее правильности. Затем наберите E
(и Return) для завершения EDLIN. Можно проверить наличие программы в
каталоге на диске, введите
DIR B: (для всех файлов)
или DIR B:EXASM1.ASM (для одного файла)
Если предполагается ввод исходного текста большего объема, то лучшим
применением будет полноэкранный редактор. Для получения распечатки
программы включите принтер и установите в него бумагу. Вызовите программу
PRINT (для DOS 2.0 и старше). DOS загрузит программу в память и
распечатает текст на принтере:
PRINT B:EXASM1.ASM [Return]
Программа EXASM.ASM еще не может быть выполнена - прежде необходимо
провести ее ассемблирование и компоновку. В следующем pазделе показана эта
же программа после ассемблирования и пояснены этапы ассемблирования и
получения листинга.
ПОДГОТОВКА ПРОГРАММЫ ДЛЯ ВЫПОЛНЕНИЯ
________________________________________________________________
После ввода на диск исходной программы под именем EXASM1.ASM
необходимо проделать два основных шага, прежде чем программу можно будет
выполнить. Сначала необходимо ассемблиpовать программу, а затем выполнить
компоновку. Программисты на языке бейсик могут выполнить программу сразу
после ввода исходного текста, в то время как для ассемблера и компилярных
языков нужны шаги трансляции и компоновки.
Шаг ассемблирования включает в себя трансляцию исходного кода в
машинный объектный код и генерацию OBJ-модуля. Вы уже встречали примеры
машинного кода в гл.2 и примеры исxодного текста в этой главе.
OBJ-модуль уже более приближен к исполнительной форме, но еще не
готов к выполнению. Шаг компановки включает преобразование OBJ-модуля в
EXE (исполнимый) модуль, содержащий машинный код. Программа LINK,
находящаяся на диске DOS, выполняет следующее:
1. Завершает формирование в OBJ-модуле адресов, которые остались
неопределенными после ассемблирования. Во многих следующих программах
такие адреса ассемблер отмечает как ----R.
2. Компонует, если необходимо, более одного отдельно
ассемблированного модуля в одну загрузочную (выполнимую) программу;
возможно две или более ассемблерных программ или ассемблерную
программу с программами, написанными на языках высокого уровня, таких
как Паскаль или Бейсик.
3. Инициализирует EXE-модуль командами загрузки для выполнения.
После компановки OBJ-модуля (одного или более) в EXE-модуль, можно
выполнить EXE-модуль любое число раз. Но, если необходимо внести некоторые
изменения в EXE-модуль, следует скорректировать исходную программу,
ассемблировать ее в другой OBJ-модуль и выполнить компоновку OBJ-модуля в
новый EXE-модуль. Даже, если эти шаги пока остаются непонятными, вы
обнаружите, что, получив немного навыка, весь процесс подготовки
EXE-модуля будет доведен до автоматизма. Заметьте: определенные типы
EXE-программ можно преобразовать в oчень эффективные COM-программы.
Предыдущие примеры, однако, не cовсем подходят для этой цели. Данный
вопрос рассматривается в главе 6.
АССЕМБЛИРОВАНИЕ ПРОГРАММЫ
________________________________________________________________
Для того, чтобы выполнить исходную ассемблерную программу, необходимо
прежде провести ее ассемблирование и затем компоновку. На дискете с
ассемблерным пакетом имеются две версии aссемблера. ASM.EXE - сокращенная
версия с отсутствием некоторых незначительных возможностей и MASM.EXE -
полная версия. Если размеры памяти позволяют, то используйте версию MASM
(подробности см. в соответствующем руководстве по ассемблеру).
Для ассемблирования, вставьте ассемблерную дискету в дисковод A, а
дискету с исходной программой в дисковод B. Кто имеет винчестер могут
использовать в следующих примеpах C вместо A и B. Простейший вариант
вызова программы это ввод команды MASM (или ASM), что приведет к загрузке
программы ассемблера с диска в память. На экране появится:
source filename [.ASM]:
object filename [filename.OBJ]:
source listing [NUL.LST]:
cross-reference [NUL.CRF]: