gpt4 book ai didi

c - x86_64 : forcing gcc to pass arguments on the stack

转载 作者:太空狗 更新时间:2023-10-29 16:56:39 26 4
gpt4 key购买 nike

我正在为 x86-64 系统开发一个 setjmp/longjmp 自定义实现,它保存了 CPU 的整个上下文(即所有 xmm、fpu 堆栈、等等;不仅是被调用者保存寄存器)。这是直接用汇编写的。

该代码在最少的示例中运行良好(当直接从程序集源调用它时)。由于参数传递给自制程序 setjmp/longjmp 函数的方式,将它与 C 代码一起使用时会出现问题。事实上,x64_64 系统的 SysV ABI 规定参数应该通过寄存器传递(如果它们最多 6 个)。我的函数的签名是:

long long set_jmp(exec_context_t *env);
__attribute__ ((__noreturn__)) void long_jmp(exec_context_t *env, long long val);

当然,这不能按原样工作。事实上,当我输入 set_jmp 时,rdirsi 已经被破坏以保留指向 env验证值。对于rdi,这同样适用于long_jmp

有什么方法可以强制 GCC,例如通过依赖某些属性,强制通过堆栈传递参数?这比用一些定义来包装 set_jmplong_jmp 要优雅得多,后者手动将被破坏的寄存器压入堆栈,以便稍后检索它们。

最佳答案

您可以通过使用内联汇编调用函数来避免覆盖寄存器。

#include <stdio.h>

static void foo(void)
{
int i;
asm volatile ("mov 16(%%rbp), %0" : "=g" (i));
printf("%d\n", i);
}

#define foo(x) ({ int _i = (x); \
asm ("push %0\ncall %P1\nadd $8, %%rsp\n" : : "g"(_i), "i"(foo)); })

int main(int argc, char *argv[])
{
foo(argc-1);
return 0;
}

这里,一个整数被压入栈中,函数 foo 被调用。 foo 使该值在其局部变量 i 中可用。返回后,栈指针调整回原来的值。

关于c - x86_64 : forcing gcc to pass arguments on the stack,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34227045/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com