记得前面提到过这个问题,几句话就给带过了。为什么还要啰里啰嗦的再说一下呢?
呵呵,是这样的,我在看一本汇编的资料时,怀疑上面的一个语句弄错了。想知道是不是他的汇编指令代码里包含“印刷错误”。我想如果是印刷错误的话,很可能他的二进制代码跟看得懂的指令码对不上。那么我如何自己将那个二进制代码转换成汇编指令码呢?
语句如下:00401046 51 push ecx ; make room for local
问题:请问如何知道51就是push ecx呢?
学友研究起细节来有时跟神经病一样,明知道这玩意儿是反汇编器的活,唉。如果水平高的话,这应该根本就不是一个值得写在blog上的问题。:)
通过搜索,知道了一个叫做opcode的概念。一查PUSH的opcode就是50。那么1就代表ecx啰?最后通过查Intel Architecture Software Developer’s Manual Volume 2: Instruction Set Reference,确认了这点。
摘抄一些信息在这里,算是给个路标,给其他学习汇编的朋友一个方便。
以下内容摘抄并翻译自《Intel Architecture Software Developer’s Manual Volume 2: Instruction Set Reference》
所有的Intel架构的指令编码都是下表列出的格式的子集。指令由以下元素组成:任意顺序排列的前缀,一个或两个字节的opcode,寻址方式指示部分(包括一个由ModR/M(register/memory mode)字节,有时还包括一个SIB(Scale-Index-Base)字节),一个偏移量(可选),和一个立即数部分(可选)。
包括锁前缀和重复前缀:
— F0H—LOCK prefix.
— F2H—REPNE/REPNZ prefix (used only with string instructions).段覆盖前缀:
— 2EH—CS segment override prefix.
— 36H—SS segment override prefix.
• Operand-size override, 66H
• Address-size override, 67H
2.3 OPCODE2.4 ModR/M和SIB字节
多数涉及内存中的操作数的指令中都有一个紧随在OPCODE之后的字节,它被用来指定寻址方式。ModR/M包括三部分信息:
模式部分:有32种可能的值-8个寄存器加24种寻址模式
reg/opcode部分:要么指定一个寄存器的值,要么指定opcode中额外的三个bit的信息。
r/m部分可以指定一个寄存器作为操作数,或者和mod部分合起来表示一个寻址模式。
SIB字节包括三个部分:
scale部分-指定scale因子。
index部分-指定索引寄存器的号码
base部分-指定记寄存器的号码
等等。。。。。
查表后发现push的opcode是50, ECX的ModR/M的值是1.