汇编,无法将数组值从堆栈添加到寄存器

时间:2014-06-07 07:08:16

标签: c arrays assembly x86 stack

C主要代码:

#include <stdio.h>

int add1 (int *a, int n);

int main (void)
{
    int a[] = {1, 2, 3, 4, 5};

    printf("%d\n", add1(a, 5));

    return 0;
}

包含注释C版本的函数的汇编代码:

/*
int add1 (int *a, int n) 
{
  int i;
  int s = 0;
  for (i=0; i<n; i++) s += *a++;
  return s;
}
returns the sum of the array elements
*/

.text

.globl add1
add1:
    pushl   %ebp        
    movl    %esp, %ebp  
    pushl   %ebx        
    pushl   %esi        

    movl    $0, %ebx    

    movl    $0, %esi    
L1:
    cmpl    12(%ebp), %esi  
    jge     out  
    addl    8(%ebp), %ebx
    addl    $4, 8(%ebp)
    incl    %esi
    jmp     L1
out:
    movl    %ebx, %eax
    popl    %esi
    popl    %ebx
    movl    %ebp, %esp
    popl    %ebp
    ret

专注于此

  

addl 8(%ebp),%ebx

     

addl $ 4,8(%ebp)

哪个应该将数组的元素添加到ebx然后移动到我想的下一个元素,但它没有。我甚至没有得到记忆价值,我得到了消极的。

事实上,对于所有进入堆栈的数组或仅第一个元素的地址非常困惑。通过这个,如何正确地添加他的初始值并转移到其他人。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

8(%ebp)保存当前元素的地址,因此您正在做的是s += a++;而不是s += *a++;

你应该可以通过以下方式解决这个问题:

movl    8(%ebp), eax     /* eax = a   */
addl    (%eax), %ebx     /* ebx += *a */
addl    $4, 8(%ebp)      /* a++       */

尽管在循环之前将8(%ebp)移动到空闲寄存器(如%edi)可能更有效,然后在循环内执行addl (%edi),ebx / addl $4,%edi