[049][x86汇编语言]控制转移到其他任务 jmp/call

学习笔记

《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f

处理器用以下四种方法将控制转移到其他任务:

  • 1、当前程序、任务、或者过程执行一个将控制转移到GDT内某个TSS描述符的jmp或者call指令;
举例,内核程序 通过TSS 切换任务
;32位间接远调用指令CALL                                 
call far [es:ecx+0x14]  ;执行任务切换
                        ;ECX指向要切换任务(用户程序)的TCB
                        ;从TCB中取出TSS基地址、TSS选择子
                        ;CPU发现这是TSS选择子,就知道要执行任务切换
                        ;新任务的TSS完整内容在子程序load_relocate_program中已经填写完毕

https://www.jianshu.com/p/a286eceb0a10

  • 2、当前程序、任务、或者过程执行一个将控制转移到GDT或者当前LDT内某个任务门描述符的jmp或者call指令;
举例,用户程序 通过 调用门 显示 字符串
 call far [fs:PrintString]
  • 3、 一个异常或者中断发生时,中断号指向中断描述表内的任务门;
  • 4、在EFLAGS寄存器的NT位置位的情况下,当前任务执行了一个iret指令;

CALL 与 栈的示意图

  • 32位相对近调用,只压入EIP寄存器
|        |
|--------|
|   EIP  |
|--------|
|        |

栈的示意图
  • 32位远调用,要入依次压入CS和EIP(通过调用门实施的控制转移一定是远转移,要压入CS和EIP
|         |
|---------|
| 0  | CS |
|---------|
|   EIP   |
|-------- |
|         |

栈的示意图
  • 假设还带参数,栈的示意图
PUSH 参数1
PUSH 参数2
PUSH 参数3
CALL 调用门


这四条语句执行完后的栈的示意图:

|         |
|---------|
|  参数1  |
|---------|
|  参数2  |
|---------|
|  参数3  |
|---------|
| 0  | CS |
|---------|
|   EIP   |
|-------- |
|         |

P.248 14.5.1 通过调用门转移控制的完整过程

CALL

不同特权级间控制转移,要实施栈切换:

  • 1、分配内存给特权栈(程序员自己编程实现);
  • 2、使用目标代码段的DPL(新的CPL,假设为 n),选择特权级栈,栈段选择子SSn,栈指针ESPn
  • 3、栈的切换由处理器固件自动完成;
PUSH 参数1
PUSH 参数2
PUSH 参数3
CALL 调用门


这四条语句执行完后的栈的示意图:

|---------|
| 0  | SS |
|---------|
|   ESP   |
|-------- |
|  参数1  |
|---------|
|  参数2  |
|---------|
|  参数3  |
|---------|
| 0  | CS |
|---------|
|   EIP   |
|-------- |
|         |

注意:这个示意图本质上是新栈的示意图,
SS 以及ESP压入这个新栈之后,
3个参数才会依次从旧栈被复制到新栈,
紧接着才是CALL指令隐含的CS以及EIP的压入。

相同特权级间的控制转移

PUSH 参数1
PUSH 参数2
PUSH 参数3
CALL 调用门


这四条语句执行完后的栈的示意图:

|-------- |
|  参数1  |
|---------|
|  参数2  |
|---------|
|  参数3  |
|---------|
| 0  | CS |
|---------|
|   EIP   |
|-------- |
|         |

注意:因为这里是相同特权级之间的转移控制,
所以不存在新栈旧栈的问题,
就只有一个栈,
CALL隐含的压入CS以及EIP而已。

call 返回

  • 近返回 ret 参数个数*4 (丢弃相应个数的参数)
举例:子程序load_relocate_program  

load_relocate_program:      ;加载并重定位用户程序
                            ;PUSH 参数1
                            ;PUSH 参数2
                            ;PUSH 参数3
    .... ....
    .... ....

  ret 3*4                   ;丢弃调用本过程前压入的参数 

https://www.jianshu.com/p/b914ac0380dc

  • 远返回 iretd : 32位模式下,iretiretd是相同的
举例:子程序 terminate_current_task

terminate_current_task:          
      
        ...
.b1:    
        ...

        iretd

https://www.jianshu.com/p/919292c53a8a

JMP

  • 如果通过JMP FAR发起调用门控制转移,那么既没有特权级的变化,也不需要切换栈。

P.297 15.5 处理器在实施任务切换时的操作

任务切换过程中NT位、B位以及TSS指针域变化规则

https://www.jianshu.com/p/44c9434b2c95

将控制转移到GDT内某个 TSS描述符 的jmp或者call指令

293页

  • 当执行任务切换时,处理器用得到的选择子访问GDT,一旦处理器发现那是一个TSS描述符,就知道应该执行任务切换的操作;
  • 首先,因为当前正在执行的任务是由任务寄存器TR指示的,所以,处理器要把每个寄存器的“快照”保存到由TR指向的TSS中;
  • 然后,处理器用指令中给出的TSS选择子访问GDT,取得新任务的TSS描述符,并从该TSS中恢复各个寄存器的内容,包括通用寄存器、标志寄存器EFLAGS、段寄存器、指令指针寄存器EIP、栈指针寄存器ESP,以及局部描述符表寄存器LDTR等等;
  • 最终,任务寄存器TR指向新任务的TSS,而处理器旋即开始执行新的任务。

CALL

  • 内核程序 切换到 用户程序(位于内核程序c15_core.asm
call far [es:ecx+0x14]  
  • 用户程序 切换回 内核程序(位于用户程序c15.asm
 call far [fs:TerminateProgram] 
  • CALL指令切换任务过程中:TSS示意图


    [049][x86汇编语言]控制转移到其他任务 jmp/call_第1张图片
    使用CALL指令 从 程序管理器 切换到 用户程序 后的TSS示意图.png

JMP

  • 内核程序 切换到 用户程序(位于内核程序c15_core.asm
 jmp far [es:ecx+0x14] 
  • 用户程序 切换回 内核程序(位于用户程序c15.asm
 call far [fs:TerminateProgram] 
  • JMP指令切换任务过程中:TSS示意图


    [049][x86汇编语言]控制转移到其他任务 jmp/call_第2张图片
    使用 JMP 指令 从 程序管理器 切换到 用户程序 后的TSS 示意图.png

你可能感兴趣的:([049][x86汇编语言]控制转移到其他任务 jmp/call)