【问题标题】:Pushing segment registers on the stack for far calls将段寄存器压入堆栈以进行远调用
【发布时间】:2017-08-31 02:23:42
【问题描述】:

当硬件将段寄存器压入堆栈以保存远指针时,因为调用过程调用了另一个段中的过程,显然,它没有保存段寄存器的不可见部分(缓存的段描述符部分)和只保存选择器部分。

当然,这很好,因为它为您提供了访问描述符所需的所有知识。

但是,选择器只有 16 位,如果您的寻址默认大小是 32 或 64,则进程自身不可见的硬件会将段选择器推入堆栈并增加堆栈指针 4 或 8 个字节,尽管事实上选择器只需要 2 个。

这是为了保持堆栈指针对齐,这一点很重要。

我的问题是:硬件用什么来填充多余的字节?

它是否扩展了选择器?

它是 0 扩展选择器吗?

它是否只是压入两个选择器字节,然后将堆栈指针额外跳转 2 或 6 个,留下最初存在的任何内容?

谢谢。

【问题讨论】:

  • 喂?有人吗??

标签: pointers architecture stack segment


【解决方案1】:

根据 Intel 64 和 IA-32 架构软件开发人员手册第 2 卷 (link) 中的 PUSH 指令条目

如果源操作数是段寄存器(16 位)并且 操作数大小为 64 位,推入一个零扩展值 堆栈;如果操作数大小为 32 位,则零扩展 值被压入堆栈或段选择器被写入 使用 16 位移动堆栈。对于最后一种情况,所有最近的 Core 和 Atom 处理器执行 16 位移动,留下 堆栈位置未修改。

因此,根据操作数的大小,它似乎是 0 扩展或保留未修改的内容。

【讨论】:

  • 关于最后一种情况,16 位移动?我假设使用类似 mov [sp-4], cs yes?
猜你喜欢
  • 2012-04-27
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多