CodeNet / Языки программирования / Ассемблер / СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
Директива DOSSEG
-----------------------------------------------------------------
Директива DOSSEG приводит к тому, что сегменты в программе
Ассемблера будут сгруппированы в соответствии с соглашениями по
упорядочиванию сегментов фирмы Microsoft. В данным момент вам не
следует вникать в смысл того, что это означает. Запомните просто,
что почти все автономные программы на Ассемблере будут прекрасно
работать, если вы начнете их с директивы DOSSEG.
При компоновке модулей Ассемблера с модулями языков высокого
уровня задавать директиву DOSSEG не обязательно, так как в языке
высокого уровня автоматически выбирается упорядочивание сегментов
по стандарту фирмы Microsoft. Однако эта директива не повредит.
Из всего перечисленного можно сделать заключение, что ис-
пользование директивы DOSSEG в качестве первой строки вашей прог-
раммы является простейшим подходом (если у вас нет конкретной
причины поступать иначе). Благодаря этому вы сможете использовать
определенный порядок сегментов (более подробно о директиве DOSSEG
рассказывается в Главе 3 "Справочного руководства").
Директива .MODEL
-----------------------------------------------------------------
Директива .MODEL определяет модель памяти в модуле Ассембле-
ра, где используются упрощенные директивы определения сегментов.
Заметим, что в "ближнем" коде переходы осуществляются с помощью
загрузки одного регистра IP, а в "дальнем" коде - путем загрузки
регистров CS и IP. Аналогично, к "ближним" данным обращение вы-
полняется только по смещению, а к "дальним" - с помощью полного
адреса "сегмент:смещение". Вкратце, термин "дальний" (FAR) озна-
чает использование полного 32-разрядного адреса ("сегмент:смеще-
ние"), а "ближний" (NEAR) означает использование 16-разрядных
смещений.
Существуют следующие модели памяти:
Сверхмалая И код программы, и ее данные должны размещаться
внутри одного и того же сегмента размером 64К.
Код и данные имеют ближний тип.
Малая Код программы должен размещаться внутри одного
сегмента данных размером 64К, а данные программы
должны размещаться в отдельном сегмента данных
(размером 64К). И код, и данные должны быть ближ-
него типа.
Средняя Код программы может превышать 64К, но данные
программы должны помещаться в один сегмент разме-
ром 64К. Код имеет дальний тип, а данные - ближ-
ний.
Компактная Код программы должен помещаться в один сегмент
размером 64К, а данные могут превышать по размеру
64К. Код имеет ближний тип, а данные - дальнего
типа.
Большая И код, и данные программы могут превышать 64К, но
один массив данных не может превышать 64К. И код,
и данные имеют дальний тип.
Сверхбольшая И код, и данные программы могут превышать по раз-
меру 64К. Массивы данных также могут превышать
64К. Код и данные имеют дальний тип. Указатели на
элементы массива также дальнего типа.
Заметим, что с точки зрения Ассемблера большая и сверхболь-
шая модели идентичны. Сверхбольшая модель не поддерживает автома-
тически массивы данных, превышающие 64К.
Немногие программы на Ассемблере используют более 64К кода
или данных, поэтому для большинства прикладных задач подходит ма-
лая модель. Вы должны использовать малую модель там, где это воз-
можно, так как дальний код (средняя, большая и сверхбольшая мо-
дель) замедляет выполнение программы, а с данными дальнего типа
(компактная, большая и сверхбольшая модель) на Ассемблере рабо-
тать значительно труднее.
Описанные здесь модели памяти соответствуют моделям, исполь-
зуемым в Турбо Си (и во многих других компиляторах для компьютера
IBM PC). Когда вы компонуете модуль на Ассемблере с языком высо-
кого уровня, убедитесь, что используется правильная директива
.MODEL. Эта директива обеспечивает соответствие имен сегментов
Ассемблера тем именам, которые используются в языках высокого
уровня, а также используемого по умолчанию типа меток PROC, ис-
пользующихся для наименования подпрограмм, процедур и функций,
типу (ближнему или дальнему), используемому в языках высокого
уровня.
Директиву .MODEL необходимо указывать, если вы используете
упрощенные директивы определения сегментов, так как в противном
случае Турбо Ассемблер не будет знать как устанавливать сегменты,
определенные с помощью директив .CODE и .DATA. Директива .MODEL
должна предшествовать директивам .CODE, .DATA и .STACK.
Приведем пример наброска программы, использующей упрощенные
директивы определения сегментов:
DOSSEG
.MODEL small
.STACK 200h
.DATA
MemVar DW 0
.
.
.
.CODE
ProgramStart:
mov ax,@data
mov ds,ax
mov ax,[MemVar]
.
.
.
mov ah,4ch
int 21h
END ProgramStart
Другие упрощенные директивы определения сегментов
-----------------------------------------------------------------
Имеется еще несколько общеупотребительных директив определе-
ния сегментов. Вам они потребуются только для больших или специ-
альных программ, поэтому мы только кратко упомянем их. За более
подробной информацией вы можете обратиться к Главе 9.
Директива .DATA? используется аналогично директиве .DATA, но
она определяет ту часть сегмента данных, которая содержит неини-
циализированные данные. Она обычно используется в модулях Ассемб-
лера, которые компонуются с языком высокого уровня.
Директива .FARDATA позволяет вам определить дальний сегмент
данных, то есть сегмент данных, отличный от стандартного сегмента
@data, разделяемого (совместно используемого) всеми модулями. Ди-
ректива .FARDATA позволяет в модуле Ассемблера определить свои
собственные сегменты размером до 64К. Если задана директива
.FARDATA, то именем определенного по этой директиве дальнего сег-
мента данных будет @fardata, так же как @data - имя сегмента, оп-
ределенного по директиве .DATA.
Директива .FARDATA? во многом аналогична директиве .FARDATA,
но она определяет неинициализированный сегмент дальнего типа. Так
же как и для директивы .FARDATA и имени @fardata, при указании
директивы .FARDATA? сегмент данных дальнего типа, определенный по
этой директиве, получает имя @fardata?.
Директива .CONST определяет ту часть сегмента данных, в ко-
торой содержатся константы. Опять-таки это имеет силу только при
компоновке кода Ассемблера с языком высокого уровня.
При использовании упрощенных директив определения сегментов
можно использовать некоторые предопределенные метки. Метка
@FileName представляет собой имя ассемблируемого файла, @curseg -
имя сегмента, в который Турбо Ассемблер в данный момент выполняет
ассемблирование, @CodeSize - это 0 для моделей памяти с ближними
сегментами кода (сверхмалой, малой и компактная), 1 - для ком-
пактной и большой модели памяти и 2 - для сверхбольшой модели.
Аналогично, @DataSize = 0 в модели памяти с сегментами данных
ближнего типа (сверхмалая, малая и средняя модель памяти), 1 в
компактной и большой моделях и 2 - для сверхбольшой модели.
Стандартные директивы определения сегментов
-----------------------------------------------------------------
Далее мы приведем такой же пример программы, как и в преды-
дущем разделе, но на этот раз используем стандартные директивы
определения сегментов SEGMENT, ENDS и ASSUME.
DGROUP GROUP _DATA, STACK
ASSUME CS:_TEXT, DS:_DATA, SS:STACK
STACK SEGMENT PARA STACK 'STACK'
DB 200h DUP (?)
STACK ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
MemVar DW 0
.
.
.
_DATA ENDS
_TEXT SEGMENT WORD PUBLIC 'CODE'
ProgramStart:
mov ax,_DATA
mov ds,ax
mov ax,[MemVar]
.
.
.
mov ah,4ch
int 21h
_TEXT ENDS
END ProgramStart
Теперь вы видите, почему упрощенные директивы определения
сегментов называются упрощенными. Однако, многое из того, что де-
лают упрощенные директивы определения сегментов предназначено для
того, чтобы облегчить компоновку модулей Ассемблера с языками вы-
сокого уровня, что является излишним в автономных программах на
Ассемблере. Приведем пример программы HELLO с использованием
стандартных директив определения сегментов:
Stack Segment PARA STACK 'STACK'
DB 200h DUP (?)
Stack ENDS
Data SEGMENT WORD 'DATA'
HelloMessage DB 'Привет!',13,10,'$'
Data ENDS
Code Segment WORD 'CODE'
ASSUME CS:Code, DS:Data
ProgramStart:
mov ax,Data
mov ds,ax ; установить DS в значение
; сегмента данных
mov dx,OFFSET HelloMessage ; DS:DX указывает
; на сообщение 'Привет!'
mov ah,9 ; функция DOS вывода строки
int 21h ; вывести строку на экран
mov ah,4ch ; функция DOS завершения
; программы
int 21h ; завершить программу
Code ENDS
END ProgramStart
Последний пример не слишком усложнился, но тем не менее яс-
но, что стандартные директивы определения сегментов более сложны,
чем упрощенные директивы.
В Главе 9 стандартные (полные) директивы определения сегмен-
тов описываются более подробно. В данном разделе разделе мы пы-
таемся только дать вам представление о том, что делают стандарт-
ные директивы определения сегментов.
