在linux下的x86/64程序集中调用具有6个以上参数的函数

在linux下的x86/64程序集中调用具有6个以上参数的函数,linux,assembly,nasm,x86-64,glibc,Linux,Assembly,Nasm,X86 64,Glibc,前6个参数分别进入寄存器rdi、rsi、rdx、rcx、r8和r9。我的理解是,如果有第七个或更多的论点,它们应该被推到堆栈上。以下代码起作用: mov rdi, format_string mov rsi, 1 mov rdx, 2 mov rcx, 3 mov r8, 4 mov r9, 5 call printf 但当我添加第七个论点时: mov rdi, format_string mov rsi, 1 mov rdx, 2 mov rcx, 3 mov r8, 4 mov r9, 5

前6个参数分别进入寄存器rdi、rsi、rdx、rcx、r8和r9。我的理解是,如果有第七个或更多的论点,它们应该被推到堆栈上。以下代码起作用:

mov rdi, format_string
mov rsi, 1
mov rdx, 2
mov rcx, 3
mov r8, 4
mov r9, 5
call printf
但当我添加第七个论点时:

mov rdi, format_string
mov rsi, 1
mov rdx, 2
mov rcx, 3
mov r8, 4
mov r9, 5
push 6
call printf
add rsp, 8

该代码生成一个分段错误。我做错了什么?

自从我使用assembly以来,这已经是很久以前的事了,但是你想在6中加一个值吗?最有可能的问题是你没有为调用
printf
将RAX调零。RAX需要设置可变函数(如
printf
,该函数采用未指定的参数)。根据64位Linux调用约定,RAX需要包含用于传递参数的向量寄存器的数量。您的案例中的数字为零,因此需要将RAX设置为零(您可以使用
xor eax、eax
。另一个要求是堆栈为16(或32字节)在函数调用完成时对齐。这包括C库函数。除非开始传递浮点,否则可能看不到对齐问题。从技术上讲,向量寄存器的数量以AL为单位(RAX的较低8个bts)。如果您想阅读最新的Linux System V ABI,您可以在此处找到一份副本:。64位的副本位于第一个列表项中的链接处。
format\u string
的内容是什么?既然您已经解决了问题,请随时提交您自己问题的答案,解释问题是什么以及您是如何解决的。您还可以ant将包含一个指向Michael推荐给您的ABI的链接。我们鼓励您回答自己的问题(您可以获得一个徽章),尽管您确实需要等待一段时间,系统才会允许您接受(勾选)您自己的答案。