Я читаю некоторую сборку для MASM, и мне трудно понять цель директивы сегмента. Чем он отличается от меток при вычислении адреса при сборке? Предположим, что директива формы - это просто name segment at addr, меня не особо интересуют другие ее параметры. Что такое

BootSeg segment at 0x7c0
BootSeg end

Хорошо, если внутри ничего нет?

Какую ценность вы имели бы в топоре, если бы сделали:

mov ax, BootSeg

?

1
Pyjong 23 Сен 2012 в 15:44
Это вопрос адресации памяти, в частности адресации в реальном режиме. Я бы посоветовал вам узнать больше об этом в руководствах для разработчиков Intel или в Википедии. Или проверьте этот аналогичный вопрос: stackoverflow.com/ questions / 12439241 /…
 – 
Jay
23 Сен 2012 в 16:40
Я знаю, что такое сегментные регистры и как они работают. Я не понимаю, как ассемблер может гарантировать, что эти регистры загружены тем, что написано в этой директиве.
 – 
Pyjong
23 Сен 2012 в 17:12
1
Это не так. Он только сообщает компилятору, что что-либо внутри этого сегмента сегмента находится в этом конкретном сегменте памяти, так что любой код вне этого сегмента сегмента может правильно ссылаться на него, например: mov ax, BootSeg. Явный адрес сегмента (вместе с директивой ORG) обычно используется для таблицы векторов прерываний, области данных BIOS, видеопамяти и т. Д., Где фактические данные не поступают из двоичного файла. Это похоже на шаблон структуры данных, привязанный к определенному сегменту памяти.
 – 
Jay
23 Сен 2012 в 18:22
Для меня это звучит как ярлык. Это правильное предположение? За исключением случаев, когда вы объявляете недействительный сегмент, он служит «меткой равного адреса». Верно? И каково окончательное значение топора сверху? это 7c00h или 7c0h?
 – 
Pyjong
23 Сен 2012 в 18:44
Да, это похоже на ярлык. Но EQU предназначен для объявления констант, а не только для метки. Регистр ax будет 07C0h, как указано в директиве SEGMENT AT.
 – 
Jay
23 Сен 2012 в 19:00

1 ответ

Лучший ответ

Директива segment в некотором роде универсальна.

Первое использование - объединение вещей в сегменты.

Второе использование - это правильная ссылка (= вычисление адреса) объектов в различных сегментах. В зависимости от сегмента объекта, к которому осуществляется доступ в вашем коде, ассемблер может вставить соответствующие segment override prefixes (es:, ss:, cs:, fs:, gs:) в сгенерированный код. Точно так же при вызове procedure из другого сегмента кода ассемблер может сгенерировать инструкцию far call вместо near call. AFAIR, для этого вам действительно нужно пометить сам procedure как far (и это также превратит все простые rets в far rets в подпрограмме).

Сегменты затем обрабатываются компоновщиком и превращаются в информацию о перемещении, которую потребляет ОС.

Зачем нам эти сегменты? Потому что они есть в ЦП, и мы не всегда можем игнорировать их существование. Существуют программы DOS .COM, которые помещают свой код, данные и стек в один сегмент, и в этом случае программа не должна усложняться понятием сегментов (за исключением тех случаев, когда ей нужен доступ к некоторому «чужому» коду / данные, а не из собственного сегмента).

И да, вещь AT в основном накладывает один объект на другой. Таким образом, mov ax, BootSeg должен дать вам ax = 0x7c0, как и с любым другим сегментом, за исключением того, что этот сегмент известен во время "компиляции".

Воспользуйтесь отладчиком, поэкспериментируйте.

6
Alexey Frunze 24 Сен 2012 в 00:36