tags:

views:

145

answers:

2

Can anyone explain to me the assembly generated by GCC of the following C++ codes? espeically, the meaning of setg and test in the codes. thx!

.cpp codes:

 1   /*for loop*/

 2   int main()

 3   { 
 4      int floop_id;

 5      for(floop_id=100;floop_id>=1;floop_id--)
 6      {}
 7      return 0;
 8   }

assembly codes:

 3      push %ebp               
 3      mov  %esp, %ebp         
 3      sub  $0x10,%esp         
 5      movl $0x64,-0x4(%ebp)   
 5      jmp  8048457<main+0x13> 
 5      subl $0x1,-0x4(%esp)    
 5      cmpl $0x0,-0x4(%esp)    
 5      setg %al                
 5      test %al, %al           
 7      mov  $0x0,%eax          
 8      leave                   
 8      ret 
+3  A: 

cmpl $0x0,-0x4(%esp); setg %al means compare -0x4(%esp) (floop_id in your code) against 0, and set %al to 1 if it's greater, or 0 otherwise.

test %al, %al here isn't doing anything. I don't know why it's in the assembly. (Normally, testing a value with itself is used to get the signum of the value (i.e., zero, positive, or negative), but the result of this isn't being used here. Chances are, it was going to do a conditional branch (to implement the loop), but seeing as your loop is empty, it got removed.)

Chris Jester-Young
Thank you for your reply! I found one interesting thing: when i compile c codes with gcc using the same code above, the assembly codes generated is different: cmpl $0x0,-0x4(%esp) jg 80483a3<main+0xf>there are no setg and test instructions. But the others are the same. do u know the possible reasons? Thx!
martin
@martin: I guess the C frontend chose not to "strip out" the empty loop body, unlike the C++ frontend. :-) Also, try compiling with different optimisation flags (e.g., `-O1`, `-O2`). You'll see dramatically different results.
Chris Jester-Young
@Chris Jester-Young: I have tried with different optimization flags, but the assembly are the same. sorry, what do u mean by strip out the empty loop body? how does it affect the assembly codes? thank u so much!
martin
A: 

Your generated assembly code doesn't have the cycle in it (apparently the compiler decided that it is not needed), but it seems to contain some loose remains of that cycle. There are bits that load 100 into a variable, subtract 1 from it, compare it with 0. But there's no actual iteration in the code.

Trying to find any logic in this is a pointless exercise. The compiler, obviously, decided to remove the entire cycle. But why it left some "debris" behind is not clear. I'd say that what is left behind in the code is harmless, but at the same time has as much meaning as a value of an initialized variable.

BTW, where does the unconditional jmp lead to? It is not clear from your disassembly. Doesn't it just jump to 7 right away?

AndreyT