Отличие памяти от константы в GNU как .intel_syntax

У меня есть инструкция, написанная в синтаксисе Intel (с использованием газа в качестве моего ассемблера), который выглядит следующим образом:

mov rdx, msg_size
...
msg: .ascii "Hello, world!\n"
     .set msg_size, . - msg

но команда mov собирается в mov 0xe,%rdx, а не mov $0xe,%rdx, как я ожидал. Как написать первую инструкцию (или определение msg_size) для получения ожидаемого поведения?

Ответ 1

В режиме GAS .intel_syntax noprefix:

  • OFFSET symbol работает как AT & T $symbol. Это похоже на MASM.
  • symbol работает как AT & T symbol (т.е. разыменование).
  • [symbol] всегда является эффективным адресом, никогда не являющимся непосредственным, в GAS и NASM/YASM. LEA не загружается с адреса, но он по-прежнему использует кодировку машинного интерфейса памяти. (Вот почему он использует тот же синтаксис).

Совет. Если вы знаете синтаксис AT & T или синтаксис NASM для чего-то, используйте это для создания нужной кодировки, а затем дизассемблируйте с помощью objdump -Mintel, чтобы узнать правильный синтаксис для .intel_syntax noprefx.

BTW, никакие проекты с открытым исходным кодом, о которых я знаю, содержат исходный код GAS intel_syntax. Если они используют газ, они используют синтаксис AT & T. В противном случае они используют NASM/YASM. (Иногда вы также видите встроенный asm MSVC в проектах с открытым исходным кодом).


GNU как .intel_syntax noprefix режим несколько похож на MASM, за исключением того, что магия не зависит от того, как определяются символы.

mov rdx, symbol всегда является нагрузкой. Значением символа является его адрес. т.е. с помощью .set создает (или изменяет) символ, который ведет себя точно так же, как наложение метки на что-то.

mov rdx, OFFSET symbol будет собрано до mov r/m64, imm32. Я забываю, если режим синтаксиса Intel позволяет собирать movabs r64, imm64 с большими операндами, но это не имеет значения, потому что статические данные/кодовые адреса всегда находятся в низком виртуальном адресном пространстве 2GiB, поэтому они вписываются в 32-битные расширенные подписки. (Это безопасно для записи mov edx, OFFSET symbol).