В сборке x86 как можно установить нулевой флаг (ZF) без выполнения операции сравнения?


У меня есть небольшой фрагмент (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 8

4 ответа:

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.

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

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

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

Что-то вроде этого.

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