6
votes

Recent times I am having a look at assembly IA32, I did a simple toy example:

#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 it is not very recommended to use global variables. I compiled the above code without optimizations and using the flag -s, 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 fancy and easy to understand, it is a normal 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 transformed in a do while type of loop. From the above assembly what I am not understanding is why "movl $1, %edx" and then "movl %eax, array-4(,%edx,4)".

The %edx starts with 1 instead of 0 and then when accessing the array it does -4 from the initial position (4 bytes = integer) . Why not simply ?

movl    $0, %edx
...
array (,%edx,4)

instead of starting with 1 if you need to do -4 all the time.

I am using "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-24)", for educational reasons to generate easily understandable assembly.

1

1 Answers

1
votes

I think I finally get the point, I test with:

...

int main(void)
{
        for (i = 0; i < 10; i+=2)
        {
         ...
        }
}

and got:

movl    $2, %edx

and with for (i = 0; i < 10; i +=3) and got :

movl    $3, %edx

and finally with (i = 1; i < 10; i +=3) and got:

movl    $4, %edx

Therefore, the compiler is initializing %edx = i (initial value of i) + incrementStep;