In x86 assembly how can you set the zero flag (ZF) without doing a compare operation?

22,138

Solution 1

inc sets ZF if the value of cl after the increment is zero. Your loop is doing this:

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;

The loop terminates when cl is incremented from 255 and wraps around to 0, setting ZF.

Solution 2

Arithmetic instructions such as add, sub, inc, dec, sar, sal, but also bitwise operations such as test, shl, shr, or, and, xor, neg and so on, modify the ZF.

Solution 3

math operations such as inc and dec can also set the zero flag.

Solution 4

Or, for starters, save [push] the flags on stack, [pop] get the stack in register, use arithmatic or operator with desired bit on the register, push the register and pop in the flag.

something like this.

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
Share:
22,138
Robert
Author by

Robert

iOS Developer

Updated on July 09, 2022

Comments

  • Robert
    Robert almost 2 years

    I have a short piece of (x86) assembly that I am trying to figure out what it does.

    ...
     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
    ....
    

    It looks like its looping though until the "JNE" evaluates to false, i.e. the zero flag = 0. (possibly its putting the numbers 1, 2, 3 ... into the stack??)

    From my short investigation into assembly (im new at this) it seam you set the zero flag by doing a compare operation (CMP), but I dont see a compare operation.

    So, under what conditions will it break out of this loop?

  • Robert
    Robert over 12 years
    Ok, this makes sense. Thank you!
  • mpontillo
    mpontillo over 12 years
    I think I followed all that except for mov %cl, (%esp, %ecx, 1). In English I would say "move the lower 8 bits of CX (CL) into RAM at the address at ESP+ECX", which makes sense, but what is the 1 operand? Is this really array[cl + 1] = cl (stack overflow?) or maybe array[cl] = cl + 1? Probably I'm missing some nuance of x86 assembly, but I'm curious.
  • Stephen Canon
    Stephen Canon over 12 years
    The 1 is actually a size by which to scale the offset. So its really array[cl * 1] = cl.
  • Robert
    Robert over 12 years
    Thanks for the complete list, it will be useful. Did you get this from a particular reference or did you know it off hand?
  • newgre
    newgre over 12 years
    I knew these instructions, but I had to look up the specific effects in the intel manuals / google. I don't know of a list of instructions affecting the ZF.
  • GreyCat
    GreyCat over 9 years
    @Mike: Note that it's just mov [esp+ecx], cl in Intel syntax.
  • David X
    David X almost 9 years
    @GreyCat, pedantically [esp+1*ecx] (with specifically no displacement, rather than disp8=0 or disp32=0), though it is not really ambiguous in this case since esp cannot be used as a index register.