簡體   English   中英

MacBook Pro,Windows XP,VS 2008 Express Edition上原始C程序的損壞行為

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM