我实际上在学习汇编,而我的实际问题是使用c调用约定在具有7个参数的汇编中实现函数。该规则表示前6个参数将传递给rdi
,rsi
,rdx
,rcx
,r8
和r9
。其余参数(从右到左)被压入堆栈。
所以,如果我有这样的功能:
extern void* asm_func(void *arg1, void *arg2, void *arg3, void *arg4,
void *arg5, void *arg6, void *arg7);
然后用此名称:
asm_func(1, 2, 3, 4, 5, 6, 7);
如果我猜对了,汇编器将生成如下内容:
mov $1, %rdi
mov $2, %rsi
mov $3, %rdx
mov $4, %rcx
mov $5, %r8
mov $6, %r9
push $7
call asm_func
现在,第7个参数被压入堆栈。这就是我困惑的地方。它去哪里了?
我的第一个猜测只是做pop
。但是,那对我来说感觉不合适。我的第二个猜测是得到rsp
减去0x10
的地址。所以,我的实现是这样的:
asm_func: # asm_func as a linux system call interface
mov %rdi, %rax
mov %rsi, %rdi
mov %rdx, %rsi
mov %rcx, %rdx
mov %r8, %r10
mov %r9, %r8
mov -0x10(%rsp), %r9
syscall
ret
这是正确的实施方式吗?
这些猜测是基于我对push和pop的工作原理的理解。我的理解是,每当我将一个值压入堆栈时,这意味着我将该值放在rsp
下(以偏移量计)。因此,我怀疑写入堆栈的值push
将消失。我对么? push
指令真的将值放在那里了吗?