|
|
|
|
Адресация к данным во множественных структурах
Одной из удобных возможностей использования структур является то, что Вы можете в любое время переорганизовывать описание структуры или
добавлять к нему новые элементы, которые будут автоматически изменяться при ассемблировании. Например, изменим предыдущую структуру MathList так,
чтобы в ней поменялись местами двоичные числа с плавающей запятой и добавился элемент LibraryPtr.
MathNumbers STRUC
Float1 DT (0) ;1 10-байтовое слово
Float2 DT (0) ;1 10-байтовое слово
ShortInteger1 DW (0) ;1 слово
ShortInteger2 DW (0) ;1 слово
LongInteger1 DD (0) ;1 двойное слово
LongInteger2 DD (0) ;1 двойное слово
Boolean1 DB (0) ;1 байт
Boolean2 DB (0) ;1 байт
LibraryPtr DD (?) ;1 двойное слово
MathNumbers ENDS
|
В нашем случае преимущество использования имен структур в том, что после реассемблирования всей программы и элементов данных новое описание
структуры [di].Float1 по-прежнему будет указывать на первое число с плавающей запятой, хотя мы и реорганизовали данные. Таким образом, программный
код, который ссылается на данные по именам структур, не требует корректировки. Заметим, однако, что если данные файла используют старые описания
структур, мы должны перегруппировать существующие данные так, чтобы они отвечали новой структуре. Реорганизация структуры не перегруппировывает
существующие данные, для них лишь объявляется относительное местоположение. Мы должны убедиться, что действительные данные соответствуют объявлению
структуры данных.
В отличие от структур языка Си структуры MASM не могут содержать описания других структур (для этого нет особых причин, и, вероятно, в более
старших версиях MASM это ограничение будет снято). Однако нет причины, чтобы структура не могла содержать адрес другой структуры, вот почему мы включили
в структуру элемент LibraryPtr. Предположим, что у нас есть структура Library, определенная так:
Library STRUC
FloatLib DD (0) ;указатель на библ. с ПЗ
ShortIntLib DD (0) ;указатель на библ. с коро-
;ткими целыми
LongIntLib DD (0) ;указатель на библ. с длин-
;ными целыми
ВooleanLib DD (0) ;указатель на библ. с бу-
;левыми значениями
Library ENDS
|
Теперь мы можем определить набор библиотечных программ с адресами, организованными в структуры. Например,
АddLibs Library
Sublibs Library
MultLibs Library
.
.
.
|
Такая комбинация структур может быть использована как показано в следующем программном сегменте:
lds si,MathList[bx] ;адрес конкретной структуры
push ds ;сохранить адрес структуры данных
push si
lds si,LibraryPtr ;адрес адресов библиотеки
call [ds:si].LongIntLib ;переход на выполнение
;операции
|
Cоответствующие указатели загружаются в структуру или во время ассемблирования, или во время выполнения программы. Прелесть использования адреса
структуры для передачи в подпрограммы параметров и указателей в том, что вызывающий программный код всегда один и тот же, несмотря на количество
изменений структуры, проводимых в течение всей жизни программы. Помещая в структуру указатели на другие структуры данных, мы избавляем программный код
от необходимости знания деталей о данных и/или вызываемых операциях. Такое "сокрытие данных" развито и более часто используется в объектно ориентированных
языках типа С++ или Smalltalk, однако Вы можете добиться почти того же самого, применяя только структуры. Применить определенную Вами структуру можно
также и к набору данных, который создан не Вами. Например, получить доступ к первым 22 байтам PSP (префикс программного сегмента), которые MS-DOS
помещает в начало выполняемых файлов, можно через следующую структуру:
PSP STRUC
INT32 DB 2 DUP (?) ; 2 байта
MemSize DW (?) ; 1 слово
Reserved DB (?) ; 1 байт
DOSCall DB 5 DUP (?) ; 5 байтов
TermVctr DW 2 DUP (?) ; 2 слова
BreakVctr DW 2 DUP (?) ; 2 слова
ErrorVctr DW 2 DUP (?) ; 2 слова
PSP ENDS
|
Получить доступ к PSP можно при помощи следующего программного фрагмента:
mov di,0 ; PSP начинается со смещения 0
push cs ; сегмент PSP в cs
pop ds ; сегмент PSP -> ds
mov si,[di].MemSize ; размер памяти программы ->
; экстра сегмент
|
|
|