Директива assume. Инициализация сегментных регистров и замена сегментов. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Директива assume. Инициализация сегментных регистров и замена сегментов.



 

В программе с помощью assume устанавливается соответствие сегмента команд text сегментному регистру CS и сегмента данных data1-сегментному регистру DS:

Assume CS:text, DS:data1

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

assume CS:text

должен стоять в программе до любых программных строк и даже до объявления процедур. Что касается регистра DS, то, если это соответствие не описано в первой директиве assume, оно может быть описано позже, например:

assume DS:data1

fill: mov raw[BX],DL

Поскольку к моменту трансляции указанной выше команды mov, транслятор уже знает из директивы assume, что сегмент data1 сопоставляется с регистром DS, а имя raw описано именно в сегменте data1, команда транслируется в такой код, что процессор при его выполнении обратится к ячейке памяти с относительным адресом raw[BX], взяв сегментный адрес из регистра DS. Транслятор выполняет (не слишком строгую) проверку правильности ссылок на данные, так что если бы ячейка raw входила в другой сегмент, была бы зафиксирована ошибка. Т.о. описание в директиве assume соответствия сегментного регистра DS сегменту данных позволяет в какой то степени контролировать правильность написания программы и, главное, избавляет нас от необходимости указывать в каждой строке, содержащей ссылку на имя данных, в каком сегментном регистре находится сегментный адрес этих данных. По умолчанию подразумеваться регистр DS.

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

mov AX,data1

mov DS,AX

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

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

mov ES:oddbit[DI],DL

….

Parity: mov ES:evenbit[SI],DL

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

mov AX,data2

mov ES,AX

Директива assume создать умолчание и для регистра ES. Однако, для этого необходимо, чтобы дополнительный сегмент данных data2 был описан в программе до сегмента команд:

data2 segment

data2 ends

text segment ‘code’

. assume CS:text, DS:data1,ES:data2

.

. mov oddbit[DI],DL;по умолчанию берется регистр ES, т.к.

;oddbit находится в data2

В этом случае директива assume ES:data2 избавляет нас от необходимости указывать в явной форме регистр ES во всех командах с обращением к данным из сегмента data2. Если таких строк много, то это несколько упрощает процесс написания программы. Некоторого улучшения можно достигнуть, заменив адресацию со смещением на чисто регистрово-базовую, индексную или базово-регистровую.

 

mov BX,offset raw;

fill: mov [BX],DL

mov SI, offset evenbit

mov DI, offset oddbit

pros: mov DL,[BX]

mov ES:[DI],DL

parity: mov ES:[SI],DL

 

Во всех 3-х массивах теперь пересчитываются не индексы внутри массивов, а смещение блоков массивов относительно начал соответствующих сегментов. Директива позволяет в некоторых случаях не указывать в командах программы сегментные регистры, однако она не запрещает это делать в случае необходимости. Часто к одному сегменту приходится обращаться то через один, то через другой сегментный регистр. Такая ситуация типична при выполнении команд обработки строк.

Источник ES:DI

Приёмник DS:SI

И потом источник и приёмник меняются местами

Здесь как бы не было объявлено соответствие сегментных регистров, придётся воспользоваться префиксом замены сегмента.

Директива assume может использоваться внутри программы неоднократно.

; Сегмент данных

data segment

mem1 DW?

mem2 DW?

data ends

;ПРОГРАММНЫЕ СТРОКИ В СЕГМЕНТЕ КОМАНД

assume DS:data

mov AX,mem1;команда будет выполняться

mov BX,mem2; как AX,DS:mem1

assume DS:nothing

assume ES:data;команда будет выполняться

mov AX,mem1; как AX,ES:mem1

mov BX,mem2

 

Директива assume DS:nothing (ничего) снимает закрепление за сегментом data регистра DS и позволяет закрепить за сегментом другой регистр assume ES:data.

Очевидно, что независимо от директивы assume, перед первым участком необходимо настроить на сегмент data регистр DS, а перед вторым-ES.

 

Структуры и записи.

 

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

Рассмотрим в качестве примера задачу определения метки тома (дискеты или жесткого диска).

Метка тома создаётся обычно с помощью команды DOS LABEL. Метка может иметь до 11 символов, разрешённых в именах файлов, причём большую часть знаков кодовой таблицы (включая русские буквы и псевдографические символы), хотя рекомендуется использовать в метке только цифры, латинские буквы и некоторые специальные знаки - _ ~ $! @ # %.

