Точка теста% eax% eax

Возможный дубликат:
x86 Assembly - 'testl eax против eax?

Я очень новичок в программировании на ассемблере, и сейчас я пытаюсь прочитать язык ассемблера, созданный из двоичного файла. Я столкнулся с

 test   %eax,%eax

или test %rdi, %rdi и т.д. и т.д. Я очень смущен относительно того, что это делает. Разве значения в %eax, %eax не совпадают? Что это такое? Я где-то читал, что он выполняет операцию AND..... но поскольку они являются одним и тем же значением, не будет ли он просто возвращать %eax?

Ниже приведен только один экземпляр, где я нашел это использование:

   400e6e:       85 c0                   test   %eax,%eax
   400e70:       74 05                   je     400e77 <phase_1+0x23>

Я думал, что je перескакивает, если два сравниваемых значения равны...... ну, потому что %eax хорошо, сам, в какой ситуации мы бы не прыгали?

Я новичок в программировании в целом, поэтому я был бы очень признателен, если бы кто-нибудь мог мне это объяснить. Спасибо!

Ответ 1

CMP вычитает операнды и устанавливает флаги. А именно, он устанавливает флаг нуля, если разность равна нулю (операнды равны).

TEST устанавливает флаг нуля, ZF, когда результат операции И равен нулю. Если два операнда равны, их побитовое И равно нулю, когда оба равны нулю. TEST также устанавливает флаг знака SF, когда в результате устанавливается старший значащий бит и флаг четности PF, когда число установленных бит равно.

JE [Jump if Equals] проверяет флаг нуля и прыгает, если флаг установлен. JE является псевдонимом JZ [Jump if Zero], поэтому дизассемблер не может выбрать один на основе кода операции. JE называется таким, потому что флаг нуля установлен, если аргументы CMP равны.

Итак,

TEST %eax, %eax
JE   400e77 <phase_1+0x23>

перескакивает, если %eax равно нулю.

Ответ 2

Некоторые инструкции x86 предназначены для того, чтобы оставить содержимое операндов (регистров) такими, какими они есть, и просто устанавливать/удалять определенные внутренние ЦП, такие как флаг нуля (ZF). Вы можете думать о ZF как истинный/ложный логический флаг, который находится внутри CPU.



в этом конкретном случае команда TEST выполняет побитовое логическое И, отбрасывает фактический результат и устанавливает/отменяет ZF в соответствии с результатом логического и: если результат равен нулю, он устанавливает ZF = 1, в противном случае он устанавливает ZF = 0.



Инструкции условного перехода, такие как JE, предназначены для просмотра ZF для прыжков/неписелей, поэтому использование TEST и JE вместе эквивалентно выполнению условного перехода на основе значения конкретного регистра:



пример:



TEST EAX, EAX

JE some_address



CPU перейдет к "some_address" тогда и только тогда, когда ZF = 1, другими словами, если и только если AND (EAX, EAX) = 0, что, в свою очередь, может произойти тогда и только тогда, когда EAX == 0



эквивалентный код C:


if(eax == 0)
{
    goto some_address
}

Ответ 3

Это проверяет, равен ли EAX нулю. Команда test выполняет побитовое AND между аргументами, а если EAX содержит ноль, результат устанавливает ZF или ZeroFlag.

Ответ 4

test является неразрушающим and, он не возвращает результат операции, но устанавливает флаги соответственно. Чтобы узнать, что он действительно проверяет, вам необходимо проверить следующие инструкции. Часто используется для проверки регистра на 0, возможно, связанного с условным скачком jz.

Ответ 5

Вы правы, что test "и" s два операнда. Но результат отбрасывается, единственное, что остается, и это важная часть, - это флаги. Они установлены, и именно поэтому используется команда test (и существует).

JE перескакивает не при равном (имеет значение, когда инструкция перед сравнением), что она действительно делает, она перескакивает, когда установлен флаг ZF. И поскольку это один из флагов, установленный test, эта последовательность команд (test x, x; je...) имеет значение, что она перепрыгивается, когда x равно 0.

Для таких вопросов (и для более подробной информации) я могу просто рекомендовать книгу о инструкции x86, например. даже когда он действительно большой, документация Intel очень хорошая и точная.