The last time I look at the IA32 build, I made a simple example with a toy:
#include <stdio.h> int array[10]; int i = 0; int sum = 0; int main(void) { for (i = 0; i < 10; i++) { array[i] = i; sum += array[i]; } printf("SUM = %d\n",sum); return 0; }
Yes, I know that it is not recommended to use global variables. I compiled the above code without optimization and using the -s flag, I got this assembly:
main: ... movl $0, %eax subl %eax, %esp movl $0, i .L2: cmpl $9, i jle .L5 jmp .L3 .L5: movl i, %edx movl i, %eax movl %eax, array(,%edx,4) movl i, %eax movl array(,%eax,4), %eax addl %eax, sum incl i jmp .L2
Nothing too unusual and easy to understand, this is a regular while loop. Then I compiled the same code with -O2 and got the following assembly:
main: ... xorl %eax, %eax movl $0, i movl $1, %edx .p2align 2,,3 .L6: movl sum, %ecx addl %eax, %ecx movl %eax, array-4(,%edx,4) movl %edx, %eax incl %edx cmpl $9, %eax movl %ecx, sum movl %eax, i jle .L6 subl $8, %esp pushl %ecx pushl $.LC0 call printf xorl %eax, %eax leave ret
In this case, it is converted to a do while loop. From the assembly above, I don't understand why "movl $ 1,% edx" , and then "movl% eax, array-4 (,% edx, 4)" ,
% edx starts with 1 instead of 0, and then when accessing the array, it executes -4 from its original position (4 bytes = integer). Why not easy?
movl $0, %edx ... array (,%edx,4)
instead of starting at 1 if you need to do -4 all the time.
I use "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-24)" for educational reasons to create an easy-to-understand assembly.