Search code examples
cassemblyx86attaddressing-mode

Explanation of array accessing in X86 assembly


I have the following C function:

int sum_arr(int b[], int size){
      int counter = size-1;
      int res = 0;
      while(counter >= 0){
          res = res + b[counter];
         counter = counter - 1;
       }
      return res;
}

From which I generated the following assembly code using:

gcc -Og -S file.c

Out came the following assembly code (I have included the parts of interest only):

sum_arr:
.LFB41:
    .cfi_startproc
    subl    $1, %esi
    movl    $0, %eax
    jmp     .L2
.L3:
    movslq  %esi, %rdx
    addl    (%rdi,%rdx,4), %eax
    subl    $1, %esi
.L2:
    testl   %esi, %esi
    jns     .L3
    rep     ret
    .cfi_endproc

I am having some trouble with .L3. The way I understand it is that it starts off by moving the int counter from a 32 bit register %esi into a 64 bit register %rdx. Then I don't understand the following line:

addl (%rdi,%rdx,4), %eax

in particluar the (%rdi,%rdx,4) part, which gets added to the value in the %eax register. And on the last line it decrements the counter with 1. Could someone help me out with that part?


Solution

  • .L3:
        movslq  %esi, %rdx           /* sign extend counter<%esi> to 64bit %rdx */
        addl    (%rdi,%rdx,4), %eax  /* res<%eax> += b<%rdi>[counter<%rdx>]; */
        subl    $1, %esi             /* counter<%esi> -= 1              */
    .L2:
        testl   %esi, %esi           /* do counter<%esi> & counter<%esi> */
        jns     .L3                  /* if result is no 0, jump to L3  */
    

    Basically addl (%rdi,%rdx,4), %eax is where you access the array (%rdi) with the index of counter (%rdx) and add the value of the element to res (%eax), the 4 is just the multiply of counter (%rdx) for the memory access as each address in the int array consume 4 bytes in memory in your system.

    The line basically says res += MEMORY[addrssOf(b) + counter*4]

    BTW, I believe you want to check that size > 0 before line int counter = size-1;, and also as P__J__ mentioned in his answer, your res can overflow as it have the same type of each element in the array you summing.