1. 什么是OpCode?

转自老罗

Things have changed in the past two decades.

-- Bill Gates(1995)

什么是OpCode?

不管计算机技术的发展如何日新月异,其最基本的东西是不会突然改变的。OpCode就是这其中的一样东西——因此,Bill Gates的这句话用在这里并不太合适。

在开始回答什么是OpCode之前,请让我先来提几个小问题。

  1. 计算机只认识0和1吗?
  2. 如果上面的回答是“是”,那么我们平时写的程序源代码是0和1吗?
  3. 如果上面的回答是“不是”,那么计算机是怎么“知道”我们的程序的意思的?

按顺序作答,依次是:

  1. 不是
  2. ???

最后一个问题的答案是……?我们来举个例子,在汇编语言中:

NOP

这条指令很简单,是吧?

在编译的时候,Assembler会扫描整个源代码。

在前面我们已经知道了,由于计算机只认识0和1,所以,源代码“NOP”是无法直接运行的。当Assembler遇到“NOP”的时候,为了生成让计算机能运行的“东西”(暂且这样称呼吧),就会以十六进制数“0x90”来代替它。

在这里,“0x90”就是“OpCode”,而“NOP”则是“助记符(mnemonic)”。

OpCode的全称

OpCode就是Operation Code,意即操作码的意思。

一个OpCode只对应一个助记符吗?

示例:OpCode && mnemonic
OpCode mnemonic
0x90 NOP
0x90 XCHG AX, AX
0x90 XCHG EAX, EAX

从上表中可以看出,同一个OpCode可以对应N个mnemonic。为什么会这样呢?原因现在不必深究,以后自然会明白的。

一个助记符只对应一个OpCode吗?

示例:OpCode && mnemonic
mnemonic OpCode
ADD EAX, 1 0x83C001
ADD EAX, 1 0x0501000000
ADD EAX, 1 0x81C001000000

从上表中也可以看出,同一个mnemonic可以对应多个OpCode。原因同样留待以后再说。

OpCode与mnemonic的关系

一个OpCode不只对应一个mnemonic
一个mnemonic不只对应一个OpCode

OpCode管中窥豹

有6个域是OpCode可能会用到的,或者说OpCode是由这6个域组成的——不过请注意:它们的名字是什么,这并不重要——重要的是它们的排列顺序。

它们是:

  1. Prefixes
  2. code
  3. ModR/M
  4. SIB
  5. Displacement
  6. Immediate

OpCode的这6个域的详细介绍留待以后再说,现在首先要知道:

在实际的使用中,并不是这所有的6个域都会被用到的,但是有一项却是一定会有的,那就是第2项:code,有些指令甚至只会用到code这一项。

例如:

OpCode && mnemonic
OpCode mnemonic
0xC3 RETN
0x2F DAS
0x90 NOP
0xAC LODSB

上表中的几个OpCode都只用到了code这一项。其中的最后一项:0xAC,让我们来看看能不能给它加上一些额外的“东西”:

0xF3AC    REP LODSB

可以看到:rep lodsb

为什么会多了个“rep”呢?是不是由额外的“F3”造成的呢?

Yes,猜对了,我们来看看它的OpCode格式描述,如下:(注:用{}包围起来的是域的名称)

AC -- {code}
F3 AC -- {Prefix}{code}
因此,F3 就是域 Prefix

在稍后的章节中我们会知道,F3表示的是Rep Prefix,它也能与movsbstosb等指令联用,但是,具体细节在这里暂不深究。

让我再来强调一次:OpCode中的6个域是可选的(除了域code之外),不必都用上,但是code是一定会有的。

知道了这一点,我们再来看一些例子:

OpCode && mnemonic
OpCode mnemonic
27 DAA
2F DAS
3F AAS
37 AAA
D40A AAM
D50A AAD

在Intel的文档中,上表中的所有指令都是1字节的,但是,我们能够看到AAMAAD是2字节的,到底有什么不同呢?
先不要看下面的答案,试着自己想一想……

.
.
.
.
.
.
.
.
.

We can see:

  1. AAMAAD都是2字节的,然而其余的4个指令都是1字节的。
  2. AAMAAD的OpCode的第2个字节都是0Ah

如果你还没把大学里的汇编知识彻底还给老师的话,应该还记得AAMAAD的描述:

AAM : divide al by 10
商   放在AH里
余数 放在AL里
AAD : AL = AH * 10 + AL

注意到了吗?两者的操作都与10有关。而且两者的OpCode的第二个字节都是10(0Ah)。

人类与动物的其中一个区别是具有思维的联想性。聪明的你是不是猜到了什么?

嗯……0Ah会不会是偶然的呢?它会不会是操作数的一部分?进一步地,AAMAAD的指令格式会不会不是

D40A for AAM
D50A for AAD

而是:

D4:imm8 for AAM
D5:imm8 for AAD

以及,imm8可以是任何别的数字呢?(注:imm8表示8位的立即数)

答案是肯定的!

事实上,我们可以通过反汇编器得知,D407表示的是AAM 7D508表示的是AAD 8,以此类推。

现在,我们又知道了一种新的指令格式:

{code}{Immediate}(域2和域6)

还有别的,以后再说。

There's Something We Should Know...

