[英]Corrupt behavior of a primitive C program on a MacBook Pro, Windows XP, VS 2008 Express Edition
我知道這很難相信,但我對此非常認真。
當我在MacBook Pro(Core 2 Duo P8600)上使用Visual Studio 2008 Express Edition在發布模式下使用Windows XP Professional 32位SP3本機運行編譯下面的代碼時,運行可執行文件,一觸摸就會偶爾打印到printf觸摸板(沒有笑話) - 絕對不應該發生。
任何人都可以在他的MacBook Pro(或任何其他筆記本電腦)上重現同樣的問題嗎? 任何人都可以在匯編列表中看到可能存在的問題嗎?
我的猜測是觸摸板驅動程序以某種方式設法操縱負責浮點比較的寄存器。 使用整數,問題不會發生。
任何想法都將在這里受到歡迎。
#include <stdio.h>
int main()
{
while (true)
{
float x = 1.0f;
for (int i = 0; i < 50; i++)
{
if (0.0f < x)
x = 0.0f;
}
if (x == 1.0f)
printf("bad: %.2f\n", x);
}
return 0;
}
以下是Visual Studio 2008 Express Edition生成的上述代碼的匯編列表:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01
TITLE c:\Dokumente und Einstellungen\azad\Desktop\WeirdProblem\main.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRT
INCLUDELIB OLDNAMES
PUBLIC ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@ ; `string'
PUBLIC __real@00000000
PUBLIC __real@0000000000000000
PUBLIC __real@3f800000
PUBLIC _main
EXTRN __imp__printf:PROC
EXTRN __fltused:DWORD
; COMDAT ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
; File c:\dokumente und einstellungen\azad\desktop\weirdproblem\main.cpp
CONST SEGMENT
??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@ DB 'bad: %.2f', 0aH, 00H ; `string'
CONST ENDS
; COMDAT __real@00000000
CONST SEGMENT
__real@00000000 DD 000000000r ; 0
CONST ENDS
; COMDAT __real@0000000000000000
CONST SEGMENT
__real@0000000000000000 DQ 00000000000000000r ; 0
CONST ENDS
; COMDAT __real@3f800000
CONST SEGMENT
__real@3f800000 DD 03f800000r ; 1
; Function compile flags: /Ogtpy
CONST ENDS
; COMDAT _main
_TEXT SEGMENT
_x$3834 = -4 ; size = 4
_main PROC ; COMDAT
; 4 : {
push ebp
mov ebp, esp
and esp, -64 ; ffffffc0H
fld1
sub esp, 60 ; 0000003cH
fldz
push esi
fldz
mov esi, DWORD PTR __imp__printf
jmp SHORT $LN7@main
$LN43@main:
; 10 : {
; 11 : if (0.0f < x)
; 12 : x = 0.0f;
; 13 : }
; 14 :
; 15 : if (x == 1.0f)
fstp ST(0)
fxch ST(2)
$LN7@main:
fxch ST(2)
mov ecx, 10 ; 0000000aH
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
$LN5@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN4@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN4@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN14@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN14@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN15@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN15@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN16@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN16@main:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT $LN17@main
fstp ST(0)
fxch ST(2)
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
fxch ST(1)
fxch ST(3)
fxch ST(1)
$LN17@main:
; 5 : while (true)
; 6 : {
; 7 : float x = 1.0f;
; 8 :
; 9 : for (int i = 0; i < 50; i++)
sub ecx, 1
jne $LN5@main
; 10 : {
; 11 : if (0.0f < x)
; 12 : x = 0.0f;
; 13 : }
; 14 :
; 15 : if (x == 1.0f)
fld ST(1)
fucomp ST(1)
fnstsw ax
test ah, 68 ; 00000044H
jp $LN43@main
fstp ST(2)
; 16 : printf("bad: %.2f\n", x);
sub esp, 8
fstp ST(2)
fstp ST(1)
fstp QWORD PTR [esp]
push OFFSET ??_C@_0L@LNNNMCPH@bad?3?5?$CF?42f?6?$AA@
call esi
; 17 : }
fld1
fldz
add esp, 12 ; 0000000cH
fldz
jmp $LN7@main
_main ENDP
_TEXT ENDS
END
我不知道觸摸板驅動程序將如何產生這種行為。
我的感覺是,這是某種硬件問題。 您有沒有對MacBook超頻? 一旦超頻,CPU便可以開始執行各種奇怪的操作( Eric Raymond有一些戰爭故事可以講述這一點 )。 如果你沒有超頻,也許你的CPU太熱了? 檢查冷卻通風口可能是個好主意。 或者它可能只是一個片狀CPU。
如果是 CPU,為什么僅在觸摸板時才會發生? 純粹的推測,但也許觸摸板的功耗會降低CPU電壓,足以導致它做傻事......
可能與FPU和優化有關。 如果將x
定義為volatile float
或使用/O0
編譯,會發生這種情況嗎? 如果是這樣,也許有缺陷的驅動程序會改變FPU的狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.