0988b24c

Доступ к данным в сегменте, принадлежащем группе


В режиме Ideal любой элемент данных в сегменте, являющемся частью группы, рассматривается строго как элемент группы, а не сегмента. В Турбо Ассемблере для распознавания элемента данных, как элемента сегмента, нужно использовать явное переопределение сегмента.

В режиме MASM это интерпретируется по-другому. Иногда иден- тификаторы считается частью сегмента, а не частью группы. В част- ности, в режиме MASM идентификатор интерпретируется, как часть сегмента, когда он используется, как указатель на выделенные дан- ные. Это может вызвать путаницу, так как когда вы непосредственно обращаетесь к данным без операции OFFSET, MASM некорректно гене- рирует ссылку на сегмент вместо ссылки на группу.

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

dseg1 SEGMENT para public 'data'

v1 db 0 dseg1 ENDS

dseg2 SEGMENT para public 'data' v2 db 0 dseg2 ENDS

dseg3 SEGMENT para public 'data' v3 db 0 dseg3 ENDS

DGROUP GROUP dseg1,dseg2,dseg3 cseg SEGMENT para public 'code'

ASSUME cs:cseg,ds:DGROUP

start: mov ax,OFFSET v1 mov bx,OFFSET v2 mov cx,OFFSET v3 cseg ENDS END start

Три сегмента dseg1, dseg2 и dseg3 группируются под одним именем DGROUP. В результате все переменные отдельных сегментов хранятся в памяти вместе. В исходном тексте программы в каждом из отдельных сегментов описывается байтовая переменная (метки v1, v2 и v3).

В коде данной программы MASM в регистры AX, BX и CX загружа- ются смещения адресов этих переменных. В соответствии с предшест- вующей директивой ASSUME и из-за того, что сегменты данных сгруп- пированы вместе, вы можете подумать, что MASM будет вычислять смещения переменных относительно всей группы, в которой перемен- ные очевидно хранятся в памяти.

Но произойдет совсем не это! Вопреки вашим намерениям MASM вычисляет смещения переменных относительно отдельных сегментов dseg1, dseg2 и dseg3. Он делает это несмотря на то, что все три сегмента данных сгруппированы в памяти в один сегмент данных, ад- ресуемый через регистр DS. Бессмысленно определять смещения пере- менных относительно отдельных сегментов в тексте программы, ког- да эти сегменты скомбинированы в памяти в один сегмент. Единственный способ ссылки на такие переменные состоит в ссылке на их смещения относительно всей группы.


Чтобы избавиться в MASM от этой проблемы, вам потребуется наряду с ключевым словом OFFSET задавать имя группы:

mov ax,OFFSET DGROUP:v1 mov bx,OFFSET DGROUP:v2 mov cx,OFFSET DGROUP:v3

Хотя теперь это ассемблируется корректно и загружаются сме- щения переменных v1, v2 и v3 относительно DGROUP (где собраны от- дельные сегменты), вы можете легко забыть задать квалификатор DGROUP. Если вы сделаете эту ошибку, значения смещений не позво- лят корректно определить переменные в памяти, и вы не получите в MASM никакого указания, что что-то произошло не так. Режим Ideal позволяет избежать таких неприятностей:

IDEAL SEGMENT dseg1 para public 'data' v1 db 0 ENDS

SEGMENT dseg2 para public 'data' v2 db 0 ENDS

SEGMENT dseg3 para public 'data' v3 db 0 ENDS

GROUP DGROUP dseg1, dseg2, dseg3 SEGMENT cseg para public 'code'

ASSUME cs:cseg,ds:DGROUP

start: mov ax,OFFSET v1 mov bx,OFFSET v2 mov cx,OFFSET v3 ENDS END start

Смещения переменных v1, v2 и v3 корректно вычисляются отно- сительно группы, в которой собраны отдельные сегменты, которым принадлежат переменные. В режиме Ideal квалификатор DGROUP для ссылки на переменные в сегментах группы не требуется. В режиме MASM этот квалификатор также не является необходимым, но, что ху- же всего, не выдается никаких предупреждений, если вы забыли в конкретной ссылке определить имя группы.


Содержание раздела