我知道這很難相信,但我對此100%認真對待。MacBook Pro,Windows XP,VS 2008 Express Edition上原始C程序的損壞行爲
當我在運行Windows XP Professional 32位SP3的MacBook Pro(Core 2 Duo P8600)上以發行模式編譯下面的代碼時,運行可執行文件,儘快printf命中因爲我觸摸觸摸板(不是玩笑) - 這絕對不會發生。
我上傳了一個包項目文件的Visual Studio,包括彙編清單和自述文件包括附加信息:
www.pedram-azad.de/WeirdProblem.zip
任何人都可以複製他的MacBook Pro還是同樣的問題(其他任何筆記本電腦)?任何人都可以在彙編中看到什麼可能是問題?
我的猜測是,觸摸板驅動程序以某種方式設法操縱負責浮點比較的寄存器。用整數,問題不會發生。
任何想法發生在這裏將是非常受歡迎的。
Pedram
#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速成版:
; 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 [email protected][email protected]@bad?3?5?$CF?42[email protected] ; `string'
PUBLIC [email protected]
PUBLIC [email protected]
PUBLIC [email protected]
PUBLIC _main
EXTRN __imp__printf:PROC
EXTRN __fltused:DWORD
; COMDAT [email protected][email protected]@[email protected]
; File c:\dokumente und einstellungen\azad\desktop\weirdproblem\main.cpp
CONST SEGMENT
[email protected][email protected]@[email protected] DB 'bad: %.2f', 0aH, 00H ; `string'
CONST ENDS
; COMDAT [email protected]
CONST SEGMENT
[email protected] DD 000000000r ; 0
CONST ENDS
; COMDAT [email protected]
CONST SEGMENT
[email protected] DQ 00000000000000000r ; 0
CONST ENDS
; COMDAT [email protected]
CONST SEGMENT
[email protected] 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 [email protected]
[email protected]:
; 10 : {
; 11 : if (0.0f < x)
; 12 : x = 0.0f;
; 13 : }
; 14 :
; 15 : if (x == 1.0f)
fstp ST(0)
fxch ST(2)
[email protected]:
fxch ST(2)
mov ecx, 10 ; 0000000aH
fst DWORD PTR _x$3834[esp+64]
fld DWORD PTR _x$3834[esp+64]
[email protected]:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT [email protected]
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)
[email protected]:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT [email protected]
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)
[email protected]:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT [email protected]
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)
[email protected]:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT [email protected]
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)
[email protected]:
fcom ST(2)
fnstsw ax
test ah, 65 ; 00000041H
jne SHORT [email protected]
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)
[email protected]:
; 5 : while (true)
; 6 : {
; 7 : float x = 1.0f;
; 8 :
; 9 : for (int i = 0; i < 50; i++)
sub ecx, 1
jne [email protected]
; 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 [email protected]
fstp ST(2)
; 16 : printf("bad: %.2f\n", x);
sub esp, 8
fstp ST(2)
fstp ST(1)
fstp QWORD PTR [esp]
push OFFSET [email protected][email protected]@[email protected]
call esi
; 17 : }
fld1
fldz
add esp, 12 ; 0000000cH
fldz
jmp [email protected]
_main ENDP
_TEXT ENDS
END
我不會稱之爲惡意行爲,因爲該程序沒有積極地嘗試做錯事。無論如何,我使用GCC 4.5.2在Linux上進行了測試,並且printf從未被調用過。 – kmm 2011-01-05 14:08:39
這可能是微軟提醒你在正確的硬件上運行錯誤的操作系統的方式。 FWIW:在使用GCC 4.5.2編譯的MacOS X 10.6.5(Core 2 Duo芯片)上運行時,代碼沒有顯示任何不良行爲。 – 2011-01-05 14:41:01
您是否嘗試將開關撥動到「更多魔法」? – derkyjadex 2011-01-05 15:11:32