OPCode 详解

OpCode

操作码(Operation Code, OPCode):描述机器语言指令中,指令要执行某种操作的机器码

OPCode在不同的场合中通常具有不同的含义,例如PHP虚拟机(Zend VM)、java虚拟机(JVM)以及一些软件保护虚拟机中的最小操作单元都可以称之为OPCode。

常用字节

常用单字节OPCode概览A -- 40~4F

         opcode                                 asm                      using

          0x40                                  inc eax                 emit(0x40)
          0x41                                  inc ecx                 emit(0x41)
          0x42                                  inc edx                 emit(0x42)
          0x43                                  inc ebx                 emit(0x43)
          0x44                                  inc esp                 emit(0x44)
          0x45                                  inc ebp                 emit(0x45)
          0x46                                  inc esi                 emit(0x46)
          0x47                                  inc edi                 emit(0x47)
          0x48                                  dec eax                 emit(0x48)
          0x49                                  dec ecx                 emit(0x49)
          0x4a                                  dec ebx                 emit(0x4a)
          0x4b                                  dec ebx                 emit(0x4b)
          0x4c                                  dec esp                 emit(0x4c)
          0x4d                                  dec ebp                 emit(0x4d)
          0x4e                                  dec esi                 emit(0x4e)
          0x4f                                  dec edi                 emit(0x4f)

常用单字节OPCode概览B -- 50~5F

           opcode ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?asm ? ? ? ? ? ? ? ? ? ? ? ?using
           0x50 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push eax ? ? ? ? ? ? ? ? emit(0x50)
           0x51 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push??ecx ? ? ? ? ? ? ? ?emit(0x51)
           0x52 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push??edx ? ? ? ? ? ? ? ?emit(0x52)
           0x53 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push??ebx ? ? ? ? ? ? ? ?emit(0x53)
           0x54 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push??esp ? ? ? ? ? ? ? ?emit(0x54)
           0x55 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push??ebp ? ? ? ? ? ? ? ?emit(0x55)
           0x56 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push??esi ? ? ? ? ? ? ? ?emit(0x56)
           0x57 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?push??edi ? ? ? ? ? ? ? ?emit(0x57)
           0x58 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop eax ? ? ? ? ? ? ? ?  emit(0x58)
           0x59 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop??ecx ? ? ? ? ? ? ? ??emit(0x59)
           0x5a ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop??edx ? ? ? ? ? ? ? ? emit(0x5a)
           0x5b ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop??ebx ? ? ? ? ? ? ? ? emit(0x5b)
           0x5c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop??esp ? ? ? ? ? ? ? ??emit(0x5c)
           0x5d ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop??ebp ? ? ? ? ? ? ? ? emit(0x5d)
           0x5e ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop??esi ? ? ? ? ? ? ? ? emit(0x5e)
           0x5f ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pop??edi ? ? ? ? ? ? ? ? emit(0x5f)

常用单字节OPCode概览C -- 70~7F

