9B 9B D9 30
Capstone корректен, и objdump fstenv
также в основном корректен.
fstenv
не является реальной машинной инструкцией , этопсевдоинструкция для fwait
+ fnstenv
.Обратите внимание, что машинный код для fnstenv
, указанный в ручном вводе , равен D9 /6
, тогда как fstenv
добавляет 9B
перед этим.
9B
равен не префикс инструкции, это отдельная 1-байтовая инструкция, которая называется wait
aka fwait
.На оригинальном 8086 + 8087 это было необходимо, потому что 8087 был действительно отдельным сопроцессором. Как интерфейс 8086 взаимодействовал с сопроцессором 8087 FPU? .Смотрите комментарии под верхним ответом там;до 286 они не были достаточно тесно связаны между собой, чтобы основной ЦП знал, были ли ожидающие исключения FPU.
Я не уверен в деталях, но fnstsw
на 8086/186 может прочитатьстарая версия слова состояния, для которой не установлены последние флаги из замаскированного исключения.Или, может быть, это имеет значение только для немаскированных исключений, для получения исключения FP из умножения или чего-то еще до инструкции fnst*
.Согласно комментариям Стивена Китта, 286 и новее «проверяют свою строку TEST перед выполнением инструкции NPX», автоматически FWAITing.
И, конечно, процессоры со встроенными FPU не имеют проблем с точными исключениями FP и синхронным поведением, поэтомуfwait
- это пустая трата места.
Capstone's wait
/ wait
/ fnstenv dword ptr [eax]
, таким образом, более явный, потому что с точки зрения процессора, это действительно 3 инструкции,(Как показывает ответ Андреаса, запись современных счетчиков производительности x86).
Objdump рассматривает две предшествующие fwait
инструкции как часть единого fstenv
.Было бы точнее расшифровать его как fwait
;fstenv dword ptr [eax]
, поскольку руководство Intel только документирует fstenv
как включающий в себя один код операции fwait
.Но дополнительный fwait
не имеет архитектурного эффекта.
Часть 2
Как показывает ответ Андреаса, f2 66 0f 12 00
декодируется как movddup
(64-битное вещание) на реальномаппаратное обеспечение с бессмысленным префиксом 66
(размер данных операнда). objdump корректно, по крайней мере для этого процессора .
Документированная кодировка для movddup
равна F2 0F 12
, где F2 - обязательный префикс, а 0F -escape-байт.
Мы могли бы ожидать, что он будет декодироваться как 66 0F 12 /r MOVLPD
с бессмысленным префиксом F2 REP, но это не так; замковый камень неправильный .Существуют правила для обязательных байтов префикса: порядок кодирования байтов префикса инструкции x86 , включая «префикс 66 игнорируется, если используется либо F2, либо F3».
Я не уверен на 100%эта последовательность гарантированно для декодирования как movddup
на всех аппаратных средствах, если это просто так, как это происходит в семействе Intel Sandybridge.Как прокомментировал @fuz, существует обязательный порядок обязательных префиксов, и неправильное его использование дает неопределенное поведение (т. Е. Определенный ЦП может декодировать его во что угодно, особенно в некоторый будущий ЦП, где другая последовательность префиксов является обязательной для некоторых других инструкций.)1083 *