首页
社区
课程
招聘
[原创]intel opcode 解析
发表于: 2023-5-7 18:09 6873

[原创]intel opcode 解析

2023-5-7 18:09
6873

intel opcode 解析

1. 保护模式 & 实模式 &8086架构

1.1. 1 指令格式描述

x86指令格式

1.1.1. 指令前缀 Instruction Prefixes

指令前缀可以划分为4种类型,每种都有一组对应的前缀码,对于每条指令可以从每种指令里面选取一条(最多可以选取4条指令,无序)

  • Group1

    • 锁定和重复前缀(Lock and repeat prefixes) :
      • F0H - LOCK prefix
      • F2H - REPNE/REPNZ prefix。(Repeat-Not-Zero)仅用于串操作和I/O指令,也可被用作某些指令的强制性前缀。
      • F3H - REP or REPE/REPZ。 仅用于串操作和I/O指令,也可被用作POPCNT、LZCNT、ADOX指令的强制性前缀。
    • F2H: BND prefix,如果满足以下条件:
      1. CPUID.(EAX = 07H, ECX = 0):EBX.MPX[bit 14] is set
      2. BNDCFGU.EN and/or IA32_BNDCFGS.EN is set.
      3. When the F2 prefix precedes a near CALL, a near RET, a near JMP, a short Jcc, or a near Jcc instruction
  • Group2

    • 段重载前缀(Segment override prefixes):
      • 2EH—CS segment override (保留任何分支指令时使用).
      • 36H—SS segment override prefix (保留任何分支指令时使用).
      • 3EH—DS segment override prefix (保留任何分支指令时使用).
      • 26H—ES segment override prefix (保留任何分支指令时使用).
      • 64H—FS segment override prefix (保留任何分支指令时使用).
      • 65H—GS segment override prefix (保留任何分支指令时使用).
    • (分支预测)Branch hints (已不用)
      • 2EH—分支不被接受 (used only with Jcc instructions).
      • 3EH—分支被接受 (used only with Jcc instructions).
  • Group 3

    • 66H - 操作数大小重载前缀(也用作某些指令的强制性前缀)。
  • Group 4

    • 67H - 地址大小重载前缀

F0H(LOCK 前缀)在多处理器环境下强制执行独占共享内存操作。

 

F2H,F3H(重复前缀)会重复字符串的每一个操作,只有 MOVS,CMPS,SCAS,LODS,STOS,INS,OUTS等字符串操作或者IO指令可以使用这些前缀。

 

2EH,3EH(分支预测)允许程序给处理器一个最有可能的执行分支提示。

 

66H(操作数大小重载前缀)允许程序在16位和32位操作数大小间切换。加前缀代表非默认值(默认值可以随意设定为16位或者32位)

 

67H(地址大小重载前缀)允许程序在16位和32位地址间切换。

1.1.2. Opcode

主操作码可以是 1, 2, 3个字节大小。可能在 ModR/M中还额外存在3位操作码,它们用来定义较小的字段,如:操作方向,位移大小,寄存器编码,条件码,符号扩展等。

 

用于通用和SIMD指令的双字节的操作码格式一般如下所示:

  • 转义操作码 0FH 被作为主操作码再跟上一个单字节操作码。
  • 强制前缀(66H,F2H,F3H)、转义操作码加上一个单字节操作码。eg: CVTDQ2PD -> F3 0F E6 F3 为强制前缀

用于通用和SIMD指令的三字节的操作码格式一般如下所示:

  • 转义操作码 0FH 被作为主操作码再跟上一个双字节操作码。
  • 强制前缀(66H,F2H,F3H)、转义操作码加上一个双字节操作码。eg: PHADDW -> 66 0F 38 01 66 为强制前缀

1.1.3. ModR/M & SIB

许多引用内存中操作数的指令在Opcode 之后都跟有一个寻址模式说明字节,称之为(ModR/M字节)。在ModR/M字节中包含三个字段的信息:

  • mod 字段 & R/M 字段:结合之后形成$4* 8 = 32$种可能的值: 8个寄存器和24种寻址模式。
  • reg/opcode字段:确定寄存器号或者附加的3位操作码的信息,用途在主Opcode中确定。
  • r/m 字段:确定一个寄存器为操作数或者和mod域一起编码寻址模式。

某些ModR/M字节编码需要第二寻址字节(SIB).基址+索引或者比例+索引形式的32位寻址需要SIB字节.SIB字节包括下列字段:

  • scale 指定比例因子
  • index 指定索引寄存器号
  • base 指定基址寄存器号

1.1.4. 偏移和立即数

一些寻址模式会在ModR/M(或者SIB)字节之后补充对应的偏移,如果存在,它是1,2,4个字节。

 

指令可能指定一个直接操作数,操作数通常在偏移之后。如果存在,它是1,2,4个字节。

1.2. 实例

1.2.1. 16位寻址模式 ModR/M 字节表

16-bit 寻址模式

1.2.2. 32位寻址模式 ModR/M 字节表

32位寻址模式

1.2.3. 32位寻址模式 SIB 字节表

32位 寻址模式 SIB表