? ? ? ? ?opcode ? ? ? ? ? ? ? ? ? ? ? ? ? ?asm ? ? ? ? ? ? ? ? ? ? ? ? ? ?using
? ? ? ? ?0x70 ?0x12 ? ? ? ? ? ?     ? ? ? ?Jo 0x12 ? ? ? ? ?{_emit(0x70)}?{_emit(0x12)}
? ? ? ? ?0x71 ?... ? ? ? ? ? ? ? ? ? ? ? ? Jno ... ? ? ? ? ? ? ? ? ? ? ?? ... ...
? ? ? ? ?0x72 ?... ? ? ? ? ? ? ? ? ? ? ? ? Jb ?... ? ? ? ? ? ? ? ? ? ?  ??... ...
? ? ? ? ?0x73 ?... ? ? ? ? ? ? ? ? ? ? ? ? Jae ... ? ? ? ? ? ? ? ? ? ?  ??... ...
? ? ? ? ?0x74 ?... ? ? ? ? ? ? ? ? ? ? ? ? Je ?... ? ? ? ? ? ? ? ? ? ??  ?... ...
? ? ? ? ?0x75 ?... ? ? ? ? ? ? ? ? ? ? ? ? Jne?... ? ? ? ? ? ? ? ? ? ?   ?... ...
? ? ? ? ?0x76 ?... ? ? ? ? ? ? ? ? ? ? ? ? Jbe ... ? ? ? ? ? ? ? ? ? ? ? ?... ...
? ? ? ? ?0x77 ?... ? ? ? ? ? ? ? ? ? ? ? ? Ja? ... ? ? ? ? ? ? ? ? ? ?   ?... ...
? ? ? ? ?0x78 ?... ? ? ? ? ? ? ? ? ? ? ? ? Js? ... ? ? ? ? ? ? ? ? ? ?   ?... ...
? ? ? ? ?0x79 ?... ? ? ? ? ? ? ? ? ? ? ? ? Jns ... ? ? ? ? ? ? ? ? ? ? ? ?... ...
? ? ? ? ?0x7a ?... ? ? ? ? ? ? ? ? ? ? ? ? Jp? ... ? ? ? ? ? ? ? ?    ? ? ... ...
? ? ? ? ?0x7b ?... ? ? ? ? ? ? ? ? ? ? ? ? Jnp?... ? ? ? ? ? ? ?  ? ? ??? ... ...
? ? ? ? ?0x7c ?... ? ? ? ? ? ? ? ? ? ? ? ? Jl  ... ? ? ? ? ? ? ?? ? ?     ... ...
? ? ? ? ?0x7d ?... ? ? ? ? ? ? ? ? ? ? ? ? Jge?... ? ? ? ? ? ? ? ? ?   ? ?... ...
? ? ? ? ?0x7e ?... ? ? ? ? ? ? ? ? ? ? ? ? Jle ... ? ? ? ? ? ? ? ?   ? ? ?... ...
? ? ? ? ?0x7f ?... ? ? ? ? ? ? ? ? ? ? ? ??Jg  ... ? ? ? ? ? ? ? ?  ?  ? ?... ...

常用单字节OPCode概览D -- 90~9F

? ? ? ? Opcode ? ? ? ? ? ? ? ? ? ? ? asm ? ? ? ? ? ? ? ? ? Using
? ? ? ? ?0x90 ? ? ? ? ? ? ? ? ? ?Nop/xchg eax,eax ? ? ? _emit(0x90)
? ? ? ? ?0x91 ? ? ? ? ? ? ? ? ? ?Xchg eax,ecx ? ? ??
? ? ? ? ?0x92 ? ? ? ? ? ? ? ? ? ?Xchg eax,edx ? ? ??
? ? ? ? ?0x93 ? ? ? ? ? ? ? ? ? ?Xchg eax,ebx ? ? ??
? ? ? ? ?0x94 ? ? ? ? ? ? ? ? ? ?Xchg eax,esp ? ? ??
? ? ? ? ?0x95 ? ? ? ? ? ? ? ? ? ?Xchg eax,ebp ? ? ?
? ? ? ? ?0x96 ? ? ? ? ? ? ? ? ? ?Xchg eax,esi ? ? ??
? ? ? ? ?0x97 ? ? ? ? ? ? ? ? ? ?Xchg eax,edi??

OPCode与指令的对应关系

同类型的指令OPCode不一定相同

B8 01000000    mov eax, 1
8B C3          mov eax, ebx
8B C7          mov eax, edi

OPCode相同的情况下指令也不一定相同

90 nop
90 xchg ax, ax
90 xchg eax, eax    

结论: OPCode与汇编指令并非是单纯的对应关系

那么它是如何进行解释的呢?

首先它分为6个主要数据域,其中只有代码是必须存在的,指令长度在1-16个字节

所以指令独此一份,不可能为其他机器码

1, 前缀 Prefixes

前缀(Prefixes):大小1Byte,描述指令前缀情况,换分为5个集合,一个OPCode可能有几个Prefixes

  • 66 切换操作数的大小
  • 67 切换地址的大小
  • F2/F3 重复操作前缀
  • 2E/36/3e/26/64/65 修改默认段(段超越前缀)
  • F0 锁定前缀
