NASM x86,FIST的意外结果

时间:2015-01-10 02:10:35

标签: assembly x86 nasm

我无法理解拳头操作的结果。在我的代码中,我试图从用户获取1个整数,然后将其传递给程序集,通过const传递多个并返回为近似整数。

问题是我已经读过FIST指令将float转换为整数并将其保存在内存中。当我返回结果并将int作为一种结果时,我得到了我想要的东西。但是,如果我将其更改为float,则无需近似即可获得结果。 因此,对于3和const = 3.86,我希望从拳头中得到12。我将eax的结果与12进行了比较,似乎确实有12个。但是,如果我将函数结果类型更改为float,则得到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;
}

1 个答案:

答案 0 :(得分:0)

FIST不会从浮点堆栈中弹出值 - 它会将其保留在那里。只是碰巧用于返回浮点值的正常x86调用约定使用浮点堆栈 - 返回float的函数只返回堆栈上的单个值。

因此,当您将声明的返回值更改为float时,C代码将从堆栈中获取该值,并且它似乎正常工作。这实际上比将int声明为int时更好,因为在FISTP情况下C编译器假设fp堆栈为空。因为它不是,如果你反复调用你的函数,你最终会得到一个fp堆栈溢出(可能只是被忽略,因为这是默认行为,但仍然)。

对于严格正确的程序,您应该使用{{1}}进行转换和弹出。