Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Системное программирование.doc
Скачиваний:
178
Добавлен:
19.03.2015
Размер:
1.96 Mб
Скачать

4.3. Общая структура программы

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

STACKSG SEGMENT STACK ; сегмент стека

DB 128 DUP(?)

STACKSG ENDS

DATASG SEGMENT ; сегмент данных

<описания переменных>

DATASGENDS

CODESGSEGMENT; сегмент команд

ASSUME CS: CODESG, DS: DATASG, SS: STACKSG

S: MOV AX, DATASG

MOV DS, AX ; загрузить DS

... ; остальные команды

MOVAX, 4C00h ; завершить программу с кодом возврата 0 INT 21h ; выполнить прерывание 21h

CODESG ENDS

END S ; конец программы, точка входа

Сегмент стека описан с параметром STACK, поэтому в самой программе не нужно загружать сегментный регистр SS. Сегмент стека следует описывать всегда, даже когда не предполагается его использовать, т.к. стек использует операционная система для обработки прерываний. Рекомендуемый размер сегмента стека с запасом составляет 128 байтов. Если программа сама использует стек, то под него отводится столько места, сколько требуется, плюс 128 байтов.

Затем следует сегмент данных, в котором необходимо описать все используемые переменные с помощью директив описания данных. В сегменте кода первой директивой должна идти ASSUME, для задания соответствия между сегментами и соответствующими сегментными регистрами. После директивы ASSUME выполняется инициализация сегментного регистра данных. Затем могут идти все остальные команды программы.

Обязательным последним действием программы в сегменте кода должен быть вызов специальной функции под номером 4C. Функция определена за прерыванием 21h и предназначена для выполнения корректного выхода в операционную систему MS-DOS после завершения работы программы. Для выполнения функции в регистр AH должен быть помещен код 4Ch, а в регистр AL – код выхода. Как правило, успешное завершение программы соответствует коду выхода 0.

В конце программы следует указать директиву END – признак конца программы. Все строки после этой директивы игнорируются. В директиве указывается метка команды, с которой должно начаться выполнение программы (точка входа, в нашем примере эта метка S).

Все предложения должны входить в состав программного сегмента. Размещать их вне сегментов недопустимо. Вне сег­ментов разрешено указывать только директивы информационного характера (например, EQU). В сегменте данных разрешается размещать команды, а в сегменте команд описания переменных.

4.4. Модели памяти

Для программ, содержащих по одному сегменту кода, данных и стека, описание директив сегментации можно упростить. Для этого в транслятор TASM введена возможность использования упрощенных директив сегментации (табл. 6).

Табл. 6. Упрощенные директивы определения сегмента.

Режим MASM

Режим IDEAL

Назначение

.CODE [имя]

CODESEG [имя]

Начало или продолжение сегмента кода.

.DATA

DATASEG

Начало или продолжение сегмента инициализированных данных. Также используется для определения данных типа NEAR.

.CONST

CONST

Начало или продолжение сегмента констант модуля

.DATA?

UDATASEG

Начало или продолжение сегмента неинициализированных данных. Также используется для определения данных типа NEAR.

.STACK [размер]

STACK [размер]

Начало или продолжение сегмента стека модуля. Параметр [размер] задает размер стека.

.FARDATA [имя]

FARDATA [имя]

Начало или продолжение сегмента инициализированных данных типа FAR.

.FARDATA? [имя]

UFARDATA [имя]

Начало или продолжение сегмента неинициализированных данных типа FAR.

Совместно с упрощенными директивами сегментации используется директива модели памятиMODEL, которая позволяет управлять размещением сегментов и выполняет функции директивы ASSUME. Директива связывает сегменты с сегментными регистрами (но явно инициализироватьDSвсе равно необходимо). Формат директивы следующий:

MODEL <модель памяти>,[<модификатор директивы>],[<язык>],[<модификатор языка>]

Параметр "модель памяти"является обязательным. Он определяет модель сегментации памяти: набор и размеры сегментов данных и кода, способ связывания сегментов и сегментных регистров. В табл. 7 приведены возможные значения параметра.

Табл. 7. Модели памяти.

Модель

Тип кода

Тип данных

Описание модели

TINY

NEAR

NEAR

Код и данные объединены в одну группу с именем DGROUP.

SMALL

NEAR

NEAR

Код занимает один сегмент, данные объединены в одну группу с именем DGROUP. Модель обычно используют для большинства программ на ассемблере.

MEDIUM

FAR

NEAR

Код занимает несколько сегментов, по одному на каждый объединяемый модуль. Все ссылки на передачу управления типа FAR. Данные объединены в одной группе; все ссылки на них типаNEAR.

COMPACT

NEAR

FAR

Код в одном сегменте; ссылка на данные типа FAR

LARGE

FAR

FAR

Код и данные расположены в нескольких сегментах.

Параметр "модификатор директивы"уточняет особенности выбранной модели (табл. 8). Для микропроцессоров 386 и выше сегменты могут быть 16 или 32-разрядными. Приuse16 используется 16-разрядная адресация, а приuse32 – 32-разрядная. В первом случае размер сегмента не должен превышать 64 Кбайт, во втором – 4 Гбайт.

Табл. 8. Модификаторы модели памяти.

Модификатор

Назначение

USE16

Сегменты выбранной модели 16-разрядные.

USE32

Сегменты выбранной модели 32-разрядные.

DOS

Программа будет работать в MS-DOS.

Параметры "язык" и "модификатор языка"необязательные и задают особенности вызова процедур при связывании программ на различных языках программирования. При использовании директивы MODEL транслятор делает доступными несколько идентификаторов, к которым можно обращаться, чтобы получить информацию о параметрах модели (табл. 9).

Табл. 9. Идентификаторы, создаваемые директивой MODEL.

Идентификатор

Значение переменной

@CODE

Физический адрес сегмента кода.

@DATA

Физический адрес сегмента данных типа NEAR.

@FARDATA

Физический адрес сегмента данных типа FAR.

@FARDATA?

Физический адрес сегмента

неинициализированных данных типа FAR.

@CURSEG

Физический адрес сегмента

неинициализированных данных типа NEAR.

@STACK

Физический адрес сегмента стека.

Приведем пример использования упрощенных директив сегментации.

MASM; режим работыMASM

MODELSMALL; модель памятиSMALL

.DATA; начало сегмента данных

... ; определение данных

.STACK; начало сегмента стека

DB128DUP(?) ; размер стека 128 байт

.CODE; начало сегмента кода

S:MOVAX, @DATA; получить адреса сегмента данных

MOVDS,AX; адрес сегмента данных в регистрAX

... ; остальные команды программы

MOVAX, 4C00h ; завершить программу с кодом возврата 0 INT 21h ; выполнить прерывание 21h

ENDS ; конец программы, точка входа

Следует заметить, что стандартные и упрощенные директивы сегментации не исключают друг друга. Стандартные директивы необходимы для получения полного контроля над размещением сегментов в памяти и их комбинированием с сегментами других модулей (см. раздел 8.2). Упрощенные директивы удобно использовать для простых программ.