繁体   English   中英

x86_64:强制gcc在堆栈上传递参数

[英]x86_64: forcing gcc to pass arguments on the stack

我正在为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_jmprdirsi已经被破坏以保持指向envval的指针。 关于rdilong_jmp

是否有任何方法可以强制GCC(例如,依靠某些属性)来强制通过堆栈传递参数? long_jmp用一些定义包裹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中可用。 返回后,将堆栈指针调整回其原始值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM