Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Упрощенные Директивы Сегментации

Стандартные директивы сегментации изначально использовались для оформления программы в трансляторах MASM и TASM. Поэтому их называют стандартными директивами сегментации. Для простых программ, содержащих по одному сегменту для кода, данных и стека, хотелось бы упростить ее описание. Для этого в трансляторы MASM и TASM ввели возможность использования упрощенных директив сегментации. Но здесь возникла проблема, связанная с тем, что необходимо было как-то компенсировать невозможность напрямую управлять размещением и комбинированием сегментов. Для этого совместно с упрощенными директивами сегментации стали использовать директиву указания модели памяти MODEL, которая частично стала управлять размещением сегментов и выполнять функции директивы ASSUME (поэтому при использовании упрощенных директив сегментации директиву ASSUME можно не использовать). Директива MODEL связывает сегменты, которые в случае использования упрощенных директив сегментации имеют предопределенные имена, с сегментными регистрами (хотя явно инициализировать ds все равно придется).
Пример программы с использованием упрощенных директив сегментации:


;----------------------------------------
masm ;режим работы TASM: ideal или masm
model small ;модель памяти
.data ;сегмент данных
message db 'Введите две шестнадцатеричные цифры,$'
.stack ;сегмент стека
db 256 dup ('?') ;сегмент стека
.code ;сегмент кода
main proc ;начало процедуры main
mov ax,@data ;заносим адрес сегмента
;данных в регистр ax
mov ds, ax ;ax в ds
;далее текст программы (см. сегмента кода в листинге 3.1 книги)
mov ax,4c00h ;пересылка 4c00h в регистр ax
int 21h ;вызов прерывания с номером 21h
main endp ;конец процедуры main
end main ;конец программы с точкой входа main

НЕ нашли? Не то? Что вы ищете?


Синтаксис директивы MODEL:

http://2.bp.blogspot.com/_LP-1tx6nFA0/SiUAePFqYYI/AAAAAAAAAXU/YD9LFz9wzv0/s400/model.gif
Модификатор модели памяти

Значение модификатора

Назначение

use16

Сегменты выбранной модели используются как 16-битные (если соответствующей директивой указан процессор i80386 или i80486)

use32

Сегменты выбранной модели используются как 32-битные (если соответствующей директивой указан процессор i80386 или i80486)

dos

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


Модель памяти является обязательным параметром директивы MODEL. Этот параметр определяет модель сегментации памяти для программного модуля.

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

Модель

Тип кода

Тип данных

Назначение модели

TINY

near

near

Код, данные и стек объединены в одну группу с именем DGROUP и размером до 64Кб. Используется для создания программ формата. com. Некоторые языки эту модель не поддерживают.
СS=DS=SS=DGROUP

SMALL

near

near

Код занимает один сегмент, данные и стек объединены в одну группу с именем DGROUP (хотя для описания могут использоваться разные сегменты). Эту модель обычно используют для большинства программ на ассемблере.
CS=_text
DS=SS=DGROUP

MEDIUM

far

near

Код занимает несколько сегментов, по одному на каждый объединяемый программный модуль. Все ссылки на передачу управления — типа far (вызов подпрограмм). Данные и стек объединены в одной группе DGROUP; все ссылки на них — типа near (для доступа к данным испльзуется только смещение).
CS=<модуль>_text
DS=SS=DGROUP

COMPACT

near

far

Код находится в одном сегменте, данные и стек в группе DGROUP и могут занимать несколько сегментов, так что для обращения к данным требуется указывать сегмент и смещение (
ссылка на данные — типа far).
CS=_text
DS=SS=DGROUP

LARGE

far

far

Код может занимать несколько сегментов, по одному на каждый объединяемый программный модуль. Стек и данные находятся в группе DGROUP. Для ссылки на данные используются дальние указатели - far.
CS=<модуль>_text
DS=SS=DGROUP

HUGE

far

far

Тоже что и модель LARGE, что касается TurboAssebmler.

FLAT

far

far

Тоже, что и TINY, но используются 32-битная адресация, так что максимальный размер сегмента, содержащего и данные, и код, и стек - 4Гб.


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

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

Формат директивы
(режим MASM)

Формат директивы
(режим IDEAL)

Назначение

.CODE [имя]

CODESEG[имя]

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

.DATA

DATASEG

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

.CONST

CONST

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

.DATA?

UDATASEG

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

.STACK [размер]

STACK [размер]

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

.FARDATA [имя]

FARDATA [имя]

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

.FARDATA? [имя]

UFARDATA [имя]

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


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

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

Идентификаторы, создаваемые директивой MODEL

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

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

@code

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

@data

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

@fardata

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

@fardata?

Физический адрес сегмента неинициализированных данных типа far

@curseg

Физический адрес сегмента неинициализированных данных типа far

@stack

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


Если вы посмотрите на текст примера, то увидите пример использования одного из этих идентификаторов. Это @data – с его помощью мы получили значение физического адреса сегмента данных нашей программы.

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

