Сборка: почему некоторые коды операций x86 недопустимы в x64?
Мой вопрос возникает из простого любопытства:
Почему в x64 некоторые коды операций недействительны (например, 06, 07), тогда как в x86 используются довольно простые инструкции (06 и 07 - push и pop)? Я думал, что эти простейшие инструкции будут хорошо работать в обеих архитектурах.
Почему они отключили некоторые из этих простых инструкций в x64? Почему они не работают? Почему они отключили некоторые коды операций, создавая дыры в списке кодов операций, когда вместо этого они могли назначить их для версий инструкций x64?
Ссылка:
2 ответа
Инструкции 06 и 07 в 32-битном режиме являются инструкциями PUSH ES
а также POP ES
, В 64-битном режиме регистры сегментов CS, DS, ES и SS больше не используются для определения адресов памяти: процессор принимает базовый адрес 0 и никаких ограничений по размеру. Поскольку теперь приложениям (кроме самой операционной системы) обычно нет причин для доступа к этим регистрам, коды операций для изменения и доступа к ним были удалены.
Сегментные регистры FS и GS могут по-прежнему устанавливать базовый адрес в 64-битном режиме, поэтому связанные с ними коды операций не были удалены.
Для всех процессоров есть что-то вроде "пространства кода операции". Например, если процессор использует 8-битные коды операций, тогда будет макс. из 256 инструкций, которые он мог бы иметь. Чем больше операционных кодов, тем больше у вас может быть операционных кодов, но тем сложнее их быстро получить и декодировать.
80x86 - относительно старая архитектура. Он начинался со скромного пространства кодов операций, состоящего в основном из 1-байтовых и 2-байтовых кодов операций. Каждый раз, когда производители процессоров добавляют новую функцию, она берет больше кодов операций из пространства кодов операций. У них закончились коды операций. Они быстро убежали.
Чтобы обойти это, они начали делать такие вещи, как добавление escape-кодов и префиксов для искусственного расширения пространства кодов операций. Например, для последних инструкций AVX вы смотрите префикс VEX, за которым следует старый / переработанный управляющий код (например, 0xF0), за которым следует старый / переработанный адрес / префикс размера операнда (например, 0x66), за которым следуют еще 4 байта., Это не красиво.
В то же время есть старые инструкции, которые сейчас используются редко (AAD, AAM и т. Д.), А также инструкции с несколькими / избыточными кодами операций (INC/DEC), которые потребляли ценные "1-байтовые" коды операций. Они не могут / не могут быть удалены полностью из-за обратной совместимости.
Тем не мение; когда разрабатывался 64-битный, просто не было 64-битного кода, с которым можно было бы работать - обратная совместимость не имела значения. Однобайтовые коды операций, используемые "не очень важными" инструкциями, могут быть переработаны; делает эти инструкции недействительными в 64-битном коде (но освобождает некоторые ценные 1-байтовые коды операций).
Большинство из этих 1-байтовых кодов операций (если я правильно помню, всю 1-байтовую группу INC / DEC) были немедленно переработаны для префикса REX, который был необходим для поддержки 64-битных операндов. Некоторые не были и стали "бесплатными для будущих расширений" (с ограничением, что расширение может работать только в 64-битном коде, потому что эти инструкции все еще действительны в 16-битном и 32-битном коде).