1. 什么是OpCode?
1. 什么是OpCode? |
转自老罗
Things have changed in the past two decades.
-- Bill Gates(1995)
什么是OpCode?
不管计算机技术的发展如何日新月异,其最基本的东西是不会突然改变的。OpCode就是这其中的一样东西——因此,Bill Gates的这句话用在这里并不太合适。
在开始回答什么是OpCode之前,请让我先来提几个小问题。
- 计算机只认识0和1吗?
- 如果上面的回答是“是”,那么我们平时写的程序源代码是0和1吗?
- 如果上面的回答是“不是”,那么计算机是怎么“知道”我们的程序的意思的?
按顺序作答,依次是:
- 是
- 不是
- ???
最后一个问题的答案是……?我们来举个例子,在汇编语言中:
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。 |
OpCode管中窥豹
有6个域是OpCode可能会用到的,或者说OpCode是由这6个域组成的——不过请注意:它们的名字是什么,这并不重要——重要的是它们的排列顺序。
它们是:
- Prefixes
- code
- ModR/M
- SIB
- Displacement
- 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,它也能与movsb,stosb等指令联用,但是,具体细节在这里暂不深究。
让我再来强调一次:OpCode中的6个域是可选的(除了域code之外),不必都用上,但是code是一定会有的。
知道了这一点,我们再来看一些例子:
OpCode && mnemonic | |||||||||||||
OpCode | mnemonic | ||||||||||||
27 | DAA | ||||||||||||
2F | DAS | ||||||||||||
3F | AAS | ||||||||||||
37 | AAA | ||||||||||||
D40A | AAM | ||||||||||||
D50A | AAD |
在Intel的文档中,上表中的所有指令都是1字节的,但是,我们能够看到AAM和AAD是2字节的,到底有什么不同呢?
先不要看下面的答案,试着自己想一想……
.
.
.
.
.
.
.
.
.
We can see:
- AAM和AAD都是2字节的,然而其余的4个指令都是1字节的。
- AAM和AAD的OpCode的第2个字节都是0Ah。
如果你还没把大学里的汇编知识彻底还给老师的话,应该还记得AAM和AAD的描述:
AAM : divide al by 10
商 放在AH里
余数 放在AL里
AAD : AL = AH * 10 + AL
注意到了吗?两者的操作都与10有关。而且两者的OpCode的第二个字节都是10(0Ah)。
人类与动物的其中一个区别是具有思维的联想性。聪明的你是不是猜到了什么?
嗯……0Ah会不会是偶然的呢?它会不会是操作数的一部分?进一步地,AAM与AAD的指令格式会不会不是:
D40A for AAM
D50A for AAD
而是:
D4:imm8 for AAM
D5:imm8 for AAD
以及,imm8可以是任何别的数字呢?(注:imm8表示8位的立即数)
答案是肯定的!
事实上,我们可以通过反汇编器得知,D407表示的是AAM 7,D508表示的是AAD 8,以此类推。
现在,我们又知道了一种新的指令格式:
{code}{Immediate}(域2和域6)
还有别的,以后再说。
There's Something We Should Know...
最后再强调一点:
- 虽然并不是6个域都是必要的,但是,它们的排列顺序绝对不能乱,必须严格按照上面的顺序进行。有些域也许不会出现,但是只要出现了,编号小的域就绝对不允许出现在编号大的域的后面,反之亦然。
例如,{Prefix}{code}的顺序绝对不允许变成{code}{Prefix}。
不相信?举个例子:4004和0440(假设在32位条件下)
OpCode && mnemonic | |||||
OpCode | mnemonic | ||||
4004 | INC EAX | ||||
0440 | ADD AL, 40h |
明白了吗?
理解了OpCode的规则,将有助于底层程序员明白一些鲜为人知的事情。在接下来的章节中,我们将学习OpCode的6个域的详细信息。
罗聪 www.LuoCong.com |
1. 什么是OpCode?相关推荐
- PHP安装parsekit扩展查看opcode
也可以通过VLD查看,具体请看本人写的http://blog.csdn.net/21aspnet/article/details/7002644 安装parsekit扩展 http://pecl.ph ...
- PHP安装与使用VLD查看opcode代码【PHP安装第三方扩展的方法】
需要分析PHP代码的性能,或者说实现同样功能的代码到底哪个更好呢?或者说想知道底层的实现可以使用VLD查看opcode 下载与安装VLD # wget http://pecl.php.net/get/ ...
- 深入理解PHP之OpCode
OpCode是一种PHP脚本编译后的中间语言,就像Java的ByteCode,或者.NET的MSL. 此文主要基于< Understanding OPcode>和 网络,根据个人的理解和修 ...
- php 的opcode缓存apc以及其安装
先说说php程序的执行流程吧,说明了这个,才好开始我们的优化之旅. 客户端(譬如浏览器) ->请求Get hello.php -->cgi服务器接(譬如apache)收到请求,根据配置寻找 ...
- java opcode 反汇编,OPCode详解及汇编与反汇编原理
1. 何为OPCode 在计算机科学领域中,操作码(Operation Code, OPCode)被用于描述机器语言指令中,指定要执行某种操作的那部分机器码,构成OPCode的指令格式和规范由处理器的 ...
- 基于深度学习的安卓恶意应用检测----------android manfest.xml + run time opcode, use 深度置信网络(DBN)...
基于深度学习的安卓恶意应用检测 from:http://www.xml-data.org/JSJYY/2017-6-1650.htm 苏志达, 祝跃飞, 刘龙 摘要: 针对传统安卓恶意程序检测 ...
- 160个Crackme024之Opcode加密
文章目录 查壳 分析程序 分析算法 第一部分 计算用户名和序列号 第二部分 根据用户名和序列号的结果改写Opcode 第三部分 关键校验 揣摩作者意图 程序算法总结 写出注册机 校验结果 查壳 024 ...
- 深入理解PHP Opcode缓存原理
什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).Opcode cache的目地是避免重复编译,减少 ...
- PHP OPCode缓存:APC详细介绍
PHP OPCode缓存:APC详细介绍 前言 PHP语言在性能上相对于其他编译型语言来说性能算不上突出,但是使用了OPCode缓存后性能提升还是很明显的.常见的主要有 Eaccelerator,XC ...
- 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 ...
最新文章
- Leetcode1706. 球会落何处[C++题解]:模拟
- 7 天玩转 ASP.NET MVC — 第 6 天
- excel转las文件_这3种Word、Excel格式不变的互转方法,实在太好用了
- 【2019南昌邀请赛现场赛 - J】Prefix(STLmap,思维)
- ffmpeg 为取经而来_伊力特的英雄情结从何而来?
- P3954 [NOIP2017 普及组] 成绩(python3实现)
- maze_travel的隐私声明
- pytorch 构造读取数据的工具类 Dataset 与 DataLoader (pytorch Data学习一)
- Vue之.sync 修饰符详解
- 利用分类模型学习特征权重
- 盘点电机重要应用的七大领域
- esxi - with nvidia geforce 10 titan xp card
- Chrome浏览器常用快捷键总结
- Fix ‘Clearing orphaned inodes’ on Ubuntu
- 怎么安装Nginx的监控模块
- Android 显示后台返回富文本rgb色值适配问题
- leetcode 1313. Decompress Run-Length Encoded List(python)
- 如何实现GPRS 拨号上网?
- 成功解决笔记本重装系统后没有无线网
- 光盘如何重装系统教程
热门文章
- 如何在电脑上使用计算机,字体如何安装到电脑里_怎么给电脑装字体-win7之家
- 网络编程+go+java_GO语言的进阶之路-网络编程之socket
- 如何 在java中输入字符
- python面试宝典2
- 用java实现PTA古风版
- 【生活】通过哈勃望远镜看看你生日那天太空景象
- [贝聊科技]使用Android Studio和MAT进行内存泄漏分析
- .as_matrix()的作用
- 计算机管理没用硬盘,win10电脑未使用中为什么硬盘一直在读写_win10未工作硬盘一直读写解决方法...
- 原神服务端建模修改模型贴图(SpecialK)教程