iret错误:一般保护故障fffc



我有一个在内核(2.6.30 x86_64)模式(r0)下运行的示例代码,试图模拟iret。我根据英特尔手册的指导推送变量。但事实证明,在iret指令的位置出现了运行时故障:

一般保护故障:fffc[#]SMP

asm volatile(
    "mov %%ss,%%ax nt"
    "push %%rax nt"/*ss*/
    "push %%rsp nt"/*rsp*/
    "pushfq nt"/*rflags*/
    "mov %%cs,%%ax nt"
    "push %%rax nt"/*cs*/
    "mov $._restart_code,%%rax nt"
    "push %%rax nt"/*rip*/
    "iret nt"/*here is the fault rip!!!!!!*/
    "._restart_code:"
    "nop" :);

我不确定它是否能解决您的问题,但这里有一些注意事项:

"mov %%cs,%%ax nt"
"push %%rax nt"/*cs*/

您正在更新EAX的低阶字节,因此RAX的高阶字节可能与0不同(不应该)。

"mov $._restart_code,%%rax nt"

这里也一样,您应该断言$._restart_code是规范形式的

"mov %%ss,%%ax nt"
"push %%rax nt"/*ss*/
"push %%rsp nt"/*rsp*/

没用,因为你回到了相同的特权级别。

错误是rsp在推送后发生了更改。

asm volatile(
    "mov %%ss,%%ax nt"
    "push %%rax nt"/*ss*/
    "push %%rsp nt"/*rsp ##########error here!!!!!!! */ 
    "pushfq nt"/*rflags*/
    "mov %%cs,%%ax nt"
    "push %%rax nt"/*cs*/
    "mov $._restart_code,%%rax nt"
    "push %%rax nt"/*rip*/
    "iret nt"/*###iretq should be used under 64bit mode*/
    "._restart_code:"
    "nop" :);

因此,在所有推送指令之前保存rsp。正确的代码是:

asm volatile(
        "mov %%rsp,%%rbx nt"
        "mov %%ss,%%ax nt"
        "push %%rax nt"/*ss*/
        "push %%rbx nt"/*rsp*/ 
        "pushfq nt"/*rflags*/
        "mov %%cs,%%ax nt"
        "push %%rax nt"/*cs*/
        "mov $._restart_code,%%rax nt"
        "push %%rax nt"/*rip*/
        "iretq nt"
        "._restart_code:"
        "nop" :);

谢谢!!!

最新更新