在使用CodeViewer调试器单步执行时,EAX寄存器被截断为16位,这种行为很奇怪吗?

编程语言 2026-07-11

DOS 6.22。虚拟机。

简单代码:

.model small, stdcall  
.386  
.stack 1024

.code  
Main proc  
mov  AX, @data  
mov  DS, AX  
mov  EBX, 00F00140h            ; ebx contain 00F00140h  
mov  EAX, EBX                  ; eax contain 00F00140h  
xor  ECX, ECX                  ; eax contain 00000140h   !!??
...
Main endp

end main

EAX的高16位丢失。怎么会这样?mov EAX, EBX 之后的命令并不重要。任意命令执行后,高16位会变为零。并且这只在 EAX 时发生。

在qemu、bochs、VirtualBox的 CodeViewer中进行了检查。用 masmfasm 编译。结果没有变化。这是怎么回事?是虚拟机问题还是CodeViewer?还有哪些用于DOS的调试器支持查看32位寄存器?
是否有支持逐步执行代码的虚拟机?

最有可能是你调试器的一个错误,可能出现在显示方面,或者在中断处理程序未保存/恢复完整寄存器,或者其他原因。

如果在

mov eax, ebx; 
xor ecx, ecx

之后添加

mov  edx, eax

那么 edx 包含00000140h,而不是00F00140h。这不太可能是调试器的错误。

@PeterCordes,感谢。确实,ldebug显示的EAX值是预期的。微软居然允许这样一个错误,真是怪。现在我可以调试我的程序,其中EAX的值也以一种奇怪的方式被破坏。

解决方案:不要使用CodeViewer调试包含32位寄存器的代码。

解决方案

感谢 @PeterCordes提供的有用提示。

如果你在CodeViewer中对程序进行逐步调试,并在代码中使用EAX寄存器,那么16位的上半部分会变为零。数据被破坏。你看不到代码实际是如何执行的。例如,EAX中来自0x08000140的数据(十进制132,218,048)被转换为0x00000140(十进制320)。

不要使用CodeViewer来调试包含32位寄存器的代码。例如,你可以使用lDebug。使用rx选项查看32位寄存器。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章