-2

I am new to Assembly and is wondering how I could write a for loop that will iterate 15 times. In the for loop i need to have an if condition that tests wether or not an integer k is greater than 7 as well. How would this be written in code?

Henrik
  • 19
  • 2
  • 6

2 Answers2

3

Usually this would be written as a comment, but it is a little bit too complex. The code in the other answer isn't as efficient as it could be:

    MOV ECX, 15   ; number of iterations
.loop:
    ...
    CMP EAX, 8    ; compare k to 7
    DEC ECX          ; partial-flag merge needed after this, slow on some CPUs
    JA .loop      ; check for loop exit condition
B:                ; code after the loop
    ...
    ;; check CF here to see if k >= 8 or not, i.e. k > 7

EDIT: To have k in memory as 32-bit integer as before, the CMP instruction looks as the following:

    CMP DWORD [k], 8

EDIT2: Save one conditional jump. The OP didn't mention to leave or to stay when k is greater than 7. The above code leaves the loop when it ran 15 times or k isn't greater than 7.

Note that this trick with combining the comparisons is only likely to be good on CPUs like Intel Sandybridge-family or Silvermont which don't have partial-flag stalls for reading CF after a dec. On Core2 / Nehalem, this will stall for ~7 cycles to merge flags, like you'd get in an adc BigInteger loop using dec. See Agner Fog's microarch PDF.

Unless you're sure it's good on all the CPUs your code will run on, use cmp / ja or jae separately from dec / jnz.

EDIT3: The OP asks for incrementing/decrementing an integer (here edx) when eax is greater/smaller than 7:

.loop:
    ...
    CMP EAX, 7
    DEC EDX
    JB .end
    INC EDX
    JE .end
    INC EDX
.end:
    DEC ECX
    JZ .loop

(probably there'll be someone optimizing this further)

caylee
  • 921
  • 6
  • 12
  • 1
    Could we all just agree not to suggest `loop` though? – harold Oct 23 '17 at 20:19
  • Exactly what I was going to say about `loop`. But also, keep `k` in a register. [`loop` is slow, don't use it.](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently). Think of it as one of those old obsolete x86 instructions like `xlatb`. – Peter Cordes Oct 23 '17 at 20:22
  • This won't even assemble because the `cmp` has ambiguous operand-size. (Assuming NASM syntax, where there's no magic that looks for a `dd` / `dw` / `db` after the `k` label.) – Peter Cordes Oct 23 '17 at 20:25
  • This would still not assemble, because `jgt` doesn't exist. – Ped7g Oct 23 '17 at 21:34
  • On some CPUs (with efficient partial-flag merging), it might be an optimization to use one `jcc` to check both conditions (maybe making branch prediction work better, but this depends on the actual patterns of values and whether you want to stay in or leave the loop on `k>7`). The `ja` condition is true when `CF=0 and ZF=0`, but `jae` only checks `CF=0`. So if we arrange the `k` test so it's a `>=` condition, we can use the ZF check part of `ja` to check the counter. `dec` leaves CF unmodified (flag merge). `cmp eax, 8` / `dec ecx` / `ja .loop` (we leave the loop if ECX=0 or if EAX<=7) – Peter Cordes Oct 24 '17 at 00:30
  • 1
    It's more of a fun-fact / tuning hack than a general-purpose suggestion. But it does make an interesting answer to this question that's otherwise way too simple. Anyway, style tip: Don't turn your answer into a changelog, just make edits to create a well-written answer. People can look at the revision history if they're curious; the edit "commit messages" are where you put things like "edit: JGT is JA/JG (signed or unsigned)" – Peter Cordes Oct 24 '17 at 07:12
  • How could i have an integer that i would increment each time k is greater than 7, and decrement each time its k is lower than 7? – Henrik Oct 24 '17 at 07:52
  • Don't be angry about loop. It's compact and is the more readable option. Sure, if you're coding in asm for a performance optimization you wouldn't use it. However, if absolute performance is not the goal, replacing it with a compare/jump sequence is a premature optimization that reduces code readability. – Brian Knoblauch Oct 24 '17 at 12:11
  • @BrianKnoblauch it is not more readable, it is unidiomatic, unexpected, doesn't make explicit what it actually does, and has a perf that is not just "not optimal" but plain *bad*. Compared to compare-and-branch, dec-and-branch, or even add-and-branch, `loop` is the one that's more likely to cause a reader to look it up in the manual. Maybe an oldtimer remembers it from 30 years ago, but does it still use `cx` today? Or `ecx`? Would it use `rcx` in 64bit mode? It does, but there's no reason anyone would know that. – harold Oct 24 '17 at 13:55
-3

I suggest learning how to use compiled code to teach you such things. Write the code you want in C, then compile it with flags to output the assembly. For example, in gcc this is done with the -S flag. You can then read the machine-generated assembly code to see how it was accomplished.

The general strategy for a for-loop could be something like this:

       MOV ECX, 0    ; clear ECX
   A:    
       CMP [k], 7    ; compare k to 7
       JGT B         ; jump to B if k is greater than 7
       CMP ECX, 15   ; check for loop exit condition
       JE C          ; jump to C if we have iterated 15 times
       INC ECX
       JMP A
   B:            ; this happens if K is greater than 7
   ...
   C:            ; this happens if we reach the end of the loop
Tyler Durden
  • 11,156
  • 9
  • 64
  • 126
  • downvoted because of poor quality. 1) The labels don't have any meaning. 2) `cmp [k],7` doesn't explicitly state data size, so it's ambiguous to read for everyone not knowing defaults of target assembler. 3) `mov ecx,0` when `xor ecx,ecx` idiom is recommended in such case for x86 asm (preservation of flags is not needed ahead of `cmp`). 4) `jgt` is invalid in x86 asm. 5) I prefer the exit condition to be not-just-equal, consider `for (int i = 0; i != 15; ++i)` changed later to step by 2 into `for (int i = 0; i != 15; i += 2)` => infinite loop. Condition `i < 15` works for both. – Ped7g Oct 23 '17 at 21:30