NASM — расширение метки с помощью битового флага

Мне нужно установить старший бит некоторого адреса/смещения метки.

Я старался:

тест.насм:

BITS 32

dw mylabel | 0x8000

mylabel:
dd 0

Но при попытке собрать это я получаю:

nasm -f bin test.nasm
test.nasm:3: error: `|' operator may only be applied to scalar values

Почему он не видит mylabel как скалярное значение? Я думал, что метки просто заменяются их адресом (скалярным значением) ассемблером.

Я использую nasm v 2.09.04, если это имеет значение.

Заранее благодарю за любую помощь.

EDIT: я смог использовать + вместо |. Похоже, что побитовые операторы не работают с метками. Как вы думаете, это специально или баг?


person masterxilo    schedule 05.12.2010    source источник


Ответы (2)


Метка является перемещаемым значением - ее значение изменяется компоновщиком/загрузчиком. Разница между двумя метками (в одном разделе) является скалярной величиной, и Nasm будет с ней работать.

дд (моя метка - $$) | 0x80000000

Я исправил заблуждение, что метка в 32-битном коде тоже 16-битная.

Для чего это предназначено?

Лучший, Фрэнк

person Frank Kotler    schedule 07.12.2010
comment
Предполагается, что dw хранит смещение (в виде 16-битного значения) метки mylabel от начала файла, но оно должно быть расширено с помощью некоторого флага. Я пишу раздел .reloc файла/образа win exe (PE) вручную. - person masterxilo; 07.12.2010

Я предполагаю, что это ограничение ассемблера, потому что nasm - это двухпроходный ассемблер, у которого есть трудности с "кодом, размер которого зависит от значения символа, объявленного после рассматриваемого кода".

http://www.posix.nl/linuxassembly/nasmdochtml/nasmdoc3.html

Раздел 3.7

person OmnipotentEntity    schedule 05.12.2010
comment
Но это также не работает, если я определяю mylabel раньше. - person masterxilo; 05.12.2010