OpCode 笔记

本文详细介绍了OpCode的6个域,重点解析了Prefixes合集及其作用,包括改变默认操作数大小、地址大小、重复前缀、段覆盖前缀和锁定前缀。同时,解释了为什么使用默认段概念以及如何确定当前使用的段。接着,文章介绍了OpCode的基本概念,特别是ModR/M域的2:3:3表示法,并通过实例展示了如何解读ModR/M。
摘要由CSDN通过智能技术生成

 OpCode的6个域:

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

记住:

  • 在实际的使用中,并不是这所有的6个域都会被用到的,但是有一项却是一定会有的,那就是第2项:code,有些指令甚至只会用到code这一项。
  • 这6个域的排列顺序绝对不能乱,必须严格按照上面的顺序进行。有些域也许不会出现,但是只要出现了,编号小的域就绝对不允许出现在编号大的域的后面,反之亦然。

Prefixes合集

在前一章中我们已经知道:

  1. 所有Prefixes的长度都是1个字节。
  2. 一个OpCode可能会有几个Prefixes。
  3. 如果有多个Prefixes,那么它们的顺序可以打乱。
  4. 如果Prefixes不能对随它之后的OpCode起作用,那么它就会被忽略。

现在我们将要学习剩下的几个Prefixes,它们可以被划分为5个集合,分别是:

  1. Change DEFAULT operand size. (66)
  2. Change DEFAULT address size. (67)
  3. Repeat prefixes. (F2, F3)
  4. Segment override prefixes(change DEFAULT segment). (2E, 36, 3E, 26, 64, 65)
  5. LOCK prefix. (F0)

读者在这里也许会存在一个疑问:默认?我怎么知道当前默认的是哪个段呢?以及为什么要用默认的概念呢?

答案是这样的:在使用内存中的数据时,处理器必须首先知道它的段地址(Segment)和偏移量(Offset),但是如果在每个地方都要显式地直接指出段地址,那么在OpCode格式中就必须增加一个新的域,这将会比现有的OpCode体系多占用大量的字节,而且处理器也必须多花费额外的时钟周期来进行解码——无论在空间还是时间上,都不值得!

因此,为了解决这个问题,一个方案诞生了:

指令由不同的定义被划分为不同的组,每个组各自有一个默认的段:

CS: for EIP pointer
ES: 目的操作数是内存单元的串指令(movs, cmps等),在这里源操作数是储存在段DS里面。
SS: 堆栈操作(push, pop等)
DS: 剩下的数据操作指令。

有了这个规则,处理器识别当前应该用哪个段将会变得非常简单而直接:

  1. 如果有“Segment override prefix”,那么就使用这个prefix所指定的段。
  2. 否则就使用默认的段。

看看:

   AC     LODS [BYTE DS:ESI]
3E AC     LODS [BYTE DS:ESI]

从上面的表中可以查出,3E是表示段DS,但是实际上在这里即使不直接指明3E,处理器也是会使用DS的,因为DS是指令LODS的默认段。


<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值