1.2.4. 实际规则描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.text:00002D0C 55                                                              push    ebp
.text:00002D0D 89 E5                                                           mov     ebp, esp
.text:00002D0F 53                                                              push    ebx
.text:00002D10 83 EC 14                                                        sub     esp, 14h
.text:00002D13 E8 4F E7 FF FF                                                  call    sub_1467
.text:00002D18 81 C3 F4 88 02 00                                               add     ebx, (offset off_2B60C - $)
.text:00002D1E 8B 83 D8 FF FF FF                                               mov     eax, ds:(stderr_ptr - 2B60Ch)[ebx]
.text:00002D24 8B 00                                                           mov     eax, [eax]
.text:00002D26 89 44 24 0C                                                     mov     [esp+0Ch], eax  ; s
.text:00002D2A C7 44 24 08 ED 01 00 00                                         mov     dword ptr [esp+8], 1EDh ; n
.text:00002D32 C7 44 24 04 01 00 00 00                                         mov     dword ptr [esp+4], 1 ; size
.text:00002D3A 8D 83 74 A1 FF FF                                               lea     eax, (aUsageSetInterp - 2B60Ch)[ebx] ; "Usage: \n  [--set-interpreter FILENAME]"...
.text:00002D40 89 04 24                                                        mov     [esp], eax      ; ptr
.text:00002D43 E8 80 E4 FF FF                                                  call    _fwrite
.text:00002D48 83 C4 14                                                        add     esp, 14h
.text:00002D4B 5B                                                              pop     ebx
.text:00002D4C 5D                                                              pop     ebp
.text:00002D4D C3                                                              retn
  1. push ebp: 查表得 符合 PUSH r64规则,Opcode对应为50+rd 其中 +rd 表示低三位用来编码 dword 寄存器操作数, 查表知ebp对应为5 所以 push ebp 对应 opcode 为 55。
  2. mov ebp, esp: 符合规则 MOV r/m32,r32规则,opcode 对应为 89 /r,其中 /r表示有一个 ModR/M 结构的opcode , 该方式为寄存器直接寻址,所以MOD 标识为 11,目的地址为寄存器 ebp,所以R/M为 101,REG/opcode 端看第二个操作数,此处为 esp 所以reg/opcode 为100,对应整体opcode为11 100 101 即 E5。所以整体opcode 为 89 E5
  3. push ebx类似 1. ebx对应为3 ,所以对应opcode 为 53
  4. sub esp, 14h: 符合SUB r/m32, imm8 opcode为83 /5 ib 其中/5表示ModR/M 端存在,且仅使用 r/m操作数,寻址方式为寄存器立即寻址。reg字段包含一个数字5提供指令操作码的扩展,目的寄存器为 esp R/M 为 100. 对应opcode 为 11 101 100ib表示立即数 14。整体opcode 为 83 EC 14
  5. call sub_1467符合CALL rel32,对应opcode 为 E8 cd 其中 cd 表示 4个btye字节在call后面,这4个byte用于指示相对偏移,此处为 $1467 - (2d13 + 5(指令长度)) = ff ff 17 4f$,即 4F 17 FF FF,所以opcode为 E8 4F E7 FF FF
    其后类似,不做展开。

2. IA-32E MODE

分为两种:

  • Compatibility Mode(兼容模式) : 允许64位操作系
  • 统运行legacy保护模式软件。
  • 64位模式: 允许64位操作系统运行为访问64位地址空间而编写的应用程序。

x64指令格式

2.1. 前缀(Prefixes)

访问64位专用的前缀 REX Prefixes。以及为了兼容x86所保留的原来的前缀 Legacy Prefixes。

Legacy prefix和REX prefix修饰符是为了改变缺省的寄存器,比如说在32位下mov ax,bx。那么就要有Legacy prefix 0x66修饰,前者还有个作用就是改变当前段寄存器,不多这在目前已经显得不怎么重要了。到了x64的时候,由于通用寄存器的扩展(主要原因),原本的8个通用寄存器只要3个位来标识,但是现在多了r8~r15,16个通用寄存器,很明显加上一位就能完全标识了。那么就是REX prefix的作用。

 

 

REX prefix格式如上:总共占1byte ,前4位固定为0100后四位用来扩展指令,其中:

  • W : 标识操作数的大小,一般指令默认为32为操作数,所以需要通过修改 W来改变默认操作数大小,此时 opcode 为 0x48,对应为 REX.W
  • R : 用于扩展ModR/W,原始8个通用寄存器使用三位即可标识,但是x64新增了 r8~r15,一共具有16个通用寄存器,因此新政一位用来扩展 ModR/M.reg域,即原始范围为 $000 ~ 111$,扩展之后为 $0 000 ~ 1 111$
  • X : 用来扩展 SIB.index 域
  • B : 用来扩展 SIB.base, ModRM.r/m 以及 Opcode.reg

其他基本与x86相同不再赘述。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2023-5-11 15:35 被安和桥南编辑 ,原因: 忘记加原创tag了
收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 2948
活跃值: (30846)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2023-5-7 20:26
1
游客
登录 | 注册 方可回帖
返回
//