Метка занимает один из блоков данных корневого каталога, предназначенных для записей о создаваемых в корневом каталоге файлах и подкаталогах и представляется системе как один из файлов этого каталога. Чтобы отличить метку тома от файла, ей присваивают атрибут 8, кроме того, в записи о метке поля длины и начального кластера заполняются нулями. В то же время метка, как и обычный файл или каталог, характеризуются датой и временем создания. Метка всегда создаётся в корневом каталоге на каждом томе может быть только одна метка.

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

Для поиска файлов в каталогах в DOS предусмотрены две функции – 4EH (поиск первого файла) и 4FH (поиск следующих файлов)

Обычно эти функции используются для поиска всех файлов соответствующих указанному шаблону групповой операции, например, всех прогаммных файлов (*.ЕХЕ или *.СОМ) или всех файлов с определённым именем PRIM.*, кроме того можно указывать атрибуты искомых файлов. При поиске группы файлов сначала вызывается функция поиска первого файла, для которой в качестве входных параметров указывается групповое имя искомых файлов и их атрибуты. После нахождения первого файла из группы вызывается (в цикле) функция поиска следующих файлов, для неё входные параметры отсутствуют. Поиск следующих файлов ведётся до тех пор, пока функция, устанавливающая флаг CF не сообщит, что больше файлов нет. Обе функции поиска, найдя первый или очередной файл, передают его характеристики (имя, размер, атрибуты, дату и время создания) в специальную системную область DTA (disk transfer area)- дисковая область передачи данных. Эта область располагается в PSP со смещением 80h. Пользователь может создать альтернативную DTA в своём сегменте данных, для чего предусмотрена функция DOS с номером 1Ah. Адрес текущей DTA определяется с номером функции 2Fh.

Функции поиска файлов заполняют DTA след.образом:

 

Смещение Число байтов Содержание
00h   Недокументированная область
15h   Атрибуты файла или каталога
16h   Время создания файла
18h   Дата создания файла
1Ah   Логический размер файла в байтах
1Eh   Имя и расширение файла в ASCIIZ

 

 

Формат записи даты и времени создания файлов в каталоге и DTA

 

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

                             

 

 

Год месяц день

 

 

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

                             

 

 

Часы минуты сек/2

 

Имя и расширение файла записывается в DTA прописными буквами и разделяются точкой (отсутствующей в записи каталога). Спецификация завершается байтом с двоичным нулём. В отличие от формата каталога, если в имени меньше 8 символов, оно не дополняется пробелами. Т.о., спецификация может иметь длину от одного байта в позиции 1Аh (плюс нуль в позиции 1Вh) до 13 символов (8 символов в имени, точка, 3 символа в расширении и нуль), заполняющих всё отведённое для файла место от 1Еh до 2Аh.

Метки записываются в DTA точно также, как и имя файла. Получается, что если в метке больше 8 символов, между первыми 8-ю и последними 3-мя символами стоит точка. Это необходимо иметь в виду при программном анализе найденной метке тома.

Программа начинается с определения структуры DTA. Разложение структуры на реальную область позволяет использовать в программе вместо численного смещения к соответствующим полям более наглядные символические, кроме этого нет необходимости использовать описатели word ptr, byte ptr, которые обычно требуются при обращении к безымянным участкам памяти. С помощью функции 4Еh ищется первый файл (и единственный) в корневом каталоге А с атрибутом 8. Если DOS не нашла такого файла, то устанавливается СF.

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

Stobs- сохранить байт строки

Movsb- пересылка байта строки

Источник DS:SI

Приёмник ES:DI

Команда lea SI,[BX].fill_name загружает 1 регистр SI смещение и имени файла в DTA. Для указания смещения используется математическое объявление из структуры DTA. При этом базовый адрес находится в BX. Tочка перед мнемоническим обозначением file_name указывает на использование обозначений из определения структуры.

Lodsb заносит содержимое ячейки в AL, автоматически инкрементирует SI

Div DL делит AX на содержимое DL.

К обоим результатам добавляются коды символа ’0’.

Записи, как и структуры, представляют собой шаблоны, накладываемые на реальные данные с целью введения удобных мнемонических обозначений отдельных элементов данных. Ключевое слово record говорит о том, что имя date относится к записи, а year, moun, day мнемонические имена отдельнах битов полей. Включение в программу описания шаблона битовых полей позволяет отказаться от утомительногоопределения смещений конкретных полей внутри слова. Для этого используются операторы mask и width. Оператор mask вызывает … маску, в которой биты соответствуют данному … 1, а все остальные 0. Оператор width возвращает ширину (в битах) указанного поля записи. Так значение width day=5.

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 733; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.133.12.172 (0.03 с.)