Effective for loop in assembly

Question!

Im currently trying to get used to assembler and I have written a for loop in c++ and then I have looked at it in disassembly. I was wondering if anyone could explain to me what each step does and/or how to improve the loop manually.

for (int i = 0; i < length; i++){
     013A17AE  mov         dword ptr [i],0  
     013A17B5  jmp         encrypt_chars+30h (13A17C0h)  
     013A17B7  mov         eax,dword ptr [i]  
     013A17BA  add         eax,1  
     013A17BD  mov         dword ptr [i],eax  
     013A17C0  mov         eax,dword ptr [i]  
     013A17C3  cmp         eax,dword ptr [length]  
     013A17C6  jge         encrypt_chars+6Bh (13A17FBh)  
temp_char = OChars [i];         // get next char from original string
     013A17C8  mov         eax,dword ptr [i]  
     013A17CB  mov         cl,byte ptr OChars (13AB138h)[eax]  
     013A17D1  mov         byte ptr [temp_char],cl  

Thanks in advance.



Answers

I'll try to interpret this in plain english:

 013A17AE  mov         dword ptr [i],0               ; Move into i, 0
 013A17B5  jmp         encrypt_chars 30h (13A17C0h)  ; Jump to check
 013A17B7  mov         eax,dword ptr [i]             ; Load i into the accumulator (register eax)
 013A17BA  add         eax,1                         ; Increment the accumulator
 013A17BD  mov         dword ptr [i],eax             ; and put that in it, effectively adding
; 1 to i.
check:
 013A17C0  mov         eax,dword ptr [i]             ; Move i into the accumulator
 013A17C3  cmp         eax,dword ptr [length]        ; Compare it to the value in 'length',
; setting flags
 013A17C6  jge         encrypt_chars 6Bh (13A17FBh)  ; Jump if it's greater or equal. This
; address is not in your code snippet

The compiler preferes EAX for arithmetic. Each register (in the past, I don't know if this is still current) has some type of operation that it is faster at doing.



Here's the part that should be more optimized:
(note: your compiler SHOULD do this, so either you have optimizations turned off, or something in the loop body is preventing this optimization)

mov eax,dword ptr [i]    ; Go get "i" from memory, put it in register EAX
add eax,1                ; Add one to register EAX
mov dword ptr [i],eax    ; Put register EAX back in memory "i". (now one bigger)
mov eax,dword ptr [i]    ; Go get "i" from memory, put it in EAX again.

See how often you're moving values back-n-forth from memory to EAX?

You should be able to load "i" into EAX once at the beginning of the loop, run the full loop directly out of EAX, and put the finished value back into "i" after its all done. (unless something else in your code prevents this)

By : abelenky


Anyway, this code comes from DEBUG build. It is possible to optimize it, but MS compiler produces very good code for such simple cases.

There is no point to do it manually, just re-build it in release mode and read the listing to learn how to do it.

By : Michael


This video can help you solving your question :)
By: admin