Разница между "или eax,eax" и "тестом eax,eax"
В чем разница между or eax,eax
а также test eax,eax
? Я видел, как разные компиляторы производят оба для одного и того же сравнения, и что касается документации, они делают одно и то же, поэтому мне интересно, почему они не все используют test eax,eax
, Думая об этом and eax,eax
установил бы флаги таким же образом, как и я, но я не видел их ни в freepascal, ни в delphi, ни в msVC++.
Я скомпилировал несколько блоков asm в delphi и проверил исходный код на ассемблере, и все 3 формы имеют одинаковую длину в кодах операций, а также проверил производительность Intel в PDF и говорит, что они имеют одинаковую задержку и пропускную способность.
Редактировать:
Вопрос конкретно о разнице между конкретными случаями test eax,eax
, or eax,eax
а также and eax,eax
, Все 3 дают абсолютно идентичные результаты для регистров, флагов, длины кода операции, задержки, пропускной способности. И все же для проверки, если 0, если не ноль, или если подписано, некоторые компиляторы будут использовать test eax,eax
в то время как некоторые используют or eax,eax
и мне было интересно, почему они не все используют test eax,eax
так как это делает код немного чище.
Edit2:
Для справки, я дома и имею только MSvC++ и Delphi, но тестирую переменную, если ноль, msvC++ делает test eax,eax
в то время как Delphi делает or eax,eax
,
3 ответа
В общем, единственная разница между test
а также and
в том, что test <reg>, <reg>
не изменяет свои операнды. по существу test
применяет and
операция, отбрасывающая не являющуюся флагом часть результата. Если операнды идентичны, результаты будут такими же (как будет or
).
test
может быть превосходным выбором инструкций из-за таких вещей, как микрооперация фьюжн. В следствии, test
обычно предпочтительнее, если только вычисления не будут повторяться. То же самое относится и к cmp
/sub
,
Поищите в документации Intel "fusion", и вы должны найти подробности.
Схема для определения того, что содержимое eax
после test eax, eax
такие же, как и раньше, инструкция проще, чем схема, необходимая для того, чтобы прийти к такому выводу для or eax, eax
, По этой причине, test
лучше.
Некоторые компиляторы могли генерировать or
в то время, когда это не имело никакого значения (перед выполнением вне очереди), но это будет иметь значение с некоторыми процессорами вне порядка в настоящее время (тогда как другие процессоры OOO будут настолько сложными, что они будут распознавать or eax, eax
как действительно эквивалентно test eax, eax
).
Я не мог найти ссылку, оправдывающую, что некоторые современные процессоры действительно могут сделать вывод, что or reg, reg
не модифицирует reg
, но вот ответ, утверждая, что это имеет место для xchg reg, reg
,
Просто для того, чтобы повторить немного и немного добавить к тому, что указал @gsg, инструкция TEST выполняет побитовое логическое сравнение (по существу, выполняет их побитовое разбиение внутри, но не сохраняет результат) двух операндов и устанавливает флаги процессора в соответствии с результатом. этой операции. Инструкция OR выполняет логическое ИЛИ источника с адресатом, сохраняя результат в месте назначения и устанавливая флаги процессора в соответствии с результатом. Они оба влияют на флаги процессора одинаково. Поэтому, когда операнды идентичны, поведение одинаково. Там нет никакой разницы в флагах. Однако, когда операнды различны, их поведение тогда совсем другое. Вы также можете проверить на ноль с and eax,eax
что также влияет на флаги одинаково.