;切换操作数大小
;切换顺序: 从大到小
40 ? ? ? ? ? ? INC EAX
66 40 ? ? ? ? ?INC AX

;无效的前缀应用
8AC1 ? ? ? ? ?MOV AL, CL
66 BAC1 ? ? ? MOV AL, CL

;重复操作段前缀
F3 66 AD ? ? ?REP LODSW
F2 AC? ? ? ? ?REPNE LODSB

;段超越前缀
8B 03 ? ? ? ? ?MOV EAX, [DWORD DS:EBX]
658B 03 ? ? ? ?MOV EAX, [DWORD GS:EBX]

前缀的具体含义可以在Intel手册中查到,比如2E,从手册可以看出是锁定CS段

2, 代码 code

3,构造模式 MODR/M

构造模式(Mode): 主要解析逻辑集中在ModeR/M域,通过查找Intel手册解析该域确定指令的具体格式

分为三个部分

  • 模式 Mode
  • 寄存器 Reg
  • 寄存器 R/M

对照Intel手册中的表来解析OPCode中的ModR/M域来确定指令的具体格式

89  D8          mov eax, ebx
D8 = 11011000
Mod  Reg  R/M
11   011  000

4,辅助分析 SIB

分为三个部分:

  • 比例 Scale
  • 索引 IndexOf
  • 基数 Base

5,位移 Displacement

6,立即数 Immediate

手工在Intel手册中查找OPCode的汇编代码:

? F0: 26: C78491 AA000000 11000000

    F0:    26:     C7      84       91    AA000000  11000000
  锁定前缀  段超越    OPCode ModeR/M   SIB      偏移       立即数
查找前缀

F0 - Prefixes:锁定前缀,即 Lock

26 - Prefixes:修改默认段,即段超越前缀,查"Opcode Map"如图,段超越前缀为 ES

查找Code

C7 - Code:查"Opcode Map"如图,可知:Grp 11 MOV Ev,Iz

查找ModeR/M

84 - ModR/M:转为二进制 10 000 100
模式(Mod)段 :2位 10
寄存器(Reg)段 :3位 000
寄存器(R/M)段 :3位 100
查"ModR/M"表如图,得到 [..][..]+disp32

查找SIB

91 - SIB:转为二进制 10 010 001
比例(Scale)段 :2位 10
索引(Index)段 :3位 010
基数(Base)段 :3位 001
查"SIB"表如图,可知 [EDX*4]+ECX

AA000000 - Displacement:此为小端模式,即为 0xAA
11000000 - Immediate:小端模式,即为 0x11
综上,得到:
LOCK MOV ES:[EDX*4+ECX+0xAA],0x11
即为:
LOCK MOV DWORD PTR ES:[EDX*4+ECX+0x0AA],0x11

3、内联汇编

 ;内联汇编可以有两种形式,一种是行内联汇编,一种是块内联汇编,二者可交叉使用;
 ;行内联汇编:
 __asm mov eax,a
 __asm add  eax,b
 __asm mov c,eax
 ; 块内联汇编:
 __asm{
          mov eax,a
          add  eax,b
          mov c,eax
 }

4、裸函数

// ;定义:没有任何可执行代码的空函数,在内存中仅仅是一条地址信息.
// ; 使用关键字“__declspec(naked)”定义;
// ; 例:
void __declspec(naked) TestFun( ){
    __asm  ret
}

总结:

ModR/M信息与确认是否有SIB字节

当Mod != 11b并且R/M的值为100b的时候,表示指令后续有SIB字节,并且该内存操作对象由SIB编码。

MODR/M里有三种情况会有SIB字节

参考链接

  1. https://blog.csdn.net/brunomarss/article/details/50589556
  2. https://blog.csdn.net/sqzxwq/article/details/47786345

原文地址:https://www.cnblogs.com/songyaqi/p/12074331.html

时间: 2025-01-17 17:34:27

OPCode 详解的相关文章

TI C66x DSP 指令集 -之- 操作码(opcode)详解

