В сборке x86, как вы можете установить нулевой флаг (ZF) без выполнения операции сравнения? - PullRequest
8 голосов
/ 06 декабря 2011

У меня есть короткий фрагмент (x86) сборки, который я пытаюсь выяснить, что он делает.

...
 6:     81 ec 00 01 00 00       sub    $0x100, %esp
 c:     31 c9                   xor    %ecx  , %ecx
 e:     88 0c 0c                mov    %cl   , (%esp, %ecx, 1)
11:     fe c1                   inc    %cl
13:     75 f9                   jne    0xe
....

Похоже, что он зацикливается до тех пор, пока "JNE" не оценивается как false, то есть флаг нуля = 0. (возможно, это помещает числа 1, 2, 3 ... в стек ??)

Из моего короткого исследования сборки (я новичок в этом) кажется, что вы устанавливаете флаг нуля, выполняя операцию сравнения (CMP), но я не вижу операции сравнения.

Итак, при каких условиях он выйдет из этого цикла?

Ответы [ 4 ]

12 голосов
/ 06 декабря 2011

inc устанавливает ZF, если значение cl после приращения равно нулю.Ваш цикл делает это:

sub    $0x100, %esp            // unsigned char array[256];
xor    %ecx  , %ecx            // unsigned char cl = 0;
mov    %cl   , (%esp, %ecx, 1) // e: array[cl] = cl;
inc    %cl                     //    cl += 1;
jne    0xe                     //    if (cl != 0) goto e;

Цикл завершается, когда cl увеличивается с 255 и оборачивается до 0, устанавливая ZF.

8 голосов
/ 06 декабря 2011

Арифметические инструкции, такие как add, sub, inc, dec, sar, sal, а также побитовые операции, такие как test, shl, shr, or, and, xor, neg и т. Д., Изменяют ZF.

2 голосов
/ 06 декабря 2011

математические операции, такие как inc и dec, также могут устанавливать флаг нуля.

1 голос
/ 26 февраля 2012

Или, для начала, сохраните [push] флаги в стеке, [pop] получите стек в регистре, используйте арифметику или оператор с нужным битом в регистре, нажмите регистр и вставьте флаг.1002 * как то так.

pushf
pop ax
or ax, 0x100 [this will set trap flag, you can get the value for any flag or flags you want]
push ax
popf
...