这条指令的含义是什么(subl $ 20,%esp)?

lxg*_*eek 1 c assembly

C代码是:

int rSum(int *Start, int Count)
{
        if (Count <= 0)
        return 0;
        return *Start + rSum(Start+1, Count-1);
}
Run Code Online (Sandbox Code Playgroud)

相应的汇编代码是:

.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
Run Code Online (Sandbox Code Playgroud)

我无法理解这个指示"subl $ 20,%esp",为什么20美元?

ick*_*fay 8

subl $20, %esp从堆栈指针(esp)中减去20 .这会在堆栈上分配20个字节的空间,可用于本地变量.

  • 对于GAS/AT&T,`$`表示它是立即值20而不是地址20处的值.它不是十六进制.对于调用`rsum`而不是局部变量所需的参数,这20个字节的空间将是8个字节.剩余的12个字节是不必要的,但编译器可能感觉就像这样只是为了维护一个64字节对齐的堆栈(在任何SSE的情况下). (4认同)