Assembly FSTENV?几乎找不到有关此指令的任何信息

Assembly FSTENV?几乎找不到有关此指令的任何信息,assembly,x86,x87,Assembly,X86,X87,我在一个程序中得到了这个指令: FSTENV (28-BYTE) PTR SS:[ESP-1C] 它有什么作用 它使用和更新哪些寄存器 谢谢大家! 它存储浮点环境。其中包括:当前控制字、状态字、标记字、指令指针和操作数指针。这些存储在内存中的一个结构中。在16位模式下,该结构为14字节。在32位模式下,它是28字节。我完全不确定它在64位模式下是否可用(64位模式主要使用SSE)[Edit:显然在32位和64位模式下操作相同。] 我认为它不会改变协处理器的任何当前状态[Edit:oops--确

我在一个程序中得到了这个指令:

FSTENV (28-BYTE) PTR SS:[ESP-1C]
它有什么作用

它使用和更新哪些寄存器


谢谢大家!

它存储浮点环境。其中包括:当前控制字、状态字、标记字、指令指针和操作数指针。这些存储在内存中的一个结构中。在16位模式下,该结构为14字节。在32位模式下,它是28字节。我完全不确定它在64位模式下是否可用(64位模式主要使用SSE)[Edit:显然在32位和64位模式下操作相同。]


我认为它不会改变协处理器的任何当前状态[Edit:oops--确实如此,它屏蔽了FP异常,但大多数人从一开始就不会取消屏蔽,所以…]--但是当您使用
fldenv
,这将使状态恢复到您使用
fstenv
存储时的状态。

Jerry Coffins的回答是正确的。
如果您想知道
(28字节)PTR SS:[ESP-1C]

这是存储FP环境的有效地址,它指定命令的28字节版本,并指向堆栈段中堆栈指针下的28(0x1c)字节。
我只是添加了英特尔的官方描述,这是我用搜索引擎找到的

说明

将当前FPU操作环境保存在内存位置 使用目标操作数指定,然后屏蔽所有 浮点异常。FPU操作环境包括 FPU控制字、状态字、标记字、指令指针、数据 指针和最后一个操作码。IA-32中的图7-13至7-16 英特尔体系结构软件开发人员手册,第1卷,显示 存储环境内存中的布局,具体取决于操作环境 处理器模式(受保护或实型)和当前操作数大小 属性(16位或32位)。在虚拟8086模式下,实际模式 使用布局

FSTENV指令检查并处理任何挂起的未屏蔽 存储FPU环境前的浮点异常;这个 FNSTENV指令不支持。保存的图像反映了图像的状态 在所有浮点指令之后的FPU 指令流中的FSTENV/FNSTENV指令已被删除 执行

异常处理程序经常使用这些指令,因为它们 提供对FPU指令和数据指针的访问。这个 环境通常保存在堆栈中。屏蔽所有异常 保存后,环境将阻止浮点异常从 中断异常处理程序。英特尔体系结构兼容性

操作奔腾®或Intel486时™ MS-DOS*操作系统中的处理器 系统兼容性模式,可能(在异常情况下 (情况)FNSTENV指令在 正在执行以处理挂起的FPU异常。见本节 标题为“无等待FPU指令可在窗口中获取FPU中断” IA-32英特尔体系结构软件开发人员指南的附录D 手册,第1卷,用于描述这些情况。FNSTENV 在奔腾Pro上,指令不能以这种方式中断 处理器

操作


DEST[FPUControlWord)我想用不同的方法回答这个问题

FSTENV不是“真实”指令。
在搜索“FNSTENV”操作码时,您可能会更幸运

仔细研究编码(从以下方面):

看到前面的“9B”了吗?
这真是一个“FWAIT”加在“FNSTENV”前面的词

所以,“FSTENV”和许多其他指令一样,只是一种大多数汇编程序和反汇编程序都能理解的约定

《英特尔手册》确实提到了这一特性,但您不应期望它在100%的情况下都是精确的,有时它可能会忽略以下细节:

FSTENV/FNSTENV商店x87 FPU环境(第2A卷3-393)

汇编程序为FSTENV指令发出两条指令(一条指令FWAIT后接一条FNSTENV 指令),处理器分别执行这些指令中的每一条 无论是这两条指令中的哪一条,save EIP都指向导致异常的指令

有许多这样的“特殊”说明。
例如,你可能会惊讶于, 它们通常是其他指令的别名

奖金-有用的资源 由于以下几个原因,在您的斗争中非常有用:

  • 它可以用作编码器/解码器来验证其他工具
  • 它是人类(和机器)可读的ISA信息的良好来源。您可能会发现它解释了数据文件的结构
  • 有一个叫做列出x86指令的东西 以英特尔SDM的方式,但有时带有附加信息。
    如果将其grep为“FSTENV”,您将看到与之关联的“pseudo”标记。

    请注意,x86.v0.2.csv可能会丢失一些指令,尤其是来自较新扩展的指令(不过这将在v0.3中修复)。

    为了完整起见,这里是
    FSTENV
    /
    FNSTENV
    指令生成的内存布局。在x86-64
    “长64位模式”和x86
    中也是如此“32位兼容模式”
    (除非在x86-64中使用前缀
    66h

    引用Intel文档,以下是布局:

    (顺便说一句,上面的图片也应该被命名为“长模式”。)

    因此,如果我们在长64位模式下运行实际测试:

    并在
    FNSTENV
    指令后立即中断,上下文状态如下:

    它返回的内存布局如下所示:

    我不想隐瞒这一点,这是非常奇怪的(从一个被切掉的RIP寄存器到外观奇怪的操作码),但出于遗留原因,我想它仍然受到支持

    FSTENV   9B D9 /6  
    FNSTENV  D9 /6