00441582 |. 8378 18 00 cmp dword ptr [eax+18], 083781800被翻译成了cmp dword ptr[eax+18],0
我查看intel指令手册发现,觉得应该被翻译成cmp byte ptr[eax+18],0
理由如下:首先83是一个opcode查看one-byte opcode表
是Immidiate Group 1组,格式是Eb,Ib,意思是目的操作数是Eb格式的,源操作数是Ib格式的,Eb是啥意思呢?Ib是啥意思呢?先不用管,下面会解释。先看Immidiate Group 1是啥意思.在指令手册中找到这样一段话
意思是说有些one-byte opcode和two-byte opcode并不代表一条指令,而是代表一组指令,具体看“Opcode Extensions For One- And Two-byte Opcodes ”这一节。
具体是怎么扩展的呢?就是说one-byte opcode后面紧跟着的是一个MODR/M字节这个字节原来的结果是MOD域占第7、 6 BITREG/OPCODE域占第5 、4、 3BITR/M域占第2 、1、 0 BIT
REG/OPCODE域大多数情况下是用来编码一个操作数的,也可以用来编码OPCODE
回到8378180083是一个opcode,后面的0x78是MODR/M字节0x78化为二进制是0111 1000转化为MODR/M格式是01 111 000所以REG/OPCODE域是111所以83和这个111共同决定了对应的指令是CMP
也就是说被翻译成CMP Eb,IbEb是又两部分构成的,E和b,同理Ib是I和b
指令手册中关于E的说明是这样的:E A ModR/M byte follows the opcode and specifies the operand. The operand is either ageneral-purpose register or a memory address. If it is a memory address, the address iscomputed from a segment register and any of the following values: a base register, anindex register, a scaling factor, a displacement.意思是说再opcode后面跟着ModR/M字节,这个字节决定了操作数类型,可以是通用寄存器也可以是一个由其它寄存器的表达式构成的一个内存地址。
指令手册中关于b的说明是这样的:b Byte, regardless of operand-size attributeb的意思就是一个字节,无论操作数是多少位的。
指令手册中关于I的说明是这样的:I Immediate data. The operand value is encoded in subsequent bytes of the instruction.意思是说I是表示立即数,这个立即数就在指令字节中就能找到。
所以CMP Eb,Ib中Eb的意思就是目的操作数无论是多少位的,比如用ebx这个32位寄存器寻址,最后也只取一个byte,我就是这里困惑,不知道我理解错了没。Ib是一个字节的立即数。
又因为MODR/M字节是MOD域占第7、 6 BITREG/OPCODE域占第5 、4、 3BITR/M域占第2 、1、 0 BIT
且MODR/M的当前值是 01 111 000查询一下MODR/M表
是disp8[eax],意思是eax要加上一个偏移值,那么83781800中的0x18就是偏移,最后的00就是立即数
所以最后被翻译成这样才对cmp byte ptr[eax+18],0
但是我看OD和IDA中的结果都是cmp dword ptr[eax+18],0
我哪里理解错了吗?好几天了,非常困惑。