2012-12-07 32 views
1

的C代码是:

int rSum(int *Start, int Count) 
{ 
     if (Count <= 0) 
     return 0; 
     return *Start + rSum(Start+1, Count-1); 
} 

相应的组装代码是:

.file "test98.c" 
.text 
.globl rSum 
.type rSum, @function 
rSum: 
pushl %ebp 
movl %esp, %ebp 
pushl %ebx 
subl $20, %esp 
cmpl $0, 12(%ebp) 
jg .L2 
movl $0, %eax 
jmp .L3 
.L2: 
movl 8(%ebp), %eax 
movl (%eax), %ebx 
movl 12(%ebp), %eax 
leal -1(%eax), %edx 
movl 8(%ebp), %eax 
addl $4, %eax 
movl %edx, 4(%esp) 
movl %eax, (%esp) 
call rSum 
leal (%ebx,%eax), %eax 
.L3: 
addl $20, %esp 
popl %ebx 
popl %ebp 
ret 
.size rSum, .-rSum 
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" 
.section .note.GNU-stack,"",@progbits 

我不明白这个Instructor作业 “subl $ 20%ESP”,以及为什么是$ 20〜

回答

7

subl $20, %esp从堆栈指针中减去20(esp)。这将在堆栈中分配20个字节的空间,用于局部变量。

+0

谢谢,为什么是20美元,而不是30美元,40美元? – lxgeek

+0

@lxgeek:如果你问为什么是32,那是因为编译器决定需要多少空间来存储局部变量。 – icktoofay

+4

对于GAS/AT&T,'$'表示它是立即值20,而不是地址20的值。它不是十六进制。这20个字节的空间将是8个字节,用于调用'rsum'所需的参数,而不是局部变量。其余的12个字节是不必要的,但编译器可能会这样做,只是为了维护一个64字节对齐的栈(在任何SSE的情况下)。 – Brendan