这是我的代码:
C代码:
int read_six_numbers(char* input, int* numbers)
{
int numScanned = sscanf(input, "%d %d %d %d %d %d", numbers, numbers + 1, numbers + 2, numbers + 3,
numbers + 4, numbers + 5); // 8 arguments
return numScanned;
}
组装代码:
// Only shows the relevant important code
read_six_numbers:
subq $24, %rsp
movq %rsi, %rdx
leaq 4(%rsi), %rcx
leaq 20(%rsi), %rax
movq %rax, 8(%rsp) // push 8th argument (numbers + 5) on stack
leaq 16(%rsi), %rax
movq %rax, (%rsp) // push 7th argument (numbers + 4) on stack
leaq 12(%rsi), %r9
leaq 8(%rsi), %r8
movl $.LC0, %esi
movl $0, %eax // why set %eax to 0
call __isoc99_sscanf
addq $24, %rsp
ret
我的问题是:
Q1-我们知道使用x86-64,最多可以通过寄存器传递6个参数,如下图所示:
由于read_six_numbers
有8个参数,因此第七和第八个参数将被压入堆栈,这意味着我们只需要从%rsp
中减去8 + 8 = 16,那么为什么要在汇编代码中堆栈指针像subq $24, %rsp
减少了24个字节?剩下的8个字节还有什么用?
Q2-为什么在调用%eax
之前将sscanf()
设置为0?由于%eax
将由sscanf()
设置为该函数的返回值,因此真的不需要将%eax
设置为0吗?