Advertisement

for loops

Started by January 13, 2024 12:05 PM
2 comments, last by Alberth 11 months, 2 weeks ago

I am trying to understand how for loops get converted to assembly. I have this for loop:

void forloop()
{
for (int i = 0; i < 5; i++) {
 printf("Loop#: %d\n", i);
}

}

This is the disassembly:

void forloop()
{
00007FF6AC5247D0  push        rbp  
00007FF6AC5247D2  push        rdi  
00007FF6AC5247D3  sub         rsp,108h  
00007FF6AC5247DA  lea         rbp,[rsp+20h]  
00007FF6AC5247DF  lea         rcx,[__95306CE6_looptest@cpp (07FF6AC554670h)]  
00007FF6AC5247E6  call        __CheckForDebuggerJustMyCode (07FF6AC521D0Ch)  
for (int i = 0; i < 5; i++) {
00007FF6AC5247EB  mov         dword ptr [rbp+4],0  
00007FF6AC5247F2  jmp         forloop+2Ch (07FF6AC5247FCh)  
00007FF6AC5247F4  mov         eax,dword ptr [rbp+4]  
00007FF6AC5247F7  inc         eax  
00007FF6AC5247F9  mov         dword ptr [rbp+4],eax  
00007FF6AC5247FC  cmp         dword ptr [rbp+4],5  
00007FF6AC524800  jge         forloop+43h (07FF6AC524813h)  
 printf("Loop#: %d\n", i);
00007FF6AC524802  mov         edx,dword ptr [rbp+4]  
00007FF6AC524805  lea         rcx,[string "Loop#: %d\n" (07FF6AC5427C8h)]  
00007FF6AC52480C  call        printf (07FF6AC5215EBh)  
}
00007FF6AC524811  jmp         forloop+24h (07FF6AC5247F4h)  

}
00007FF6AC524813  lea         rsp,[rbp+0E8h]  
00007FF6AC52481A  pop         rdi  
00007FF6AC52481B  pop         rbp  
00007FF6AC52481C  ret  

I don't understand why the "inc" statement occurs before the printf. Shouldn't it be after?

Thank you.

Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/

Code execution order (Note: variable "i" is created on the stack. This variable is accessed via "dword ptr [rbp+4]")

1. variable "i" is initialized to zero

00007FF6AC5247EB  mov         dword ptr [rbp+4],0

2. Jump to check the loop exit condition (point 4.)

00007FF6AC5247F2  jmp         forloop+2Ch (07FF6AC5247FCh)

3. variable "i" incrementation

00007FF6AC5247F4  mov         eax,dword ptr [rbp+4]  
00007FF6AC5247F7  inc         eax  
00007FF6AC5247F9  mov         dword ptr [rbp+4],eax

4. Comparison: variable "i" and the constant value 5

00007FF6AC5247FC  cmp         dword ptr [rbp+4],5  

5. Checking the comparison result in CPU flags. If the condition is met (dword ptr [rbp+4] >= 5, checking for signed variables), the loop is exited (point 8.)

00007FF6AC524800  jge         forloop+43h (07FF6AC524813h)

6. If the condition is not met, printf is executed

00007FF6AC524802  mov         edx,dword ptr [rbp+4]  
00007FF6AC524805  lea         rcx,[string "Loop#: %d\n" (07FF6AC5427C8h)]  
00007FF6AC52480C  call        printf (07FF6AC5215EBh)

7. jump to increment variable "i" (point 3.)

00007FF6AC524811  jmp         forloop+24h (07FF6AC5247F4h)

8. Loop exit:

00007FF6AC524813 
Advertisement

mike74 said:
I don't understand why the "inc" statement occurs before the printf. Shouldn't it be after?

The compiler is not obligated to literally do what you say. In fact, it can produce any assembly code that it likes.The only promise that you get is that execution of its code cannot be distinguished with respect to observable effects from the code that you gave the compiler.

So in theory, if the compiler had generated code that did

void forloop()
{
 printf("Loop#: 0\n");
 printf("Loop#: 1\n");
 printf("Loop#: 2\n");
 printf("Loop#: 3\n");
 printf("Loop#: 4\n");
}

it would still be correct.

Generally this is a good thing, if a compiler can find a faster way to perform the same functionality as what you wrote, you'd like to have that, right?

This topic is closed to new replies.

Advertisement