gcc错误:"无法找到注册表溢出" (OS&#dev;内联汇编问题)

时间:2018-06-18 04:37:34

标签: c gcc intel inline-assembly cpu-registers

所以伙计,我正在学习如何在英特尔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

1 个答案:

答案 0 :(得分:2)

i386只有8个通用寄存器。您可以为所有这些角色分配特定角色。结果,GCC无法找到可行的寄存器分配。 (它需要一些寄存器来实现间接加载和存储。)此外,ESP和EBP在函数序言中使用,并且可能在代码运行之前被破坏。名为eax的寄存器变量将包含指针到随后读取的值也是奇怪的。

您必须在单独的汇编程序中编写此代码,而不是C内联汇编。目前还不清楚你是否可以通过ABI呼叫惯例达到你想要的效果。