Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скляров И. Изучаем Assembler за 7 дней (2010).pdf
Скачиваний:
1335
Добавлен:
23.02.2015
Размер:
2.11 Mб
Скачать

http://www.sklyaroff.ru

37

Данная директива должна находиться перед любой из директив определения сегментов в программе и имеет следующий вид:

.model модель [,язык][,модификатор]

Обязательным параметром этой директивы является только модель, которая может принимать следующие значения:

TINY имеет один сегмент памяти размером не более 64 Кбайт, в котором размещаются коды, данные и стек.

SMALL может иметь до трех сегментов: один 64-килобайтный сегмент для кода, один сегмент для данных и один сегмент стека.

COMPACT то же, что и SMALL, но может иметь несколько сегментов данных.

MEDIUM то же, что и SMALL, но может иметь несколько сегментов для кода.

LARGE имеет несколько сегментов как для кода, так и для данных, при одном сегменте стека.

HUGE разрешает данным быть больше, чем 64 Кбайт, но в остальном полностью похожа на модель LARGE. Реализуется в защищенном режиме процессора.

FLAT — вся память определяется как единый сегмент для кодов, данных и стека размером 4 Гбайт. Основная модель памяти, используемая в защищенном режиме процессора.

Как видите, всего существует 7 моделей памяти.

Язык — необязательный параметр, который может принимать значения C, PASCAL, BASIC, FORTRAN, SYSCALL и STDCALL. Этот параметр необходим для связи модулей на ассемблере с языками высокого уровня.

Модификатор — необязательный параметр, который может принимать значения NEARSTACK (по умолчанию) или FARSTACK. В первом случае области данных и стека размещаются в одном и том же физическом сегменте, во втором — в разных.

Директива .MODEL делает доступными несколько идентификаторов, которые программист может задействовать в своей программе:

@code — физический адрес сегмента кода;

@data — физический адрес сегмента данных типа near (ближний); @fardata — физический адрес сегмента данных типа far (дальний);

@fardata? — физический адрес сегмента неинициализированных данных типа far; @curseg — физический адрес сегмента неинициализированных данных типа far; @stack — физический адрес сегмента стека.

2.5. Разработка нашей первой программы на ассемблере

Вплоть до дня 7 мы будем с вами писать программы, предназначенные для выполнения в операционной системе MS-DOS, потому что так проще изучить ассемблер. Программы для MS-DOS не могут выполняться в операционной системе Windows, потому что используют 16-разрядную модель памяти реального режима (посмотрите еще раз описание памяти в разд. 1.6), поэтому такие программы еще называют 16-разрядными. Но как уже говорилось, Windows выполняет 16-разрядные программы во встроенной виртуальной машине VDM. На седьмом дне мы научимся писать 32-разрядные программы (использующие 32-разрядную модель памяти защищенного режима), предназначенные непосредственно для выполнения в ОС

Windows.

16-разрядные программы MS-DOS с точки зрения программиста отличаются от 32разрядных Windows-программ не только типом используемой памяти, но внутренней структурой, они даже транслируются и компонуются по-разному.

В MS-DOS существует два основных формата исполняемых файлов – COM и EXE. Об их отличиях мы поговорим далее подробно.

http://www.sklyaroff.ru

38

Windows также использует формат EXE для исполняемых файлов, но он имеет более сложную структуру в отличие от 16-разрядных программ.

Везде где мы будем далее говорить о EXE файлах вплоть до дня 7, то будем иметь только EXE формат файлов системы MS-DOS.

По существующей традиции самая первая программа на любом языке программирования должна выводить на экран приветствие "Hello, World!". Не будем отступать от этой традиции.

2.5.1. Программа типа COM

Наберите в любом текстовом редакторе текст, показанный в листинге 2.1, и сохраните его под именем hello1.asm.

Листинг 2.1. Программа типа COM (hello1.asm)

.model

tiny

.code

 

org

100h

start: mov

ah,9

mov

dx,offset message

int

21h

ret

 

message

db "Hello, World!",0Dh,0Ah,'$'

end start

Для получения исполняемого файла необходимо выполнить трансляцию и линковку.

В пакет MASM входит программа ml, которая позволяет выполнить автоматически трансляцию и линковку, для этого в командной строке необходимо выполнить такую команду:

ml hello1.asm

Если трансляция и линковка пройдет без ошибок, то в текущем каталоге появится файл hello1.com размером 24 байта. Если его выполнить, на экране появится фраза "Hello, World!" и программа сразу завершится.

Рассмотрим исходный текст программы, чтобы понять, как она работает. Директива .model tiny устанавливает модель памяти типа TINY.

Для COM-файлов отведена единственная модель памяти типа TINY, все остальные модели памяти используются только в файлах типа EXE.

COM-файлы не содержат в себе никакой служебной информации, только код программы. Поэтому в отличие от EXE-файлов они хранятся на диске точно в том же виде, что и в памяти. Кроме того, COM-файл ни при каких обстоятельствах не может превышать размер 64 Кбайт (точнее немного меньше), так как он загружается в единственный сегмент, который одновременно является сегментом кода, данных и стека (модель памяти TINY). Директива .code начинает сегмент кода, который одновременно будет и сегментом данных и сегментом стека.

При загрузке в память COM-файл должен освободить первые 256 байт (100h) в памяти, куда MS-DOS поместит специальную служебную информацию, так называемый префикс программного сегмента (PSP). Поэтому любая программа, предназначенная для ассемблирования в COM-файл должна начинаться директивой

org 100h.

Метка start располагается перед самой первой командой в программе.

Команда mov ah,9 заносит в регистр AH число 9 — это номер функции DOS вывода строки на экран (адрес строки должен быть задан в регистрах DS:DX). Команда mov dx,offset message помещает в регистр DX адрес строки message. Сегментный регистр DS будет автоматически заполнен при запуске COM-файла.

Команда int 21h далее вызывает эту функцию на выполнение.