gpt4 book ai didi

assembly - 对汇编FLD指令m64fp感到困惑

转载 作者:行者123 更新时间:2023-12-04 21:02:54 24 4
gpt4 key购买 nike

我很困惑。我对 FLD m64fp 指令有一些疑问,但我不知道从哪里开始。因为这是作业,所以我不是专门问答案,而是解决问题的方法。任何建议或想法将不胜感激。

内存中的八个连续字节包含十六进制值 01、00、00、00、00、00、00、00。执行 FLD m64fp 指令。它的参数是这八个连续字节中第一个字节的地址。作为 FLD 指令的结果,ST(0) 中的值现在是:

1)  2^(-1075)
2) 2^(-1074)
3) 2^(-1023)
4) 2^(-1022)

此外,如果我有以下汇编代码

   │0x8048384 <main>                lea    0x4(%esp),%ecx                                                                                                                                               │
│0x8048388 <main+4> and $0xfffffff0,%esp │
│0x804838b <main+7> pushl -0x4(%ecx) │
│0x804838e <main+10> push %ebp │
│0x804838f <main+11> mov %esp,%ebp │
│0x8048391 <main+13> push %ecx │
│0x8048392 <main+14> fldpi │
│0x8048394 <main+16> fsqrt │
│0x8048396 <main+18> fld1 │
│0x8048398 <main+20> fsubrp %st,%st(1) │
│0x804839a <main+22> mov $0x0,%eax │
│0x804839f <main+27> pop %ecx │
│0x80483a0 <main+28> pop %ebp │
│0x80483a1 <main+29> lea -0x4(%ecx),%esp │
│0x80483a4 <main+32> ret

如何找出 main 返回之前 ST(0) 中的值?谢谢。

最佳答案

让我们从第一个问题开始。

虽然没有明确说明,但我认为我们可以假设我们在这里处理的是小端字节序(您今天要使用的每台 PC 都会使用它)。因此,如果您在该内存位置执行 FLD m64p,浮点堆栈将以相反的顺序包含这些字节 - 即 00 00 00 00 00 00 00 01。让我们看看 double 格式是什么样的: enter image description here

现在,这实际上是一个特例 - 因为指数为零而尾数不是,我们表示 subnormal数字 - 无法使用归一化尾数表示的数字,即整数部分为 1 (1.xxx) - 它需要前导零(请记住,由于指数有偏差 (1023),因此实际上为零在这里表示 1 - 指数 (0) - 1023,所以 -1022

作为Wikipedia告诉我们,我们可以使用以下公式计算次正规数的值: enter image description here

但是,设置了尾数中的最低有效位(并且只有那个),这使尾数的值为 2^(-52)(因为我们有 52 位用于 double 格式的尾数)。

因此,如果我们使用该公式,我们得到的是:
(-1)^0 x 2^(1-1023) x 2^(-52) = 1 x 2^(-1022) x 2^(-52) = 2^(-1022 - 52) = 2^(-1074),即答案2。

这是可能的最小正次正规数 - 如果未设置最后一位,则这些位将表示带符号的零

要测试它(或者更容易地找出结果,如果你觉得懒惰的话:))你可以使用 OllyDbg for Windows,它允许你即时修改汇编代码。让我们输入问题中给出的指令:

enter image description here

然后让我们将字节设置为所需的值:

enter image description here

确实,当我们执行它时,我们得到了这个:

enter image description here

(几乎)等于 2 ^ (-1074)



现在,关于第二个问题。让我们分析一下您列出的说明。

  1. 我们从 fldpi 开始,它等同于 ST(0) = PI
  2. 我们执行 fsqrt,所以现在我们有 ST(0) = sqrt(PI)
  3. fld1 将一个加载到 ST(0) 中,因此堆栈如下所示:ST(0) = 1, ST(1) = sqrt(PI)
  4. fsubrp 执行反向 减法并弹出寄存器堆栈。因为这是 AT&T assembly ,而且是 buggy one此时源在前,所以我们从ST(1)中减去ST(0),将结果存入ST(1) , 并弹出寄存器堆栈,使 ST(1) 变为 ST(0)。实际上,现在我们有 ST(0) = sqrt(PI) - 1,它接近于 0.772。当 main 返回时,该值保留在 ST(0) 中,因为稍后没有任何内容修改浮点堆栈。

关于assembly - 对汇编FLD指令m64fp感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30421005/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com