Assembly NASM反汇编代码与汇编代码不同

Assembly NASM反汇编代码与汇编代码不同,assembly,x86,nasm,Assembly,X86,Nasm,我将此代码汇编成NASM(为保护模式设置段选择器,但与此问题无关): NASM反汇编显示机器代码将其视为: 66B810008ED8 mov eax,0xd88e0010 66B818008EC0 mov eax,0xc08e0018 这显然是一项非常艰巨的装配工作。有人能解释一下这里出了什么问题吗?这是虫子吗 我还注意到mov edi,0没有以0x66作为前缀,即使它在32位指令之后,但NASM在操作码之后留下32位。纯粹的猜测,但在我看来,它似乎在汇编16位模式代码,但在反汇编为32位模式

我将此代码汇编成NASM(为保护模式设置段选择器,但与此问题无关):

NASM反汇编显示机器代码将其视为:

66B810008ED8 mov eax,0xd88e0010
66B818008EC0 mov eax,0xc08e0018
这显然是一项非常艰巨的装配工作。有人能解释一下这里出了什么问题吗?这是虫子吗


我还注意到mov edi,0没有以0x66作为前缀,即使它在32位指令之后,但NASM在操作码之后留下32位。

纯粹的猜测,但在我看来,它似乎在汇编16位模式代码,但在反汇编为32位模式代码。因此,它期望一个较大的常量移动到较大的寄存器中,并且基本上将寄存器移动指令解释为常量的一部分。一些输出可能看起来正确,但仍然被不正确地反汇编。我假设您使用
-b32
进行反汇编以获得此输出。相信我说的话。输出的二进制文件将丢失有关所使用的编码类型(16/32/64位)的所有信息。使用NDISSM正确反汇编32位代码的唯一方法是通过使用
-k
选项指定要跳过的字节数来跳过16位代码,并指定
-b32
解码为32位。这里的问题不是NASM,而是NDISSM。NDISASM也不是一个bug,因为由yoo来告诉NDISASM 32位代码从哪里开始,并将其解码为32位。NDISAM无法自动执行此操作。CPU不知道任何事情,它有一个状态,并且在每一个机器周期中,它都会根据以前的内存和内存内容修改其状态(即,它从
ip
寄存器指向的内存中读取什么指令,如果该指令引用了其他内存,则会在那里找到什么值)。如果它确实运行了将CPU切换到32位模式的指令,那么它将进一步解码并执行内存字节作为32位模式指令,但是如果它仍然处于16b模式,它将解码并执行与16位模式指令相同的字节=您将得到完全不同的结果。我应该指出一些问题。NASM在引擎盖下进行了一些优化。在32位代码中,它使用32位寄存器将mov从16位寄存器转换为段寄存器,再转换为mov。这在代码中保存了一个字节,并且做了同样的事情。如果您使用
mov-ds,ax
它实际上编码
mov-ds,eax
66B810008ED8 mov eax,0xd88e0010
66B818008EC0 mov eax,0xc08e0018