Visual C ++实际上是否产生了明显不正确的代码?

时间:2017-03-03 18:48:22

标签: c++ visual-studio assembly compilation

所以我正在调试我的DPLL实现并且它工作不正常所以我在调试器中逐行遍历代码,它返回到一个返回语句但事情是它没有返回,它只是继续执行相同的功能。 WTF我想,我真的看到了吗?所以我查看了dissasembly,确定其中一个return语句跳转到了错误的位置。我从来没有见过VS生成错误的代码所以我想知道我是否搞砸了某个地方,但我找不到任何东西。即使在关闭所有优化的情况下进行编译,跳转也是不正确的。

这说明了最新进展。

bool dpll(std::vector<clause> f)
{
    unitPropagate(f);

    if(checkFalseClause(f))
    {
        return false; //je dpll+5Fh (0C01D1Fh) <-- Totally wrong jump adress
    }
    else if(checkAllClausesTrue(f))
    {
        return true; //jmp dpll+206h (0C01EC6h) <-- this is fine
    }
    else
    {
        atom l = chooseLiteral(f); //this is where the jump ends up (0C01D1Fh)

        std::vector<clause> a = makeDuplicate(f);
        replaceInstancesOf(a, l, true);

        std::vector<clause> b = makeDuplicate(f);
        replaceInstancesOf(b, l, false);

        return dpll(a) | dpll(b);
    }

    //this is where the jump is supposed to go (0C01EC6h)
}

所以我的问题是,Visual Studio真的坏了还是我误解了什么?有没有人遇到过这样的事情?

如果版本有所不同,则版本为Visual Studio Enterprise 2015,代码是为x86_32生成的。

如果有人感兴趣的话,这是完整的解决方案:

00C01CC0  push        ebp  
00C01CC1  mov         ebp,esp  
00C01CC3  push        0FFFFFFFFh  
00C01CC5  push        0C08FF0h  
00C01CCA  mov         eax,dword ptr fs:[00000000h]  
00C01CD0  push        eax  
00C01CD1  sub         esp,40h  
00C01CD4  mov         eax,dword ptr [__security_cookie (0C0D008h)]  
00C01CD9  xor         eax,ebp  
00C01CDB  mov         dword ptr [ebp-10h],eax  
00C01CDE  push        ebx  
00C01CDF  push        esi  
00C01CE0  push        eax  
00C01CE1  lea         eax,[ebp-0Ch]  
00C01CE4  mov         dword ptr fs:[00000000h],eax  
bool dpll(std::vector<clause> f)
00C01CEA  lea         ecx,[f]  
00C01CED  mov         dword ptr [ebp-4],0  
00C01CF4  call        unitPropagate (0C01950h)  
{
    unitPropagate(f);
00C01CF9  lea         ecx,[f]  
00C01CFC  call        checkFalseClause (0C01660h)  
00C01D01  test        al,al  
00C01D03  je          dpll+4Ch (0C01D0Ch)  
00C01D05  xor         bh,bh  
00C01D07  jmp         dpll+206h (0C01EC6h)  

    if(checkFalseClause(f))
    {
        return false;
00C01D0C  lea         ecx,[f]  
00C01D0F  call        checkAllClausesTrue (0C014F0h)  
00C01D14  test        al,al  
00C01D16  je          dpll+5Fh (0C01D1Fh)  
    }
    else if(checkAllClausesTrue(f))
00C01D18  mov         bh,1  
00C01D1A  jmp         dpll+206h (0C01EC6h)  
    {
        return true;
    }
    else
00C01D1F  lea         edx,[f]  
00C01D22  lea         ecx,[l]  
00C01D25  call        chooseLiteral (0C013D0h)  
00C01D2A  mov         byte ptr [ebp-4],1  
    {
        atom l = chooseLiteral(f);
00C01D2E  lea         edx,[f]  
00C01D31  xorps       xmm0,xmm0  
00C01D34  mov         dword ptr [ebp-20h],0  
00C01D3B  lea         ecx,[a]  
00C01D3E  movq        mmword ptr [a],xmm0  
00C01D43  call        makeDuplicate (0C01A30h)  
00C01D48  mov         byte ptr [ebp-4],2  

00C01D4C  sub         esp,20h  
00C01D4F  mov         esi,esp  
00C01D51  mov         bl,1  
00C01D53  mov         dword ptr [ebp-4Ch],esi  
00C01D56  lea         ecx,[esi+4]  
00C01D59  mov         al,byte ptr [l]  
00C01D5C  mov         byte ptr [esi],al  
00C01D5E  mov         dword ptr [ecx+14h],0Fh  
00C01D65  mov         dword ptr [ecx+10h],0  
00C01D6C  cmp         dword ptr [ecx+14h],10h  
00C01D70  jb          dpll+0B6h (0C01D76h)  
00C01D72  mov         eax,dword ptr [ecx]  
00C01D74  jmp         dpll+0B8h (0C01D78h)  
00C01D76  mov         eax,ecx  
00C01D78  push        0FFFFFFFFh  

00C01D7A  mov         byte ptr [eax],0  
00C01D7D  lea         eax,[ebp-44h]  
00C01D80  push        0  
00C01D82  push        eax  
00C01D83  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign (0C02A80h)  
00C01D88  mov         al,byte ptr [ebp-2Ch]  
00C01D8B  lea         ecx,[a]  
00C01D8E  mov         byte ptr [esi+1Ch],al  
00C01D91  mov         dl,bl  
00C01D93  mov         al,byte ptr [ebp-2Bh]  
00C01D96  mov         byte ptr [esi+1Dh],al  
00C01D99  call        replaceInstancesOf (0C017D0h)  
00C01D9E  xorps       xmm0,xmm0  
00C01DA1  mov         dword ptr [ebp-14h],0  
        std::vector<clause> a = makeDuplicate(f);
        replaceInstancesOf(a, l, true);
00C01DA8  lea         edx,[f]  
        std::vector<clause> a = makeDuplicate(f);
        replaceInstancesOf(a, l, true);
00C01DAB  movq        mmword ptr [b],xmm0  
00C01DB0  lea         ecx,[b]  
00C01DB3  call        makeDuplicate (0C01A30h)  

00C01DB8  mov         esi,esp  
00C01DBA  mov         byte ptr [ebp-4],3  
00C01DBE  mov         dword ptr [ebp-4Ch],esi  
00C01DC1  lea         ecx,[esi+4]  
00C01DC4  mov         al,byte ptr [l]  
00C01DC7  xor         bl,bl  
00C01DC9  push        0FFFFFFFFh  
00C01DCB  mov         byte ptr [esi],al  
00C01DCD  lea         eax,[ebp-44h]  
00C01DD0  push        0  
00C01DD2  mov         dword ptr [ecx+14h],0Fh  
00C01DD9  mov         dword ptr [ecx+10h],0  
00C01DE0  push        eax  
00C01DE1  mov         byte ptr [ecx],bl  
00C01DE3  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign (0C02A80h)  
00C01DE8  mov         al,byte ptr [ebp-2Ch]  
00C01DEB  lea         ecx,[b]  
00C01DEE  mov         byte ptr [esi+1Ch],al  
00C01DF1  mov         dl,bl  
00C01DF3  mov         al,byte ptr [ebp-2Bh]  
00C01DF6  mov         byte ptr [esi+1Dh],al  
00C01DF9  call        replaceInstancesOf (0C017D0h)  
        std::vector<clause> b = makeDuplicate(f);
        replaceInstancesOf(b, l, false);
00C01DFE  add         esp,14h  
00C01E01  lea         eax,[a]  
00C01E04  mov         ecx,esp  
00C01E06  push        eax  
00C01E07  call        std::vector<std::vector<atom,std::allocator<atom> >,std::allocator<std::vector<atom,std::allocator<atom> > > >::vector<std::vector<atom,std::allocator<atom> >,std::allocator<std::vector<atom,std::allocator<atom> > > > (0C02420h)  
00C01E0C  call        dpll (0C01CC0h)  
00C01E11  mov         bl,al  
00C01E13  mov         ecx,esp  
00C01E15  lea         eax,[b]  
00C01E18  push        eax  
00C01E19  call        std::vector<std::vector<atom,std::allocator<atom> >,std::allocator<std::vector<atom,std::allocator<atom> > > >::vector<std::vector<atom,std::allocator<atom> >,std::allocator<std::vector<atom,std::allocator<atom> > > > (0C02420h)  
00C01E1E  call        dpll (0C01CC0h)  
00C01E23  mov         ecx,dword ptr [b]  
00C01E26  mov         bh,al  
00C01E28  add         esp,0Ch  
00C01E2B  or          bh,bl  
00C01E2D  test        ecx,ecx  
00C01E2F  je          dpll+1B4h (0C01E74h)  
00C01E31  push        dword ptr [ebp-4Ch]  
00C01E34  mov         edx,dword ptr [ebp-18h]  
00C01E37  push        ecx  
00C01E38  call        std::_Destroy_range1<std::allocator<std::vector<atom,std::allocator<atom> > >,std::vector<atom,std::allocator<atom> > *> (0C035E0h)  
00C01E3D  mov         ecx,dword ptr [ebp-14h]  
00C01E40  mov         eax,2AAAAAABh  
00C01E45  mov         esi,dword ptr [b]  
00C01E48  add         esp,8  
00C01E4B  sub         ecx,esi  
00C01E4D  imul        ecx  
00C01E4F  sar         edx,1  
00C01E51  mov         eax,edx  
00C01E53  shr         eax,1Fh  
00C01E56  add         eax,edx  
00C01E58  push        eax  
00C01E59  push        esi  
00C01E5A  call        std::_Wrap_alloc<std::allocator<std::vector<atom,std::allocator<atom> > > >::deallocate (0C02D20h)  
00C01E5F  mov         dword ptr [b],0  
00C01E66  mov         dword ptr [ebp-18h],0  
00C01E6D  mov         dword ptr [ebp-14h],0  
00C01E74  mov         ecx,dword ptr [a]  
00C01E77  test        ecx,ecx  
00C01E79  je          dpll+1FEh (0C01EBEh)  
00C01E7B  push        dword ptr [ebp-4Ch]  
00C01E7E  mov         edx,dword ptr [ebp-24h]  
00C01E81  push        ecx  
00C01E82  call        std::_Destroy_range1<std::allocator<std::vector<atom,std::allocator<atom> > >,std::vector<atom,std::allocator<atom> > *> (0C035E0h)  
00C01E87  mov         ecx,dword ptr [ebp-20h]  
00C01E8A  mov         eax,2AAAAAABh  
00C01E8F  mov         esi,dword ptr [a]  
00C01E92  add         esp,8  
00C01E95  sub         ecx,esi  
00C01E97  imul        ecx  
00C01E99  sar         edx,1  
00C01E9B  mov         eax,edx  
00C01E9D  shr         eax,1Fh  
00C01EA0  add         eax,edx  
00C01EA2  push        eax  
00C01EA3  push        esi  
00C01EA4  call        std::_Wrap_alloc<std::allocator<std::vector<atom,std::allocator<atom> > > >::deallocate (0C02D20h)  
00C01EA9  mov         dword ptr [a],0  
00C01EB0  mov         dword ptr [ebp-24h],0  
00C01EB7  mov         dword ptr [ebp-20h],0  
00C01EBE  lea         ecx,[ebp-44h]  
00C01EC1  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (0C027A0h)  
00C01EC6  mov         ecx,dword ptr [f]  
00C01EC9  test        ecx,ecx  
00C01ECB  je          dpll+23Bh (0C01EFBh)  
00C01ECD  push        dword ptr [ebp-4Ch]  
00C01ED0  mov         edx,dword ptr [ebp+0Ch]  
00C01ED3  push        ecx  
00C01ED4  call        std::_Destroy_range1<std::allocator<std::vector<atom,std::allocator<atom> > >,std::vector<atom,std::allocator<atom> > *> (0C035E0h)  
00C01ED9  mov         ecx,dword ptr [ebp+10h]  
00C01EDC  mov         eax,2AAAAAABh  
00C01EE1  mov         esi,dword ptr [f]  
00C01EE4  add         esp,8  
00C01EE7  sub         ecx,esi  
00C01EE9  imul        ecx  
00C01EEB  sar         edx,1  
00C01EED  mov         ecx,edx  
00C01EEF  shr         ecx,1Fh  
00C01EF2  add         ecx,edx  
00C01EF4  push        ecx  
00C01EF5  push        esi  
00C01EF6  call        std::_Wrap_alloc<std::allocator<std::vector<atom,std::allocator<atom> > > >::deallocate (0C02D20h)  
00C01EFB  mov         al,bh  

00C01EFD  mov         ecx,dword ptr [ebp-0Ch]  
00C01F00  mov         dword ptr fs:[0],ecx  
00C01F07  pop         ecx  
00C01F08  pop         esi  
00C01F09  pop         ebx  
00C01F0A  mov         ecx,dword ptr [ebp-10h]  
00C01F0D  xor         ecx,ebp  
00C01F0F  call        __security_check_cookie (0C080CCh)  
00C01F14  mov         esp,ebp  
00C01F16  pop         ebp  
00C01F17  ret

1 个答案:

答案 0 :(得分:2)

源交错是错误的。这是您想要查看的正确位置:

00C01CFC  call        checkFalseClause (0C01660h)  
00C01D01  test        al,al  
00C01D03  je          dpll+4Ch (0C01D0Ch)  
00C01D05  xor         bh,bh  
00C01D07  jmp         dpll+206h (0C01EC6h)  

如您所见,如果返回值非零,则会转到预期的地址。

您查看的部分实际上是else if(checkAllClausesTrue(f)),跳转是else子句,因为编译器否定了条件。