В сборке 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 ответа:
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.
Или, для начала, сохраните [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