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 异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值