c++ - ASM 中的 float

标签 c++ assembly floating-point double inline-assembly

最近几天我一直在玩 C++、ASM 和内联 ASM。我知道如何访问内存中的基本变量和类似的东西。现在我正尝试在 ASM 中使用 float 。 我已经反汇编了这段代码:

float A = 0.058;

我得到了这个结果:

 fld         dword ptr ds:[00415744h]  
 fstp        dword ptr [ebp-8]

但是我不明白这段代码。我在谷歌上搜索但我没有找到任何对我有用的东西。谁能向我解释 ASM 中的实数,谁能向我解释这段代码?请帮助我。

最佳答案

这是编译器对您的代码所做的:

编译器将“0.058”识别为浮点文字。它分析字符串以计算它表示的值并将该值编码为 double 浮点值。然后它认识到您正在将此 double 值分配给单精度对象(float A,而不是 double A),因此它不需要完整的 double 值。所以编译器将其转换为单精度。产生的编码可能是 0x3d6d9168,这是单精度 .058 的常见 IEEE 754 编码。

在编译器生成的汇编代码中的某处,编译器生成了一个指令(给汇编程序的指令),该指令导致该值 0x3d6d9168 存储在内存中。 (这是一个复杂的过程;汇编程序将值写入它生成的目标文件,作为程序镜像的各种数据的一部分。当程序准备执行或程序运行时,这些数据将被加载到内存中首先尝试访问那部分内存。)

此外,编译器生成了 fld 指令“fld dword ptr ds:[00415744h]”。自从我使用这种形式的汇编以来已经有一段时间了,所以我可能会稍微偏离,但我相信指令说“使用数据段 (DS) 寄存器作为基地址,0x415744 作为段内的偏移量。该组合是指向双字的指针。从那里加载四个字节到浮点堆栈。 (浮点堆栈是处理器内部的一组特殊寄存器。)

fstp 指令“fstp dword ptr [ebp-8]”表示“获取扩展基址指针 (EBP) 寄存器的内容并减去 8。该值是指向双字的指针。将浮点堆栈中的四个字节存储到该双字,然后将项目从浮点堆栈中弹出。”

请注意,0x415744 与浮点值无关。它是存储常量值的内存地址。这两条指令从内存中的只读位置加载常量值并将其存储到 [ebp-8],这是内存中编译器决定将值保存在变量 A 中的位置。EBP 通常是用于引用堆栈中的位置,因此编译器几乎肯定会在此函数的堆栈帧中留出一些内存来保存变量的值。

我怀疑您在关闭优化的情况下编译了这段代码。启用优化后,编译器可能不会费心实际将浮点值存储在分配给 A 的内存中。这是因为您不会立即对该值执行任何操作,只是将其存储在 A 中。但我们已经知道值并将其存储在其他地方,那么为什么还要复制它呢?相反,在代码后面的某个位置,您实际使用 A 的值的地方,编译器将从只读内存中加载它并直接在计算中使用它。 (情况并非总是如此;您可以编写要求编译器进行一些复制的代码,因为您的代码可能会根据传递给它的参数或其他因素采用多个可能路径之一,并且编译器需要进行复制以确保正确的数据用于后面的路径。但是,一般来说,您不应该期望在您编写的 C 代码和编译器生成的汇编指令之间找到精确匹配。)

关于c++ - ASM 中的 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11177460/

相关文章:

c++ - 在任何情况下都可以使用整数或 float ?

c - 如何获得最大的 float ?

删除对象时出现 C++ 断言错误

c++ - 将值插入 vector 时没有任何反应

c++ - 不同的优化级别会导致功能不同的代码吗?

c++ - QComboBox 已激活(int)

assembly - sin 和 cos 是如何在硬件上实现的?

c++ - ASM I/O 引脚 HCS12 微 Controller

assembly - 在 8086 中的变量中存储标志值 - 汇编语言

swift - Double 与 Float 的浮点运算的惊人区别