最后再强调一点:

  • 虽然并不是6个域都是必要的,但是,它们的排列顺序绝对不能乱,必须严格按照上面的顺序进行。有些域也许不会出现,但是只要出现了,编号小的域就绝对不允许出现在编号大的域的后面,反之亦然。

例如,{Prefix}{code}的顺序绝对不允许变成{code}{Prefix}。

不相信?举个例子:40040440(假设在32位条件下)

OpCode && mnemonic
OpCode mnemonic
4004 INC EAX
0440 ADD AL, 40h

明白了吗?

理解了OpCode的规则,将有助于底层程序员明白一些鲜为人知的事情。在接下来的章节中,我们将学习OpCode的6个域的详细信息。


罗聪
www.LuoCong.com

1. 什么是OpCode?相关推荐

  1. PHP安装parsekit扩展查看opcode

    也可以通过VLD查看,具体请看本人写的http://blog.csdn.net/21aspnet/article/details/7002644 安装parsekit扩展 http://pecl.ph ...

  2. PHP安装与使用VLD查看opcode代码【PHP安装第三方扩展的方法】

    需要分析PHP代码的性能,或者说实现同样功能的代码到底哪个更好呢?或者说想知道底层的实现可以使用VLD查看opcode 下载与安装VLD # wget http://pecl.php.net/get/ ...

  3. 深入理解PHP之OpCode

    OpCode是一种PHP脚本编译后的中间语言,就像Java的ByteCode,或者.NET的MSL. 此文主要基于< Understanding OPcode>和 网络,根据个人的理解和修 ...

  4. php 的opcode缓存apc以及其安装

    先说说php程序的执行流程吧,说明了这个,才好开始我们的优化之旅. 客户端(譬如浏览器) ->请求Get hello.php -->cgi服务器接(譬如apache)收到请求,根据配置寻找 ...

  5. java opcode 反汇编,OPCode详解及汇编与反汇编原理

    1. 何为OPCode 在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的 ...

  6. 基于深度学习的安卓恶意应用检测----------android manfest.xml + run time opcode, use 深度置信网络(DBN)...

    基于深度学习的安卓恶意应用检测 from:http://www.xml-data.org/JSJYY/2017-6-1650.htm 苏志达, 祝跃飞, 刘龙     摘要: 针对传统安卓恶意程序检测 ...

  7. 160个Crackme024之Opcode加密

    文章目录 查壳 分析程序 分析算法 第一部分 计算用户名和序列号 第二部分 根据用户名和序列号的结果改写Opcode 第三部分 关键校验 揣摩作者意图 程序算法总结 写出注册机 校验结果 查壳 024 ...

  8. 深入理解PHP Opcode缓存原理

    什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).Opcode cache的目地是避免重复编译,减少 ...

  9. PHP OPCode缓存:APC详细介绍

    PHP OPCode缓存:APC详细介绍 前言 PHP语言在性能上相对于其他编译型语言来说性能算不上突出,但是使用了OPCode缓存后性能提升还是很明显的.常见的主要有 Eaccelerator,XC ...

  10. php-5.6.26源代码 - opcode处理器,“函数调用opcode”处理器,如何调用扩展模块的函数...

    // opcode处理器 --- ZEND_DO_FCALL_SPEC_CONST_HANDLER实现在 php-5.6.26\Zend\zend_vm_execute.h static int ZE ...

最新文章

  1. Leetcode1706. 球会落何处[C++题解]:模拟
  2. 7 天玩转 ASP.NET MVC — 第 6 天
  3. excel转las文件_这3种Word、Excel格式不变的互转方法,实在太好用了
  4. 【2019南昌邀请赛现场赛 - J】Prefix(STLmap,思维)
  5. ffmpeg 为取经而来_伊力特的英雄情结从何而来?
  6. P3954 [NOIP2017 普及组] 成绩(python3实现)
  7. maze_travel的隐私声明
  8. pytorch 构造读取数据的工具类 Dataset 与 DataLoader (pytorch Data学习一)
  9. Vue之.sync 修饰符详解
  10. 利用分类模型学习特征权重
  11. 盘点电机重要应用的七大领域
  12. esxi - with nvidia geforce 10 titan xp card
  13. Chrome浏览器常用快捷键总结
  14. Fix ‘Clearing orphaned inodes’ on Ubuntu
  15. 怎么安装Nginx的监控模块
  16. Android 显示后台返回富文本rgb色值适配问题
  17. leetcode 1313. Decompress Run-Length Encoded List(python)
  18. 如何实现GPRS 拨号上网?
  19. 成功解决笔记本重装系统后没有无线网
  20. 光盘如何重装系统教程

热门文章

  1. 如何在电脑上使用计算机,字体如何安装到电脑里_怎么给电脑装字体-win7之家
  2. 网络编程+go+java_GO语言的进阶之路-网络编程之socket
  3. 如何 在java中输入字符
  4. python面试宝典2
  5. 用java实现PTA古风版
  6. 【生活】通过哈勃望远镜看看你生日那天太空景象
  7. [贝聊科技]使用Android Studio和MAT进行内存泄漏分析
  8. .as_matrix()的作用
  9. 计算机管理没用硬盘,win10电脑未使用中为什么硬盘一直在读写_win10未工作硬盘一直读写解决方法...
  10. 原神服务端建模修改模型贴图(SpecialK)教程