操作码(opcode)就是操作指令,表示该指令应进行什么性质的操作.CPU从程序计数器(PC寄存器)中得到操作码的地址,然后从程序存储空间获取操作码,然后译码,取出操作数,最后执行. 下面以在.D Functional Unit中执行的LDW指令(Load Word From Memory With a 5-Bit Unsigned Constant Offset or Register Offset)讲解.以下内容可参考TMS320C66x_DSP_CPU_and_Instruction an

OPCode详解及汇编与反汇编原理

1. 何为OPCode 在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的指令规范指定.除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显示的操作数.这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等. OPCode在不同的场合中通常具有不同的含义,例如PHP虚拟机(Zend VM).java虚拟机(JVM)以及一些软件保护虚拟机中

Oracle 11g数据库详解(2015-1-18更新)

Oracle 11g数据库详解 整理者:高压锅 QQ:280604597 Email:[email protected] 大家有什么不明白的地方,或者想要详细了解的地方可以联系我,我会认真回复的 1   简介 数据库操作主要有以下几步: 1.  启动.停止数据库 2.  连接.断开数据库 3.  创建.修改.删除数据库用户 4.  表空间 5.  新建.修改.删除表 6.  查询.插入.修改.删除表数据 7.  新建.修改.删除视图 8.  新建.修改.删除存储过程 9.  新建.修改.删除触发

【详解】DNS服务工作原理、正反向解析和主从同步

目录: 一.理论部分 二.实验部分 ******************************理论部分*************************************** 正文: 一.什么是DNS服务. DNS服务是互联网的基础性服务之一.全称为Domain Name System(域名系统).DNS是因特网上作为域名和IP地址相互映射的一个分布式数据库,提供将域名转换成对应IP地址的信息条目,能够使用户更方便的通过域名(如baidu.com)去访问互联网,而不用去记住能够被机器直接

Linux系统DNS详解(BIND)

一.Linux运维实战之DNS基础    DNS服务作为网络的一种基础架构,在网络中有举足轻重的地位.它担负着整个网络用户计算机的名称解析工作.没有正确的名称解析,服务器就无法识别各客户机.我们在日常进行的浏览网页等上网活动,无一例外都在使用DNS服务.*******************************************************************************    DNS的基本知识:        DNS服务器的组成        DNS域名称

Oracle 11g数据库详解(2015-02-28更新)

Oracle 11g数据库详解 整理者:高压锅 QQ:280604597 Email:[email protected] 大家有什么不明白的地方,或者想要详细了解的地方可以联系我,我会认真回复的 1   简介 数据库操作主要有以下几步: 1.  启动.停止数据库 2.  连接.断开数据库 3.  创建.修改.删除数据库用户 4.  表空间 5.  新建.修改.删除表 6.  查询.插入.修改.删除表数据 7.  新建.修改.删除视图 8.  新建.修改.删除存储过程 9.  新建.修改.删除触发

Oracle ErrorStack 使用和阅读详解

一.概述 在Oracle数据库运行过程中,我们经常会遇到这样或那样的错误,但是错误的提示并不具体,加大了我们在诊断问题时的难度. ErrorStack是Oracle提供的一种对于错误堆栈进行跟踪的方法,通过设置跟踪可以将一些指定错误的后台信息详细的转储出来,写入跟踪文件,帮助我们诊断问题. 备注: 1.当oracle发生关键的错误诸如:ora-600,Errorstack是自动被oracle dump写入trace文件中. 2.当你在alert.log里面看见这类错误,并提示已经产生trace文

新手入门:史上最全Web端即时通讯技术原理详解

前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM(相关文章请参见:<IM架构篇>.<IM综合资料>.<IM/推送的通信格式.协议篇>.<IM心跳保活篇>.<IM安全篇>.<实时音视频开发>).消息推送应用(参见:<推送技术好文>)的通信原理介绍也较多

Web端即时通讯技术原理详解

前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM(相关文章请参见:<IM架构篇>.<IM综合资料>.<IM/推送的通信格式.协议篇>.<IM心跳保活篇>.<IM安全篇>.<实时音视频开发>).消息推送应用(参见:<推送技术好文>)的通信原理介绍也较多