代码之家  ›  专栏  ›  技术社区  ›  Lorenzo

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

  •  -1
  • Lorenzo  · 技术社区  · 8 年前

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

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

    我使用组件x86-32+SSE asmfunction .

    我不明白为什么第二个 clock() 调用返回nan。

    我的汇编代码是一个进行过程调用的循环。我注意到,如果它迭代超过六次,则时钟函数的第二次调用返回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

    1 回复  |  直到 8 年前
        1
  •  2
  •   Eric Postpischil    8 年前

    x87 FPU(浮点单元)堆栈只有八个元素。如果例程没有弹出它所推送的所有元素,堆栈将随着例程的重复使用而迅速溢出。一旦堆栈溢出,浮点操作将产生NAN(Intels文档中的浮点不定值)。

    这个 fst 问题中汇编代码中的指令存储一个值,而不会弹出堆栈。假设先前的函数之一( function1 function2 )将浮点值推送到堆栈上以将其返回给调用者,调用者应将其从堆栈中弹出,这可以通过使用 fstp 指令而不是 fst公司 .