Почему инструкции x86-64 на 32-разрядных регистрах обнуляют верхнюю часть полного 64-разрядного регистра?


на x86-64 тур по руководствам Intel, Я читал

Пожалуй, самым удивительным фактом является то, что инструкция типа MOV EAX, EBX автоматически обнуляет верхние 32 бита RAX зарегистрироваться.

документация Intel (3.4.1.1 регистры общего назначения в 64-битном режиме в ручной базовой архитектуре), цитируемая в том же источнике, говорит нам:

  • 64-разрядные операнды генерируют 64-разрядный результат в месте назначения регистры общего назначения.
  • 32-разрядные операнды генерируют 32-разрядный результат, нулевое расширение до 64-разрядного результата в целевом регистре общего назначения.
  • 8-битные и 16-битные операнды генерируют 8-битный или 16-битный результат. Верхние 56 бит или 48 бит (соответственно) целевого регистра общего назначения не изменяются операцией. Если результат 8-битной или 16-битной операции предназначен для вычисления 64-битного адреса, то явным образом знак-расширьте регистрация до полного 64-бит.

в сборке x86-32 и x86-64, 16-битные инструкции, такие как

mov ax, bx

не показывайте такого "странного" поведения, что верхнее слово eax обнуляется.

таким образом: какова причина, по которой это поведение было введено? На первый взгляд это кажется нелогичным (но причина может быть в том, что я привык к причудам сборки x86-32).

2 82

2 ответа:

Я не AMD или говорить за них, но я бы сделал точно так же. Поскольку обнуление высокой половины не создает зависимости от предыдущего значения, ЦП придется подождать. Механизм переименования регистра был бы по существу побежден, если бы это не было сделано таким образом. Таким образом, вы можете писать быстрый 32-битный код в 64-битном режиме без необходимости явно нарушать зависимости все время. Без этого поведения каждая 32-битная инструкция в 64-битном режиме должна была бы ждать что-то, что случилось раньше, хотя эта высокая часть почти никогда не будет использоваться.

поведение для 16-битных инструкций о странном. Безумие зависимости является одной из причин того, что 16-битные инструкции теперь избегаются.

Это просто экономит место в инструкции, и набор инструкций. Небольшие непосредственные значения можно переместить в 64-разрядный регистр с помощью существующих (32-разрядных) инструкций.

Это также избавляет вас от необходимости кодировать значения 8 байт для MOV RAX, 42, когда MOV EAX, 42 можно использовать повторно.

эта оптимизация не так важна для 8 и 16 битных операций (потому что они меньше), и изменение правил там также нарушит старый код.