0

我知道这很难相信,但我对此是 100% 认真的。

当我在我的 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
4

2 回答 2

1

我看不出触摸板驱动程序如何能够产生这种行为。

我的感觉是,这是某种硬件问题。你有没有超频过你的 MacBook?一旦你超频 CPU 就会开始做各种奇怪的事情(Eric Raymond 有一些战争故事要讲)。如果你没有超频,也许你的 CPU 太热了?检查冷却通风口可能是个好主意。或者也许它只是一个片状的 CPU。

如果CPU,为什么只有触摸触摸板才会出现?纯属猜测,但触摸板的功耗可能会降低 CPU 电压,足以让它做一些愚蠢的事情......

于 2011-01-05T14:40:30.130 回答
1

可能与 FPU 和优化有关。如果您定义xvolatile float或编译时会发生这种情况/O0吗?如果是这样,可能有缺陷的驱动程序会改变 FPU 的状态。

于 2011-01-05T17:53:45.857 回答