Префикс REX.W для инструкции MOV x86-64 с сегментным регистром - PullRequest
2 голосов
/ 05 апреля 2019

Я читаю руководство разработчика x86 / x64 , пытаясь понять кодировку инструкций, и меня смутило перемещение из регистра сегмента, то есть 12-й и 13-й формы на этой странице .Есть два конкретных вопроса:

(1) Оба помечены префиксом REX.W, но, насколько я понимаю, этот флаг используется только тогда, когда размер операнда составляет 64 бита.Я понимаю, почему его следует использовать с r64, но кроме этого, почему эти две инструкции помечены префиксом REX.W?

(2) В обеих инструкциях есть пункт назначения m16, не дублирование?Почему эти две инструкции в первую очередь разделены?

Одна из причин, по которой я могу придумать для (2), заключается в том, что в первой форме r16 / r32 может быть выбран с префиксом 66H, а 66H игнорируется, когда REX.W существует (для r64).Но 66H, похоже, тоже не работает для m16, почему он включен во вторую форму (r64 / m16)?

Ответы [ 2 ]

3 голосов
/ 05 апреля 2019

Я считаю, что это ошибка редактирования. Я думаю, что префикс REX должен быть опущен в строке 12, чтобы контрастировать с 16-битной формой в строке 11 и 64-битной формой в строке 13 (так же, как существуют 16-, 32- и 64-битные формы для других вариантов).

(Возможно, была попытка объединить три формы в одну строку. Столбец «Описание» для этой записи говорит: « Переместить нулевой расширенный регистр 16-битного сегмента в r16 / r32 / r64 / m16", так что это согласуется с тем, что кто-то начинает объединять строки, а затем понимает, что строка r64 должна быть отдельной, но забывает удалить REX.W из 16/32-битной строки.)

Я думаю, что причина того, что m16 появляется во всех трех формах, заключается в том, что перемещение из регистра сегмента в память всегда составляет 16 бит , независимо от размера операнда. mov из SR - странная инструкция.


Нет смысла использовать 64-битную форму: все процессоры, поддерживающие 64-битный режим, расширяются от нуля до полного размера регистра без префиксов.

Верхние биты регистра назначения равны нулю для ... и всех процессоров Intel 64.

Исключением являются 32-разрядные ЦП, более старые, чем Pentium Pro, и Quark (на основе P5) , которые также являются 32-разрядными.

Я не проверял руководства AMD, чтобы увидеть, есть ли вероятность того, что любые процессоры AMD64 могут оставить верхние 6 байтов RAX неопределенными или неизмененными для 8c d8 (mov eax,ds без префиксов). Но в руководстве Intel ясно, что все процессоры Intel64 будут расширяться от нуля до 32-разрядного (и, следовательно, неявно до 64-разрядного, как всегда при записи 32-разрядного регистра).


Префикс размера операнда 66h может использоваться для кодирования 66 8c d8 (mov ax,ds), который оставляет старшие байты RAX неизменными (как всегда для записи 16-битного регистра).

Обычно вы этого никогда не захотите, но префикс размера операнда влияет на mov reg, SR в отличие от REX.W.

1 голос
/ 05 апреля 2019

Руководство уже несколько десятилетий печально известно своими опечатками и (само) несоответствиями.И это не единственный, первый или последний неаккуратный.Так что не должно быть большого удивления, если только это не ваше первое руководство, которое когда-либо читалось.

Да, REX.W не имеет большого смысла с размерами операндов меньше 64 бит.

Однако, префикс REX может быть там (если в 64-битном режиме), но с .W = 0, и в этом случае размер операнда будет 32-битным.То есть, если не существует префикса размера операнда (66H), который перевернет его до 16 бит.

И может быть REX. [RXB] для изменения кодировки адреса операнда (для использования регистров r8 и выше) без изменения размера операнда.

...