NASM x86,FIST 的意外结果
NASM x86, unexpected result of FIST
我无法理解拳头操作的结果。在我的代码中,我试图从用户那里获取 1 个整数,然后将其传递给程序集,乘以 const 和 return 作为近似整数。
问题是我读到 FIST 指令将浮点数转换为整数并将其保存在内存中。当我 return 我的结果并且有 int 作为一种结果时,我得到了我想要的。但是,如果我将其更改为 float,我将获得没有近似值的结果。
所以对于 3 和 const = 3.86 我希望从拳头得到 12。我将 eax 中的结果与 12 进行了比较,似乎确实有 12。但是,如果我将函数结果类型更改为浮点数,我会得到 11.58 的答案。
我唯一猜测的可能是在 returning 浮动的情况下,它是从浮动堆栈中取出的,因为我不从那里弹出它,这就是答案。
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
不会从浮点堆栈中弹出值——它会将它留在那里。碰巧 returning 浮点值的正常 x86 调用约定使用浮点堆栈——一个函数 returning float returns 在堆栈上只有一个值.
因此,当您将声明的 return 值更改为 float
时,C 代码从堆栈中获取该值并且似乎工作正常。这实际上比将其声明为 int
时效果更好,因为在 int
情况下,C 编译器假设 fp 堆栈为空。因为它不是,如果你重复调用你的函数,你最终会得到一个 fp 堆栈溢出(它可能会被忽略,因为这是默认行为,但仍然)。
对于一个严格正确的程序,你应该使用FISTP
转换和弹出。
我无法理解拳头操作的结果。在我的代码中,我试图从用户那里获取 1 个整数,然后将其传递给程序集,乘以 const 和 return 作为近似整数。
问题是我读到 FIST 指令将浮点数转换为整数并将其保存在内存中。当我 return 我的结果并且有 int 作为一种结果时,我得到了我想要的。但是,如果我将其更改为 float,我将获得没有近似值的结果。 所以对于 3 和 const = 3.86 我希望从拳头得到 12。我将 eax 中的结果与 12 进行了比较,似乎确实有 12。但是,如果我将函数结果类型更改为浮点数,我会得到 11.58 的答案。
我唯一猜测的可能是在 returning 浮动的情况下,它是从浮动堆栈中取出的,因为我不从那里弹出它,这就是答案。
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
不会从浮点堆栈中弹出值——它会将它留在那里。碰巧 returning 浮点值的正常 x86 调用约定使用浮点堆栈——一个函数 returning float returns 在堆栈上只有一个值.
因此,当您将声明的 return 值更改为 float
时,C 代码从堆栈中获取该值并且似乎工作正常。这实际上比将其声明为 int
时效果更好,因为在 int
情况下,C 编译器假设 fp 堆栈为空。因为它不是,如果你重复调用你的函数,你最终会得到一个 fp 堆栈溢出(它可能会被忽略,因为这是默认行为,但仍然)。
对于一个严格正确的程序,你应该使用FISTP
转换和弹出。