NASM x86,FIST 的意外结果
Posted
技术标签:
【中文标题】NASM x86,FIST 的意外结果【英文标题】:NASM x86, unexpected result of FIST 【发布时间】:2015-01-10 02:10:35 【问题描述】:我无法理解拳头操作的结果。在我的代码中,我试图从用户那里获取 1 个整数,然后将其传递给程序集,乘以 const 并作为近似整数返回。
问题是我读过 FIST 指令将浮点数转换为整数并将其保存在内存中。当我返回我的结果并将 int 作为结果类型时,我得到了我想要的。但是,如果我将其更改为浮动,我将获得不带近似值的结果。 所以对于 3 和 const = 3.86,我希望从拳头中得到 12。我将 eax 的结果与 12 进行了比较,似乎确实有 12 个。但是,如果我将函数结果类型更改为浮点数,我会得到 11.58 的答案。
我唯一猜测的可能是在返回浮点数的情况下,它是从浮点数堆栈中取出的,因为我没有从那里弹出它,这就是答案。
extern "C" int fun (int a);
extern "C" float fun (int a);
这是我的代码:
组装
section .data
bmp dd 3.86
res dd 0
section .text
global fun
fun:
;---------- intro ----------
push ebp
mov ebp,esp
;-------- procedura --------
fld dword [bmp]
fimul dword [ebp+8]
fist dword [res]
xor eax, eax
mov eax, [res]
;---------- outro ----------
mov esp, ebp
pop ebp
ret
C++
#include <iostream>
#include <cstring>
using namespace std;
extern "C" float fun (int a);
int main()
int a;
cin >> a;
cout << fun(a) <<endl;
return 0;
【问题讨论】:
"FIST converts ST0 to an integer and stores that in memory;"
(src)。然后,您从内存中获取该值并返回它。它是一个整数。
好的,如果我错了,请纠正我。如果我尝试将整数作为浮点数返回,它应该类似于 x.00000 (我的意思是带点和零的整数)。但是,当我在函数声明中交换 float 和 int 时,我得到 11.58 而不是 12.000。
根据您使用的编译器,高级语言可能会在 FP 堆栈上预期浮点结果,这就是您离开它的地方(也是),因为您没有这样做FISTP
(最后弹出)。
您知道整数和浮点值在内存中的存储方式完全不同,对吧?
好的。所以这就是我想知道的。谢谢你。 @JonathonReinhart - 好吧......我实际上已经忘记了这个:)
【参考方案1】:
FIST
不会将值从浮点堆栈中弹出——它会将其保留在那里。碰巧返回浮点值的普通 x86 调用约定使用浮点堆栈——返回浮点的函数仅返回堆栈上的单个值。
因此,当您将声明的返回值更改为 float
时,C 代码会从堆栈中获取该值,并且它似乎可以正常工作。这实际上比将其声明为 int
时效果更好,因为在 int
情况下,C 编译器假设 fp 堆栈为空。既然不是这样,如果你反复调用你的函数,你最终会得到一个 fp 堆栈溢出(这可能会被忽略,因为这是默认行为,但仍然如此)。
对于一个严格正确的程序,你应该使用FISTP
来转换和弹出。
【讨论】:
以上是关于NASM x86,FIST 的意外结果的主要内容,如果未能解决你的问题,请参考以下文章
顶部带有 %include 的程序集 - 打印输出意外结果:只是一个“S”
是啥导致“ConvertResourcesCases”意外失败?