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然后移动到我想的下一个元素,但它没有。我甚至没有得到记忆价值,我得到了消极的。
事实上,对于所有进入堆栈的数组或仅第一个元素的地址非常困惑。通过这个,如何正确地添加他的初始值并转移到其他人。
我在这里缺少什么?
答案 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
。