在与使用 x87 浮点数的程序集混合的 C 代码中意外出现 NaN

NaNs arise unexpectedly in C code mixed with assembly that uses x87 floating point

我的C代码如下。它调用一个汇编函数。

clock_t t = clock();
asmfunction(input);
t = clock() - t;
printf("%.5f\n", ((float)t)/CLOCKS_PER_SEC);

我为 asmfunction 使用程序集 x86-32+SSE。

我无法理解为什么第二次clock()调用returns nan.

我的汇编代码是一个程序调用的循环。我注意到如果它迭代超过六次,时钟函数的第二次调用 returns NaN。否则正常。

这是我的核心汇编代码:

do_while:
    push dword [eax+n]
    push eax
    push ecx
    push dword [eax+p]
    call function1
    add esp,16

    push dword [eax+n]
    push eax
    push ecx
    call function2
    add esp,12      

    fst qword[res]

    push dword [eax+n]
    push eax
    push ecx
    call function3  ;function3 returns a double precision floating 
                    ;point value
    add esp,12 
    movsd xmm1,[res] ;xmm1=res

    comisd xmm1,[eax+ex] ; eax+ex is a quadword
    ja do_while

为什么 clock 调用的结果是 NaN?

x87 FPU(浮点单元)堆栈只有八个元素。如果一个例程没有弹出它压入的所有元素,堆栈将随着例程的重复使用而迅速溢出。一旦堆栈溢出,浮点运算就会产生NaN(英特尔文档中的“浮点不定值”)。

题中汇编代码中的fst指令在不弹出堆栈的情况下存储了一个值。假设前面的函数之一(function1function2)将一个浮点值推入堆栈 return 并将其传递给其调用者,调用者应将其从堆栈中弹出,这可以是在使用 fstp 指令而不是 fst.

存储它时完成