在与使用 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
指令在不弹出堆栈的情况下存储了一个值。假设前面的函数之一(function1
或 function2
)将一个浮点值推入堆栈 return 并将其传递给其调用者,调用者应将其从堆栈中弹出,这可以是在使用 fstp
指令而不是 fst
.
存储它时完成
我的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
指令在不弹出堆栈的情况下存储了一个值。假设前面的函数之一(function1
或 function2
)将一个浮点值推入堆栈 return 并将其传递给其调用者,调用者应将其从堆栈中弹出,这可以是在使用 fstp
指令而不是 fst
.