Как работает $ в NASM?

message db "Enter a digit ", 0xA,0xD Length equ $- message 

Используется ли она для получения длины строки?
Как это работает внутри страны?

$ – адрес текущей позиции, прежде чем испускать байты (если есть) для строки, в которой он отображается. Раздел 3.5 руководства не вникает в детали.

$ - msg как делать here - msg , т.е. расстояние в байтах между текущей позицией (в конце строки) и началом строки. ( См. Также этот учебник по этикеткам NASM и директивам, таким как resb )

(Связано: Большинство других ассемблеров x86 также используют $ таким же образом, за исключением GAS, который использует . (Период). Ассемблер MMIX использует @ , который имеет правильное семантическое значение).


Чтобы понять это лучше, это может помочь узнать, что происходит, когда вы ошибаетесь: на ярлыках NASM рядом друг с другом в памяти возникают проблемы с печатью . Этот человек использовал

 HELLO_MSG db 'Hello, World!',0 GOODBYE_MSG db 'Goodbye!',0 hlen equ $ - HELLO_MSG glen equ $ - GOODBYE_MSG 

в результате чего hlen включает длину обеих строк.

EQU оценивает правую сторону, до постоянного значения. (В некоторых ассемблерах, таких как FASM, equ – это текстовая подстановка, и вы должны использовать glen = $ - GOODBYE_MSG для оценки с помощью $ в этой позиции вместо оценки $ в более поздней mov ecx, glen инструкции mov ecx, glen или что-то в этом роде. место, использование %define для текстовых замещений)


Использование $ точно эквивалентно помещению метки в начало строки и использованию ее вместо $ .

Пример размера объекта также может быть выполнен с использованием стандартных меток:

 msg: db "Enter a digit " msgend: Length equ msgend - msg Length2 equ $ - msg ; Length2 = Length newline: db 0xA,0xD Length3 equ $ - msg ; Length3 includes the \n\r LF CR sequence as well. ; sometimes that *is* what you want 

Вы можете поместить Length equ msgend - msg любом месте или mov ecx, msgend - msg напрямую. (Иногда полезно иметь метку в конце чего-то, например cmp rsi, msgend / jb .loop внизу цикла.

Кстати, это обычно CR LF, а не LF CR.


Менее очевидные примеры:

 times 4 dd $ 

аналогично этому (но без создания записи в виде таблицы символов или столкновения с существующим именем):

 here: times 4 dd here 

В times 4 dd $ , $ не обновляет свой собственный адрес для каждого слова, он по-прежнему является адресом начала строки. (Попробуйте в файле сам по себе и hexdump плоский двоичный файл: это все нули.)


Но блок %rep расширяется до $ , поэтому

 %rep 4 dd $ %endrep 

производит 0, 4, 8, 12 (начиная с выходного положения 0 в плоском двоичном файле для этого примера).

 $ nasm -o foo rep.asm && hd foo 00000000 00 00 00 00 04 00 00 00 08 00 00 00 0c 00 00 00 

Перемещение смещений в ручном режиме:

Нормальным прямым call является E8 rel32 , причем смещение вычисляется относительно конца инструкции. (т. е. относительно EIP / RIP во время выполнения команды, поскольку RIP содержит адрес следующей команды. Режимы RIP-относительной адресации тоже работают). Диск имеет 4 байта, поэтому в псевдо-инструкции dd с одним операнд, адрес конца – $+4 . Разумеется, вы могли бы просто поместить ярлык на следующую строку и использовать это.

 earlyfunc: ; before the call call func ; let NASM calculate the offset db 0xE8 dd func - ($ + 4) ; or do it ourselves db 0xE8 dd earlyfunc - ($ + 4) ; and it still works for negative offsets ... func: ; after the call 

вывод parsingки (из objdump -drwC -Mintel ):

 0000000000400080 : 400080: e8 34 00 00 00 call 4000b9  # encoded by NASM 400085: e8 2f 00 00 00 call 4000b9  # encoded manually 40008a: e8 f1 ff ff ff call 400080  # and backwards works too. 

Если вы ошиблись в смещении, objdump поместит символическую часть как func+8 , например. Относительное смещение в первых двух call rel32 вызова отличается на 5, потому что call rel32 имеет call rel32 5 байтов, и они имеют одинаковое фактическое назначение, а не одно и то же относительное смещение. Обратите внимание, что дизассемблер позаботится о добавлении rel32 в адрес инструкций вызова, чтобы показать вам абсолютные адреса назначения.

Вы можете использовать db target - ($+1) для кодирования смещения для короткого jmp или jcc . (Но будьте осторожны: db 0xEB, target - ($+1) не прав, потому что конец инструкции на самом деле равен $+2 когда вы помещаете как код операции, так и смещение в виде нескольких аргументов для одной и той же псевдо-инструкции db .)


Связано: $$ – это начало текущего раздела , поэтому $ - $$ – это то, насколько далеко вы находитесь в текущем разделе. Но это только в текущем файле, поэтому связывание двух файлов, .rodata материал в .rodata , отличается от наличия двух блоков section .rodata в том же исходном файле. Посмотрите, каков реальный смысл $$ в nasm .

На сегодняшний день наиболее распространенным является times 510-($-$$) db 0 / dw 0xAA55 для dw 0xAA55db 0 ) загрузочного сектора до 510 байт, а затем добавить подпись загрузочного сектора, чтобы сделать 512 байт. ( Руководство NASM объясняет, как это работает )

  • Какова цель инструкции LEA?
  • Ссылка на содержимое ячейки памяти. (режимы адресации x86)
  • Безопасно ли читать конец конца буфера на одной странице на x86 и x64?
  • Прямой просмотр программы
  • Сборка скомпилированного исполняемого файла на Bash на Ubuntu в Windows не производит вывод
  • Получение максимального значения в векторе __m128i с SSE?
  • Изменение целевых настроек процессора в Visual Studio 2010 Express
  • Что такое инструкции IN & OUT для x86?
  • Как сгенерировать код сборки с clang в синтаксисе Intel?
  • Может ли x86 переупорядочить узкий магазин с более широкой нагрузкой, которая полностью его содержит?
  • Что означает «int 0x80» в коде сборки?
  • Interesting Posts

    Можно ли установить Windows 10 на Android-устройство?

    Строка против StringBuilder

    Изменить шрифт для не-устаревшей командной строки в Windows 10 с не-ASCII-кодировкой – Свойства по умолчанию?

    Программно ассоциировать расширения файлов с приложением в Windows

    Java SSL подключиться, добавить серверный сертификат в хранилище ключей программно

    переопределить css для проверки формы html5 / требуемого всплывающего windows

    Как сделать снимок экрана текущей активности, а затем поделиться ею?

    Обновление Windows 10 и Truecrypt

    Должен ли я всегда отключать обработчики событий в методе Dispose?

    Объедините две ветви с использованием Subversion

    SQLException: Не найдено подходящего драйвера для jdbc: derby: // localhost: 1527

    Запуск Windows с дефектной оперативной памятью

    Установка имени файла журнала для включения текущей даты в Log4j

    Каковы модификаторы доступа по умолчанию в C #?

    Прочитать размер шрифта в настройках

    Давайте будем гением компьютера.