1
带有注释C版的组件,功能:大会,负值治疗上总和
/*
struct X
{
int c; // 4 bytes
struct X *next; // 4 bytes
};
int add2 (struct X *x)
{
if (x == NULL) return 0;
else return x->c + add2(x->next);
}
*/
.text
.globl add2
add2:
/********************************** prologue *************************************/
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
/********************************************************************************/
movl 8(%ebp), %ebx
cmpl $0, %ebx
jne out
movl $0, %eax
jmp end
out:
/***************************** calculates in x->next *******************************/
pushl %ecx
pushl %edx
pushl %eax
movl 4(%ebx), %esi
pushl %esi
call add2
addl $4, %esp
popl %eax
popl %edx
popl %ecx
/********************************************************************************/
cmpl $0, (%ebx) /* > negative values */
js neg /* treatment < */
addl (%ebx), %eax /* return x->c + add2(x->next); */
neg:negl (%ebx) /* c = |c| */
subl (%ebx), %eax /* return x->(-)c + add2(x->next); */
end:
/****************************************end *************************************/
popl %esi
popl %ebx
movl %ebp, %esp
popl %ebp
ret
/*********************************************************************************/
主要的C代码:
#include <stdio.h>
#include <stdlib.h>
struct X
{
int c;
struct X * next;
};
typedef struct X Xlist;
Xlist * lst_create (void)
{
return NULL;
}
Xlist * lst_insert (Xlist * l, int c)
{
Xlist * new = (Xlist*) malloc(sizeof(Xlist));
new->c = c;
new->next = l;
return new;
}
int add2 (struct X * x);
int main (void)
{
// int i;
Xlist * l;
l = lst_create();
//for (i=-9;i<10;i++)
l = lst_insert(l, -1);
printf("%d\n", add2(l));
return 0;
}
的意图是要打印链接的元素的总和名单。 使用负值时我收到内存垃圾。我相信错误在这里:
neg:negl (%ebx) /* c = |c| */
subl (%ebx), %eax /* return x->(-)c + add2(x->next); */
但是为什么? 已经在其他添加功能中使用了相同的算法,并没有问题。
谢谢@迈克尔,好点。另一个add函数没有'call',所以没有'pushl%eax''popl%eax'崩溃。在'addl(%ebx),%eax'之后我也忘记了'jmp end'。我在调用之后添加了'%edi'来接收'%eax'的值,并维护它的'pushl'和'popl'。之后,将'movl'的最终值转换为'return'的'%eax'。关于负值的修改(接着是减法,而不是标准加法),这是我知道的负值处理的唯一算法。你知道另一个吗? – Ajna