我正在为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
时,rdi
和rsi
已被破坏,以保留指向env
和val
的指针。 long_jmp
相对于rdi
也是如此。
有没有办法强迫GCC,例如通过依赖某些属性,强制通过堆栈传递参数?这比将set_jmp
和long_jmp
与一些定义手动推送堆栈上的修饰寄存器更加优雅,以便稍后检索它们。
答案 0 :(得分:2)
您可以通过使用内联汇编调用函数来避免覆盖寄存器。
import {} from ''
export class ... { }
这里,在栈上推送一个整数,并调用函数foo。 foo使其值在本地变量i中可用。返回后,堆栈指针将调整回原始值。