C++ Gcc,使用no_caller_saved_registers属性
我试图编译一些C函数,使用C++ Gcc,使用no_caller_saved_registers属性,c++,c,gcc,attributes,C++,C,Gcc,Attributes,我试图编译一些C函数,使用gcc不运行任何寄存器。我正在从事x86_64。 我正在尝试使用无调用方\u已保存\u寄存器,但我得到的是: 警告:“无调用方保存的寄存器”属性指令被忽略[-Wattributes] void foo() 我的临时解决方案是编写内联汇编序言和尾声,以保存和恢复所有寄存器,但我确实更喜欢使该属性起作用 有人有这个问题吗?没有调用方保存的寄存器只被实现了,所以它在任何正式的GCC发行版atm中都不可用。我需要一个不会破坏任何寄存器的函数,因为它是一种页面错误处理程序。 多亏
gcc
不运行任何寄存器。我正在从事x86_64。
我正在尝试使用无调用方\u已保存\u寄存器
,但我得到的是:
警告:“无调用方保存的寄存器”属性指令被忽略[-Wattributes]
void foo()
我的临时解决方案是编写内联汇编序言和尾声,以保存和恢复所有寄存器,但我确实更喜欢使该属性起作用
有人有这个问题吗?没有调用方保存的寄存器只被实现了,所以它在任何正式的GCC发行版atm中都不可用。我需要一个不会破坏任何寄存器的函数,因为它是一种页面错误处理程序。 多亏了前面的答案,我们知道这个属性将在未来的gcc版本中得到支持,但还不是主流 如果没有此属性,我的函数(用作某种页面错误处理程序,不得对任何寄存器值进行碰撞)如下所示:
#define PREFIX_SIZE (14l)
__asm__ volatile ("in: \n\t"
"pushf\n\t"
"push %rbp\n\t"
"mov %rsp,%rbp\n\t"
"push %rdi\n\t"
"push %rsi\n\t"
"push %rdx\n\t"
"push %rcx\n\t"
"push %r8 \n\t"
"push %r9 \n\t"
"push %rax\n\t"
);
void page_fault_handler() {
/*
* some code here
*/
__asm__ volatile ("jmp reg_out\n\t");
}
__asm__ volatile ("reg_out: \n\t"
"leave\n\t" // what the original code was doing
"pop %rax\n\t"
"pop %r9 \n\t"
"pop %r8 \n\t"
"pop %rcx\n\t"
"pop %rdx\n\t"
"pop %rsi\n\t"
"pop %rdi\n\t"
"leave\n\t" // my leave
"popf\n\t"
"ret\n\t");
这显然很烦人,因为我得打电话给这个地址:
(void*)((ulong)page_fault_handler - PREFIX_SIZE)
而不是
(void*)page_fault_handler
当使用-O2优化标志编译时,它也会导致问题,因为它会重新排序标签
如果您注意到,我不会在此处手动保存rbx,因为我使用以下代码编译此代码:
gcc -fcall-saved-rbx
此编译标志使编译器在函数的开头和结尾保存和还原rbx。
那我为什么不为所有的寄存器做呢?
因为它会导致rax的内部编译器错误:您能解释一下您实际要做什么吗?我有理由相信,不能强迫gcc在函数中不使用寄存器——当然不能用于任何复杂的操作,因为x86中的大多数指令至少需要一个操作数作为寄存器。我正在检测汇编代码,以调用这些函数。我同意他们使用任何寄存器,只要他们能够还原它们。我找到了这个编译标志,它具有我想要的效果,但对整个文件:-fcall saved reg。它在某些寄存器(rax、rdx)上无法正常工作。为什么不保存所需的寄存器呢?我仍然不知道您到底想实现什么。@要使这些函数代码独立于平台吗?更新:gcc 7.2支持此属性。必须添加此编译标志:gcc-7main.c-mgeneralregs only