MSVC++ 内联程序集未处理的异常 0x80000004:单步

MSVC++ inline assembly unhandled exception 0x80000004: Single step

我正在使用 VC++ 2019 32 位的内联汇编编写代码。我写了一个函数来切换coroutine.This是源代码:

我测试过,效果很好。参数是一个包含寄存器值的 uintptr_t 数组。此函数将交换除 ebx.

之外的寄存器值

问题是“tool.exe 中 0x5514704E (pevm.dll) 处的未处理异常:0x80000004:单步执行。

寄存器值:EAX = 00000246 EBX = 0019F5A0 ECX = E2F13240 EDX = 0019F5A0 ESI = 0019F3A8 EDI = 0019F3C8 EIP

我不明白为什么“pop eax”抛出异常? 也许我的代码破坏了一些“内部数据结构”并且程序碰巧停在这里,就像双重释放一样。对如何调试有什么建议吗?

inline __declspec(naked) void switchCoroutine(uintptr_t* vreg)
{
    //discard ebx
    __asm
    {
        push ebp
        mov ebp, esp
        //save 
        push eax
        //argument
        mov ebx, [ebp + 8]

        //exchange eflags 
        pushfd
        pop eax
        push[ebx]
        popfd
        mov[ebx], eax

        pop eax
        //exchange eax ,ecx,edx,esi,edi
        XCHG eax, [ebx + type int]
        xchg ecx, [ebx + 3 * type int]
        xchg edx, [ebx + 4 * type int]
        xchg esi, [ebx + 5 * type int]
        xchg edi, [ebx + 6 * type int]

        //exchange ebp,esp
        mov esp, ebp
        pop ebp
        xchg ebp, [ebx + 7 * type int]
        xchg esp, [ebx + 8 * type int]

        //go eip
        ret
    }
}

55147031 C2 04 00             ret         4  
--- No source file -------------------------------------------------------------
55147034 CC                   int         3  
55147035 CC                   int         3  
55147036 CC                   int         3  
55147037 CC                   int         3  
55147038 CC                   int         3  
55147039 CC                   int         3  
5514703A CC                   int         3  
5514703B CC                   int         3  
5514703C CC                   int         3  
5514703D CC                   int         3  
5514703E CC                   int         3  
5514703F CC                   int         3  
--- D:\code\c++\PEVM\core\vm\vdata.h -------------------------------------------
   643:     //discard ebx
   644:     __asm
   645:     {
   646:         push ebp
55147040 55                   push        ebp  
   647:         mov ebp, esp
55147041 8B EC                mov         ebp,esp  
   648:         //save 
   649:         push eax
55147043 50                   push        eax  
   650:         //argument
   651:         mov ebx, [ebp + 8]
55147044 8B 5D 08             mov         ebx,dword ptr [vreg]  
   652: 
   653:         //exchange eflags 
   654:         pushfd
55147047 9C                   pushfd  
   655:         pop eax
55147048 58                   pop         eax  
   656:         push[ebx]
55147049 FF 33                push        dword ptr [ebx]  
   657:         popfd
5514704B 9D                   popfd  
   658:         mov[ebx], eax
5514704C 89 03                mov         dword ptr [ebx],eax  
   659: 
   660:         pop eax
5514704E 58                   pop         eax    //HERE   **Unhandled exception at 0x5514704E (pevm.dll) in tool.exe: 0x80000004: Single step.**

   661:         //exchange eax ,ecx,edx,esi,edi
   662:         XCHG eax, [ebx + type int]
5514704F 87 43 04             xchg        eax,dword ptr [ebx+4]  
   663:         xchg ecx, [ebx + 3 * type int]
55147052 87 4B 0C             xchg        ecx,dword ptr [ebx+0Ch]  
   664:         xchg edx, [ebx + 4 * type int]
55147055 87 53 10             xchg        edx,dword ptr [ebx+10h]  
   665:         xchg esi, [ebx + 5 * type int]
55147058 87 73 14             xchg        esi,dword ptr [ebx+14h]  
   666:         xchg edi, [ebx + 6 * type int]
5514705B 87 7B 18             xchg        edi,dword ptr [ebx+18h]  
   667: 
   668:         //exchange ebp,esp
   669:         mov esp, ebp
5514705E 8B E5                mov         esp,ebp  
   670:         pop ebp
55147060 5D                   pop         ebp  
   671:         xchg ebp, [ebx + 7 * type int]
55147061 87 6B 1C             xchg        ebp,dword ptr [ebx+1Ch]  
   672:         xchg esp, [ebx + 8 * type int]
55147064 87 63 20             xchg        esp,dword ptr [ebx+20h]  
   673: 
   674:         //go eip
   675:         ret
55147067 C3                   ret  
--- No source file -------------------------------------------------------------
55147068 CC                   int         3  
55147069 CC                   int         3  
5514706A CC                   int         3  
5514706B CC                   int         3  
5514706C CC                   int         3  
5514706D CC                   int         3  
5514706E CC                   int         3  
5514706F CC                   int         3  

0x5514704B 你设置了 EFLAGS。当设置了 TF 标志时,CPU 将在下一条执行指令后生成调试异常 (#DB)。 popfd之后的下一个是mov[ebx], eax,所以执行完就产生了异常。由于 #DB 是一个陷阱,因此 eip 指向执行指令后的地址,在您的情况下为 pop eax

检查 0x55147048 处的 push[ebx] 是否设置了 TF 位。