将jmp指令用于非常量TSS段

Amu*_*umu 2 x86 assembly operating-system kernel gnu-assembler

JMP指令参考.

根据文档,我们可以执行jmp一个恒定的远段:

jmp 0x18:00
Run Code Online (Sandbox Code Playgroud)

这里,0x18是GDT全局描述符表中的有效段选择器.

jmp 可以与包含有效GDT条目的段寄存器一起使用,该条目是代码/数据段描述符:

mov es, 0x18
jmp es:0x0
Run Code Online (Sandbox Code Playgroud)

这里0x18是TSS(任务状态段)描述符,当跳转到时,CPU执行任务切换,自动将其状态保存到当前TSS中,然后填充新TSS中保存的状态.

但是,TSS是系统段描述符,因此无法加载到任何段寄存器中(如英特尔文档所建议).那么,如何在运行时使用动态分配的TSS跳转到任务?

我能想到的唯一方法是使用该iret指令,但我觉得它像一个hack,因为我需要修改链接字段,然后在EFLAGS中设置NT位以执行反向链接任务切换.

Mar*_*oom 6

push WORD <TSS_selector>
push DWORD 0
jmp FAR [esp]
Run Code Online (Sandbox Code Playgroud)

假设32位代码和可用堆栈.
这将使堆栈在调用线程中不平衡且未对齐,您可能希望使用专用内存位置:

mov WORD [tss_pointer + 4], <TSS_selector>
jmp FAR [tss_pointer]

tss_pointer dd 0, dw 0
Run Code Online (Sandbox Code Playgroud)