9

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?

Jay Kominek
  • 8,674
  • 1
  • 34
  • 51
Robert
  • 37,670
  • 37
  • 171
  • 213

4 Answers4

12

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.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • 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. – mpontillo Dec 06 '11 at 19:03
  • 3
    The 1 is actually a size by which to scale the offset. So its really array[cl * 1] = cl. – Stephen Canon Dec 06 '11 at 19:48
  • 1
    @Mike: Note that it's just `mov [esp+ecx], cl` in Intel syntax. – GreyCat Sep 22 '14 at 21:03
  • 2
    @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. – David X Jun 29 '15 at 13:27
8

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.

newgre
  • 5,245
  • 4
  • 31
  • 41
  • Thanks for the complete list, it will be useful. Did you get this from a particular reference or did you know it off hand? – Robert Dec 06 '11 at 20:08
  • 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. – newgre Dec 07 '11 at 12:41
2

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

John Knoeller
  • 33,512
  • 4
  • 61
  • 92
1

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
dandan78
  • 13,328
  • 13
  • 64
  • 78
A-Cube
  • 61
  • 1
  • 9