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 стандартные (полные) директивы определения сегмен- тов описываются более подробно. В данном разделе разделе мы пы- таемся только дать вам представление о том, что делают стандарт- ные директивы определения сегментов.