К сожалению, на самом деле на бумаге не написано ни одного "стандарта x86", который бы определял все минимальные требования, которым должен соответствовать процессор, чтобы быть x86.
Документация Intel очень близка к тому, чтобы быть "стандартом x86", но в некоторых случаях дает более надежные гарантии, чем на современных процессорах AMD. например Intel гарантирует атомарность загрузки 1/2/4/8 байт или сохранения из / в кешируемой памяти с любым выравниванием, которое не пересекает границу строки кеша. Но AMD гарантирует это только для кэшируемых загрузок / хранилищ, которые не пересекают 8-байтовую границу.
Почему целочисленное присваивание для естественно выровненной переменной atomic в x86? цитирует руководство Intel, показывающее, что все гарантии даны как «Процессор Intel486 (и более новые процессоры с тех пор)» гарантирует то-то и то-то. Не существует базовых данных, применимых к всем x86 процессорам (или, что более важно, ко всем процессорам x86-64). Я думаю, что фактическая общая базовая линия на практике для x86 (включая pre-x86-64) составляет 1 байт из-за 8088.
Таким образом, программное обеспечение, которое хочет работать на современных процессорах x86-64, не может предполагать атомарность для 8-байтовых загрузок / хранилищ, если они фактически не выровнены. Я думаю, что мы все можем согласиться с тем, что гарантии атомарности являются неотъемлемой частью современного многоядерного процессора x86. Атомарность некэшированного доступа MMIO имеет значение даже на одном ядре; современные Intel и AMD согласны с этим, но опять же Intel только документирует это в терминах «Pentium и более поздние процессоры». Неявно «позже Intel процессоров».
Тем не менее, документация Intel действительно определяет мнемонику для каждого кода операции и регистрирует имена. Документация AMD согласуется с документацией Intel по всем этим вопросам.
См. Том 2 Руководства по разработке программного обеспечения Intel x86 . HTML-выдержки только из записей руководства для каждой инструкции (без разделов, объясняющих формат записи и инструкции) можно найти в https://www.felixcloutier.com/x86/index.html и https://github.com/HJLebbink/asm-dude/wiki,, а в других местах более старые версии отформатированы по-разному.
Как объясняет @fuz, большинство ассемблеров предпочитают следовать этому стандарту, но это не обязательно. Важной частью является двоичная совместимость, а не совместимость с исходным кодом asm.
Intel должна присваивать имена инструкциям, чтобы они могли говорить о них на английском языке в остальных своих руководствах, а не потому, что им нужно, чтобы все в мире использовали такой же синтаксис asm.
Я не уверен, что руководства Intel даже полностью определяют полный синтаксис asm (например, как указать префиксы переопределения сегментов в режиме адресации).
В некоторых случаях они выходят далеко за рамки описания того, какой машинный код делает, например. в строковых инструкциях lods / stos / movs / cmps / scas (и, вероятно, входы / выходы) вы найдете параграфы, подобные этому, в руководстве Intel по vol.2:
На уровне кода ассемблера допускаются две формы этой инструкции: форма «явные операнды» и форма «без операндов». Форма явных операндов (указывается с помощью мнемоники MOVS) позволяет явно указывать исходный и целевой операнды. Здесь операнды источника и назначения должны быть символами, которые указывают размер и местоположение значения источника и назначения, соответственно. Эта форма явных операндов предоставляется для разрешения документации; Однако обратите внимание, что документация, предоставленная этой формой, может вводить в заблуждение. То есть символы операнда источника и назначения должны указывать правильный тип (размер) операндов (байты, слова или двойные слова), но они не обязательно должны указывать правильное расположение . Расположение операндов источника и назначения всегда указывается регистрами DS: (E) SI и ES: (E) DI, которые должны быть правильно загружены перед выполнением команды перемещения строки.
(выделение воспроизведено из (фрагмент HTML) оригинальный PDF)
ТакМои ассемблеры Intel-синтаксиса, такие как NASM, игнорируют это и разрешают использовать только movs
с размером как часть мнемоники, например movsb
. NASM также имеет синтаксис для указания префикса переопределения сегмента, такого как fs lodsd
, который не требует операндов, так что это полностью исключает возможность использования операндов, которые указывают на неправильный операнд памяти, но все еще собираются.
(Строковые инструкции используют только неявные операнды памяти, а не режим адресации ModR / M.)
NASM: синтаксический анализатор: команда ожидает повторений
Инструкция по преобразованию в коде ассемблера lods и stos, чтобы NASM мог скомпилировать
Так что да, существует несколько разновидностей Intel-синтаксиса сборки, не говоря уже об очень разных синтаксисах, таких как AT & T .
AT & T намеренно использует различные мнемоники для некоторых инструкций, даже разделяя некоторые коды операций, которые разделяют мнемонику в синтаксисе Intel, на отдельные мнемоники, такие как movzb
для movzx
-with-a-byte-source и movzw
для версия источника слова. (Обычно используется также с суффиксом размера, например movzbl
, но l
может быть выведен из 32-битного регистра назначения, если хотите.)
И синтаксис AT & T непреднамеренно заменяет fsubr
на fsub
при использовании с двумя операндами регистра, что является ошибкой проектирования синтаксиса, в которой мы застряли . (К счастью, x87 в целом устарел.)