Языкнеобязательный операнд, принимающий значения C, PASCAL, BASIC, FORTRAN, SYSCALL и STDCALL. Если он указан, подразумевается, что процедуры рассчитаны на вызов из программ на соответствующем языке высокого уровня, следовательно, если указан язык C, все имена ассемблерных процедур, объявленных как PUBLIC, будут изменены так, чтобы начинаться с символа подчеркивания, как это принято в C.
Модификаторнеобязательный операнд, принимающий значения NEARSTACK (по умолчанию) или FARSTACK. Во втором случае сегмент стека не будет объединяться в одну группу с сегментами данных.
После того как модель памяти установлена, вступают в силу упрощенные директивы определения сегментов, объединяющие действия директив SEGMENT и ASSUME. Кроме того, сегменты, объявленные упрощенными директивами, не требуется закрывать директивой ENDS — они закрываются автоматически, как только ассемблер обнаруживает новую директиву определения сегмента или конец программы.

Директива.CODE описывает основной сегмент кода

.code имя_сегмента

эквивалентно:

_TEXT segment word publicCODE

для моделей TINY, SMALL и COMPACT

name_TEXT segment word publicCODE

для моделей MEDIUM, HUGE и LARGE (name — имя модуля, в котором описан данный сегмент). В этих моделях директива. CODE также допускает необязательный операнд — имя определяемого сегмента, но все сегменты кода, описанные так в одном и том же модуле, объединяются в один сегмент с именем NAME_TEXT.

Директива.STACK описывает сегмент стека

.stack размер

эквивалентно:

STACK segment para publicstack

Необязательный параметр указывает размер стека. По умолчанию он равен 1 Кб.

Директива.DATA описывает обычный сегмент данных

.data

эквивалентно:

_DATA segment word publicDATA

Директива.DATA? описывает сегмент неинициализированных данных

.data?

Эквивалентно:

_BSS segment word publicBSS

Этот сегмент обычно не включается в программу, а располагается за концом памяти, так что все описанные в нем переменные на момент загрузки программы имеют неопределенные значения.

Директива.CONST описывает сегмент неизменяемых данных

.const

Эквивалентно:

CONST segment word publicCONST

В некоторых операционных системах этот сегмент будет загружен так, что попытка записи в него может привести к ошибке.

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

.fardata имя_сегмента

эквивалентно:

имя_сегмента segment para privateFAR_DATA

Доступ к данным, описанным в этом сегменте, потребует загрузки сегментного регистра. Если не указан операнд, в качестве имени сегмента используется FAR_DATA.

Директива.FARDATA? описывает сегмент дальних неинициализированных данных

.fardata? имя_сегмента

эквивалентно:

имя_сегмента segment para privateFAR_BSS

Как и в случае с FARDATA, доступ к данным из этого сегмента потребует загрузки сегментного регистра. Если имя сегмента не указано, используется FAR_BSS.

Во всех моделях памяти сегменты, представленные директивами. DATA, .DATA?, .CONST, .FARDATA и. FARDATA?, а также сегмент, описанный директивой. STACK, если не был указан модификатор FARSTACK, и сегмент. CODE в модели TINY автоматически объединяются в группу с именем FLAT — для модели памяти FLAT или DGROUPдля всех остальных моделей. При этом сегментный регистр DS (и SS, если не было FARSTACK, и CS в модели TINY) настраивается на всю эту группу, как если бы была выполнена команда ASSUME.

Порядок загрузки сегментов

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

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

Порядок загрузки сегментов:

1. Все сегменты класса 'CODE'.
2. Все сегменты, не принадлежащие группе DGROUP и классу 'CODE'.
3. Группа сегментов DGROUP:
3.1. Все сегменты класса 'BEGDATA'.
3.2. Все сегменты, кроме классов 'BEGDATA', 'BSS' и 'STACK'.
3.3. Все сегменты класса 'BSS'.
3.4. Все сегменты класса 'STACK'.

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

P. S. В книге Зубкова, порядок загрузки сегментов описан несколько иначе, НО практика показала, что его описание не правильное. При использовании упрощенных директив сегментации, директива .seq, которая, по идее должна устанавливать порядок загрузки сегментов, как они описаны в прорамме, этого не делает! А делает это дериктива .alpha, и то, только при использовании TASM, только в модели small, и при этом она добавляет заголовок в exe файл длиной 600h байт! MASM же, при использовании упрощенных директив сегментации всегда размещает сегменты в соответствии с порядком MS DOS, забивая на директивы. seq и. alpha. И еще с выравниванием сегментов, при использовании упрощенных директив сегментации, происходит какая-то свистопляска :). Все это выявлено опытным путем. Все в следующих сериях супер сериала "Hello World". И так, жем вас у экранов мониторов :)

Автор: -=*=- Ярлыки: директива MODEL, директива SEGMENT, синтаксис ассемблера на 7:51

0 коммент.:

Отправить комментарий

Следующее Предыдущее Главная страница