Почему недопустимый опкод может иметь операнды

Название «неопределённая инструкция» не означает, что процессор обязан прекратить чтение сразу после первого байта. Последовательность байтов, приводящая к исключению недопустимой инструкции, может иметь внутреннюю структуру с операндами: декодер сначала распознаёт формат инструкции и извлекает сведения об операндах, а уже затем определяет, что выполнение этой комбинации недопустимо.

Разбор и выполнение — разные шаги

Декодирование и выполнение — отдельные этапы. Механизм декодера может успешно разобрать последовательность байтов, определить длину инструкции и расположение операндов, но на этапе семантики или проверки прав доступа обнаружить, что инструкция недопустима и вызвать исключение. В таких случаях данные о формате и операндах остаются доступными даже при возникновении исключения.

В качестве иллюстрации в архитектуре x86 встречались последовательности байтов, которые сборки и программы использовали с расчётом на то, что процессор бросит исключение. Это ограничивало возможность занять такие комбинации для новых, легитимных инструкций, поскольку изменив поведение декодирования можно было бы сломать существующее ПО. Модель упрощённого декодера помогает объяснить, как одна и та же последовательность может быть распознана как формат с операндами, но при этом считаться недопустимой для выполнения.

Практический вывод для разработчиков

Не следует полагаться на недокументированное поведение процессора как на контракт. При работе с машинным кодом важно ориентироваться на официальную документацию целевой архитектуры и учитывать, что длина инструкции и способ её декодирования могут отличаться от фактической семантики выполнения. Если код полагается на исключениях или на конкретном побочном поведении декодера, это может привести к проблемам при переносе или обновлении процессора.