如何解决MSVC++ 内联汇编未处理异常 0x80000004:单步
我正在使用带有 VC++ 2019 32 位的内联 asm 编写代码。我写了一个函数来切换协程。这是源代码:
我对其进行了测试,效果很好。参数是一个包含寄存器值的 uintptr_t 数组。该函数将交换除ebx之外的寄存器值。
问题是“tool.exe 中 0x5514704E (pevm.dll) 处的未处理异常:0x80000004:单步。”。
寄存器值:EAX = 00000246 EBX = 0019F5A0 ECX = E2F13240 EDX = 0019F5A0 ESI = 0019F3A8 EDI = 0019F3C8 EIP = 5514704E ESP = 0019F2BC EBP = 0019F2C0 EFL = 00000202
我不明白为什么“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,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
。
检查 push[ebx]
处的 0x55147048
是否设置了 TF
位。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。