c - gcc 错误:“无法找到要溢出的寄存器”(操作系统开发人员的内联汇编存在问题)
问题描述
所以伙计们,我正在学习如何在英特尔的 80386 中制作调度程序,所以请不要杀了我 :),我有以下混合了 C 和 inline-asm 的代码:
__INT_HANDLERS_SECTION__ static void saveTaskContext(_str_TSS * str_TSS_task)
{
register uint32 * eax asm ("eax");
register uint32 * ebx asm ("ebx");
register uint32 * ecx asm ("ecx");
register uint32 * edx asm ("edx");
register uint32 * esi asm ("esi");
register uint32 * edi asm ("edi");
register uint32 * ebp asm ("ebp");
register uint32 * esp asm ("esp");
asm volatile("mov eax,gs");
str_TSS_task->GS = *eax;
asm volatile("mov eax,fs");
str_TSS_task->FS = *eax;
asm volatile("mov eax,ds");
str_TSS_task->DS = *eax;
asm volatile("mov eax,ss");
str_TSS_task->SS = *eax;
asm volatile("mov eax,es");
str_TSS_task->ES = *eax;
asm volatile("mov eax,cr3");
str_TSS_task->ES = *eax;
str_TSS_task->EDI = * edi;
str_TSS_task->ESI = * esi;
str_TSS_task->ESP = * esp;
asm volatile("pop edx");
str_TSS_task->EDX = *edx;
asm volatile("pop ecx");
str_TSS_task->ECX = *ecx;
asm volatile("pop ebx");
str_TSS_task->EBX = *ebx;
asm volatile("pop eax");
str_TSS_task->EAX = *eax;
asm volatile("pop eax");
str_TSS_task->EFLAGS = *eax;
asm volatile("pop eax");
str_TSS_task->CS = *eax;
asm volatile("pop eax");
str_TSS_task->EIP = *eax;
str_TSS_task->EBP = *ebp;
return;
} // <------------------------- LINE 515 !!!
我期待保存寄存器的值(正如函数名称所说),但是当我尝试编译时,我得到下一个 gcc 错误:
src/handlers.c: In function ‘saveTaskContext’:
src/handlers.c:515:1: error: unable to find a register to spill
}
^
src/handlers.c:515:1: error: this is the insn:
(insn 7 92 93 2 (set (reg:SI 146 [orig:88 D.1975 ] [88])
(mem:SI (reg/f:SI 145 [orig:87 D.1974 ] [87]) [0 *_2+0 S4 A32])) src/handlers.c:470 90 {*movsi_internal}
(expr_list:REG_DEAD (reg/f:SI 145 [orig:87 D.1974 ] [87])
(nil)))
src/handlers.c:515: confused by earlier errors, bailing out
任何想法如何解决它?我真的很感激:)
编辑:我忘了说在弹出之前我已经在堆栈中(按自上而下的顺序)EIP、CS、EFLAGS、EAX、EBX、ECX 和 EDX
解决方案
i386 只有八个通用寄存器。您将特定角色分配给所有这些角色。结果,GCC 无法找到可行的寄存器分配。(它需要一些寄存器来实现间接加载和存储。)此外,函数序言中使用了 ESP 和 EBP,并且可能在您的代码运行之前已被破坏。一个被调用的寄存器变量eax
包含一个指向然后读取的值的指针也很奇怪。
您必须在单独的汇编程序例程中编写此代码,而不是作为 C 内联汇编。也不清楚您是否可以通过 ABI 调用约定实现您想要的。
推荐阅读
- python-3.x - pandas read_excel 不返回数据
- c++ - 合并链表
- docker - spring-cloud 配置在本地运行正常,但在 docker 上显示无法克隆或签出存储库
- python - 用常数改变像素值?
- pandas - 如何使用多索引逐行计算百分比
- maven - maven sql插件转义反斜杠
- unity3d - 如何在不更改默认颜色的情况下应用“可交互”组件?
- android - Recyclerview 项目有时不会在应用启动时显示
- java - Java中的XSSFWorkbook
- java - nimbus-jose 是否支持仅给定私钥的 ECKey 构造?