Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка1.doc
Скачиваний:
8
Добавлен:
05.12.2018
Размер:
407.55 Кб
Скачать
      1. Начальная загрузка сегментных регистров

Директива ASSUME сообщает ассемблеру о том, по каким регистрам он должен сегментировать имена из каких сегментов, и "обещает", что в этих регистрах будут находиться начальные адреса этих сегментов. Однако загрузку этих адресов в регистры сама директива не осуществляет.

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

Поскольку в ассемблере нет команды пересылки непосредственного операнда в сегментный регистр (а имя, т.е. начало, сегмента - это непосредственный операнд), то такую загрузку приходится делать через какой-то другой, несегментный, регистр (например, AX):

MOV AX,DT1 ;AX:=начало сегмента DT1

MOV DS,AX ;DS:=AX

Аналогично загружается и регистр ES.

Загружать регистр CS в начале программы не надо: он, как и счетчик команд IP, загружается операционной системой перед тем, как начинается выполнение программы (иначе нельзя было бы начать ее выполнение). Что же касается регистра SS, используемого для работы со стеком, то он может быть загружен так же, как и регистры DS и ES.

Это называется стандартными директивами сегментации.

      1. Упрощенная директива сегментации

Для простых программ, содержащих по одному сегменту кода, данных и стека возможно использовать упрощенную директиву сегментации. Совместно с упрощенными директивами сегментации используется директива указания модели памяти MODEL, которая управляет размещением сегментов и выполняет функцию директивы ASSUME. Эта директива связывает сегменты с предопределенными именами.

Существуют модели памяти:

tiny и код и данные программы должны помещаться внутри

одного 64 Кбайтного сегмента. И код и данные -

ближние.

small код программы должен помещаться внутри одного

сегмента в 64 К, и данные должны помещаться внутри

другого 64 К сегмента. И код и данные - ближние.

medium код программы может быть больше 64 К, а данные

должны помещаться внутри 64 К сегмента. Код -

дальний, а данные - ближние.

compact программный код должен помещаться внутри 64 К сегмента, а данные могут быть больше 64 К. Код - ближний, а данные - дальние. Любой массив данных не может быть больше 64 К.

large и код и данные могут быть больше 64 К, но ни один массив данных не может быть больше 64 К. И код и данные - дальние.

huge и код и данные могут быть больше 64 К, и массив данных может быть больше 64 К. И код и данные -дальние. Указатели на элементы внутри массива - дальние.

Заметим, что с точки зрения ассемблера, large и huge идентичны. Модель huge не поддерживает автоматически массивы данных больше 64 К.

Немногие ассемблерные программы требуют более 64 К кода или данных, поэтому модель smALl оптимальна для большинства программ. Вы должны использовать модель smALl, где это возможно, т.к. дальний код (модели medium, large и huge) делают выполнение программы более медленным; дальние данные (модели compact, large и huge) значительно труднее обрабатывать на ассемблере.

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

Директива MODEL требуется, если Вы используете упрощенные директивы сегментации, иначе Турбо-Ассемблер не будет знать, как установить сегменты, определенные с .CODE и .DATA. MODEL должна предшествовать директивам .CODE, .DATA, .STACK.

Приведем заготовку программы, использующей упрощенные директивы сегментации:

Пример:

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

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

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

A DB 0

B DW ?

.STACK ;сегмент стека

DB 256 DUP(?)

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

MAIN PROC

MOV AX,@DATA ; инициализация сегмента

MOV DS,AX ; данных

. . .

MOV AX,4C00H ;выход

INT 21H ;из программы

MAIN ENDP ;конец процедуры

ENDMAIN ;конец программы с точкой выхода main

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

.DATA? используется так же как .DATA, за исключением того, что она определяет, какая часть сегмента данных содержит неинициализированные данные. Она обычно используется в ассемблерных модулях, связанных с языком высокого уровня.

.FARDATA позволяет Вам определить дальний сегмент данных, т.е. сегмент данных, отличный от стандартного сегмента @data, используемого всеми модулями. .FARDATA позволяет ассемблерному модулю определить его собственный сегмент данных размером более 64 К. Если .FARDATA была использована, @fardata - это имя для дальнего сегмента данных, указанного этой директивой, так же как @data - это имя сегмента данных, указанного .DATA.

.FARDATA? во многом подобна .FARDATA за исключением того, что она определяет неинициализированный дальний сегмент. Как для .FARDATA и @fardata, если была задана директива .FARDATA?, @fardata? - это имя для дальнего сегмента данных, указанного этой директивой.

.CONST определяет, что часть сегмента данных содержит константные данные. Она используется, когда ассемблерный код связывается с языком высокого уровня.

Когда используются упрощенные директивы сегментации, доступны некоторые предопределенные метки. @FileName - это имя ассемблируемого файла. @curseg - это имя сегмента, который сейчас ассемблируется Турбо-Ассемблером. @CodeSIze - 0 для моделей памяти с ближними кодовыми сегментами (tiny, smALl и compact) и единица для моделей памяти с дальними кодовыми сегментами (medium, large и huge). Аналогично @DataSIze - 0 для моделей памяти с ближними сементами данных (tiny, smALl и medium), 1 в compact и large и 2 в huge модели.