C++ Visual Studio优化中断SDL图形输出

C++ Visual Studio优化中断SDL图形输出,c++,visual-studio,assembly,sdl-2,C++,Visual Studio,Assembly,Sdl 2,在Visual Studio中编译使用SDL-2并启用优化的芯片8模拟器时,SDL窗口无法显示任何图形。在未经优化的情况下进行编译时,SDL窗口完全工作 我对二进制文件进行了反汇编,以查看是否能够了解优化程序到底在做什么,反汇编时优化代码和未优化代码之间的唯一区别是两行rdata,如下所示: 优化: .rdata:140006914 2f 0x2f '/' .rdata:140006915 55

在Visual Studio中编译使用SDL-2并启用优化的芯片8模拟器时,SDL窗口无法显示任何图形。在未经优化的情况下进行编译时,SDL窗口完全工作

我对二进制文件进行了反汇编,以查看是否能够了解优化程序到底在做什么,反汇编时优化代码和未优化代码之间的唯一区别是两行rdata,如下所示:

优化:

.rdata:140006914 2f                               0x2f '/'
.rdata:140006915 55                               0x55 'U'
未经选择:

.rdata:140006914 ce                               0xce 
.rdata:140006915 56                               0x56 'V'
我在x86汇编方面没有太多经验,因此不理解这种差异会带来什么,以及为什么它会破坏东西

此外,恢复到我认为有效的前一个提交也会以同样的方式中断,使用有效的前一个编译的二进制文件也会以同样的方式中断。这让我想知道这是否可能是来自Windows的问题

这两条rdata行究竟如何对应用程序产生如此显著的影响?我将如何着手解决这一问题


我不确定确切的问题,但是

当编译器看到如下内容时:

int loopDisplay(void) {
    while (running) {
        if (chip8.drawFlag) {
            UpdateDisplay();              // Update Display
            chip8.drawFlag = false;       // Reset Draw Flag
        }
    }
    return 0;
}
int loopDisplay(void) {
    temp = chip8.drawFlag;
    if(running && temp) 
         UpdateDisplay();              // Update Display
        }
    }
    while(running) {}
    chip8.drawFlag = false;
    return 0;
}
它将查找chip8.drawFlag等变量的详细信息,意识到它没有什么特别之处,它是一个纯布尔drawFlag;;然后优化代码,使其更像这样,其中temp可能只是CPU寄存器中的一个值:

int loopDisplay(void) {
    temp = chip8.drawFlag;
    while (running) {
        if (temp) {
            UpdateDisplay();              // Update Display
            temp = false;                 // Reset Draw Flag
        }
    }
    chip8.drawFlag = temp;
    return 0;
}
然后它会意识到它可以对它进行更多的优化,也许会想出这样的办法:

int loopDisplay(void) {
    while (running) {
        if (chip8.drawFlag) {
            UpdateDisplay();              // Update Display
            chip8.drawFlag = false;       // Reset Draw Flag
        }
    }
    return 0;
}
int loopDisplay(void) {
    temp = chip8.drawFlag;
    if(running && temp) 
         UpdateDisplay();              // Update Display
        }
    }
    while(running) {}
    chip8.drawFlag = false;
    return 0;
}
当然,如果running也只是一个普通的旧变量,那么它可以决定函数要么不执行任何操作,立即返回,要么永远循环,永远不执行chip8.drawFlag=false,永远不返回


要解决这类问题,即两个或多个线程在没有任何同步的情况下使用相同的东西,您需要告诉编译器变量是特殊的,例如,在使用它们之前获取一个锁,或者使它们成为原子。您必须检查所有代码并找出所有问题。

没有太多的x86汇编经验。rdata用于只读数据,而不是x86指令。因此,查看初始化数据并搜索这些字节,也许你会得到一个关于它们作为小数、十六进制、字符串的一部分的clueLook,将它们还原为LE vs BE…一如既往,我们需要一个。也许更好的方法是调试未编译的代码,看看是否有错误……快速查看源代码会让我怀疑线程存在重大问题。例如,一个chip8.drawFlag被多个线程使用,不受任何类型的锁/互斥的保护,不是原子性的,甚至不是易失性的。看起来我需要解决我的线程安全问题,添加线程锁或使draw标志原子化可以解决我的问题。谢谢