2016-10-29 23 views
6

Я новичок здесь и только начинаю изучать язык ассемблера. Поэтому, пожалуйста, поправьте меня, если я ошибаюсь, или если этот пост не имеет никакого смысла, я удалю.Разница между movq и movabsq в x86-64

Я говорю о инструкциях по перемещению данных в архитектуре Intel x86-64. Я прочитал, что обычная команда movq может иметь только непосредственные операнды источника, которые могут быть представлены как номера дополнений 32-разрядных двоичных чисел, тогда как команда movabsq может иметь произвольное 64-битное непосредственное значение в качестве исходного операнда и может иметь только регистр как пункт назначения.

Не могли бы вы рассказать об этом? Означает ли это, что я могу переместить 64-битное мгновенное значение, используя инструкцию movabsq? И только от непосредственного значения к регистру? Я не вижу, как я могу перемещать 64-битное мгновенное значение в память. Или, может быть, я ошибся что-то важное здесь.

+2

Вы должны перенести его в регистр, а затем в память. Вот и все. –

ответ

11

В синтаксисе NASM/Intel mov r64, 0x... выбирает a MOV encoding на основе константы. Есть четыре варианта с немедленными операндами:

  • 5 байт mov r32, imm32. (zero-extended to fill the 64-bit register like always). AT & T: mov/movl
  • 6 байт mov r/m32, imm32. только полезно для назначения памяти. AT & T: mov/movl
  • 7 байт mov r/m64, sign-extended-imm32. Может хранить 8 байтов в памяти или установить 64-разрядный регистр на отрицательное значение. AT & T: mov/movq
  • 10 байт mov r64, imm64. (Это версия REX.W = 1 одного и того же кода операции, как mov r32, imm32) AT & T: movabs

(отсчеты байт только для назначения регистра или режимов адресации, которые не нуждаются байта SIB или disp8/disp32:. только опкод + ModR/М + imm32)


в газе с AT & T синтаксис

movabsq означает, что машины кодировка кодировки будет содержать 64-битное значение: либо постоянную константу, либо абсолютный адрес памяти. Без movabsq, он не может.

Некоторые из них упоминаются в этом what's new in x86-64 guide с использованием синтаксиса AT & T.

movq всегда является 7-байтовой формой, поэтому не используйте mov $1, %rax, если вы не хотите использовать более длинную инструкцию для выравнивания (вместо заполнения с помощью NOP позже). Используйте mov $1, %eax, чтобы получить 5-байтовую форму.

Интересный эксперимент: movq $0xFFFFFFFF, %rax, вероятно, не encodeable, потому что это не представимо с знаком с увеличенным 32-битовый непосредственный а, и нужно либо imm64 кодирование или кодирование в %eax назначения.

movabs с непосредственным источником всегда является формой imm64. (movabs также может быть кодировкой MOV с 64-битным абсолютным адресом и RAX в качестве источника или dest: REX.W + A3MOV moffs64, RAX).


Некоторые Intel-синтаксис монтажники (но не GAS) оптимизирует 32-битные константы 5-бытье mov r32, imm32 (NASM делает это), в то время как другие (как Yasm) будет использовать 7-байт mov r/m64, sign-extended-imm32. Оба они выбирают кодировку imm64 только для больших констант, без необходимости использовать специальную мнемонику.


Я не понимаю, как я могу переместить непосредственное значение 64-разрядной памяти.

Это отдельный вопрос, и ответ таков: вы не можете. Значение insn ref manual entry for MOV делает это ясным: единственная форма, которая имеет немедленный операнд imm64, имеет только регистр, а не r/m64.

Если ваше значение вставляется в 32-битный расширенный знак, movq $0x123456, 32(%rdi) сделает 8-байтовый магазин в память. Ограничение в том, что это только imm32.

+0

[Загрузить с 64-разрядного адреса в другой регистр, чем rax] (http://stackoverflow.com/q/19415184/995714) –

+0

Почему 'movq $ 0xFFFFFFFF,% rax' не кодируется? почему не работает 5-байтная версия? –

+0

@ LưuVĩnhPhúc: Потому что вы использовали 'movq'. Чтобы получить газ для использования 5-байтовой кодировки без REX-префикса, вы должны сделать оптимизацию самостоятельно и написать 'movl $ 0xFFFFFFFF,% eax'. Так что это похоже на YASM и не будет оптимизировать это для вас. –