首页 > 代码库 > [转载]long mode 下的 call gate

[转载]long mode 下的 call gate

6.1.4、  long mode 下的 call gate



6.1.4.1、 64 位的 call gate descriptor 中已经不支持 parameter count 域,offset 域被扩展至 64 位 base 值。

情景提示:
64 位的 call gate descriptor 的中 selector 域必须是一个 64 位代码的 selector,也就是说:这个 selector 指向的 code segment descriptor 中的 L 属性必须是 1,并且 default operand size 为 32 位,即:D 属性为 0。否则将产生 #GP 异常。(L = 1 && D = 0)
若要转到 32 位代码,须使用 32 位的 call gate descriptor。



由于 64 位的 call gate descriptor 中不支持 parameter count 域,所以在 long mode 下,processor 不支持自动复制参数的行为(从 caller 的 stack 复制到 callee 的 stack 中)。

那么,在 long mode 下如何使用 call gate 调用例程时,如果确实需要传递参数,又是如何传递参数呢?

在 stack 不进行切换的情况下,和一般的例程调用别无两样。在要进行 stack 切换的情形下,原来的 stack 的 ss 和 rsp 值被保存至新的 stack 中(也就是 caller 的 ss 和 rsp 会保存至 callee 的 stack 中)。那么,例程 callee 将直将使用原来的 rsp 去获取参数。
这样做的根本原因是,在 x64 的 long mode 下在硬件级下使用的是平坦内存管理模式,忽略了 segmentation 管理,callee 将可以直接使用 rsp 来获取参数。


看看下面的指令的情形:

caller:

    ... ...
push param1
push param2
    call [call_gate]            /* call gate */
... ...



caller 中用 call gate 进行调用例程 callee, 假设这里需要进行 stack 的切换。


callee:


   ret         



callee 中仅使用 ret 进行返回,无需进行清栈处理。


那么:
caller 的 ss 和 rsp 将被保存至 callee 的 stack 中,如下:

------------------
     caller‘s SS       + 24
------------------
    caller‘s RSP      + 16
------------------
    caller‘s CS       + 8
------------------
    caller‘s RIP         <------------   callee‘s  rsp
------------------
... ...
------------------

在例程 callee 中 [rsp+16] 处获取 caller‘s rsp 值,callee 中如下处理:

push rbp
      mov rbp, rsp
      mov rax, [rbp + 24]           /* get caller‘s rsp */
      mov rbx, [rax]                   /* get param1  */
      ... ...

      和一般的调用例程,使用参数无异,不像 x86 下使用 call gate 调用例程,processor 会自动产生复制参数行为。



6.1.4.2、 前面提过,call gate 只能存放在 GDT / LDT 中,不能放在 IDT 中
这造成 64 位的 call gate descriptors 的高 8 字节的 type 属性必须为 0000,以避免 32 位的 descriptor 与 64 位的 descriptors 重叠在一起。为 0 的 type 是属于无效的 descriptors 类型,processor 会检测这个 type 是否为 0,为 0 则是无效的 descriptors。
这样的话,想提取 64 位的 descriptors 的高半部分作为 32 位 descriptors 使用就会产生一个 #GP 异常。

[转载]long mode 下的 call gate