我有一个在内核(2.6.30 x86_64)模式下运行的示例代码(r0),试图在intel手册的指导下模拟iret.I推送变量。但是在iret指令的位置发现运行时错误:
一般保护错误:fffc [#] SMP
asm volatile(
"mov %%ss,%%ax \n\t"
"push %%rax \n\t"/*ss*/
"push %%rsp \n\t"/*rsp*/
"pushfq \n\t"/*rflags*/
"mov %%cs,%%ax \n\t"
"push %%rax \n\t"/*cs*/
"mov $._restart_code,%%rax \n\t"
"push %%rax \n\t"/*rip*/
"iret \n\t"/*here is the fault rip!!!!!!*/
"._restart_code:"
"nop" :);
答案 0 :(得分:0)
我不确定它是否会解决您的问题,但这里有一些注意事项:
"mov %%cs,%%ax \n\t"
"push %%rax \n\t"/*cs*/
您正在更新EAX的低位字节,因此RAX的高位字节可能与0不同(不应该)。
"mov $._restart_code,%%rax \n\t"
同样,你应该断言$._restart_code
是规范形式的。
"mov %%ss,%%ax \n\t"
"push %%rax \n\t"/*ss*/
"push %%rsp \n\t"/*rsp*/
无用,因为你返回相同的权限级别。
答案 1 :(得分:0)
错误是推送后rsp发生了变化。
asm volatile(
"mov %%ss,%%ax \n\t"
"push %%rax \n\t"/*ss*/
"push %%rsp \n\t"/*rsp ##########error here!!!!!!! */
"pushfq \n\t"/*rflags*/
"mov %%cs,%%ax \n\t"
"push %%rax \n\t"/*cs*/
"mov $._restart_code,%%rax \n\t"
"push %%rax \n\t"/*rip*/
"iret \n\t"/*###iretq should be used under 64bit mode*/
"._restart_code:"
"nop" :);
所以,在所有推送指令之前保存rsp。并且正确的代码是:
asm volatile(
"mov %%rsp,%%rbx \n\t"
"mov %%ss,%%ax \n\t"
"push %%rax \n\t"/*ss*/
"push %%rbx \n\t"/*rsp*/
"pushfq \n\t"/*rflags*/
"mov %%cs,%%ax \n\t"
"push %%rax \n\t"/*cs*/
"mov $._restart_code,%%rax \n\t"
"push %%rax \n\t"/*rip*/
"iretq \n\t"
"._restart_code:"
"nop" :);
感谢!!!