https://blog.csdn.net/ross1206/article/details/81661804
https://blog.csdn.net/ross1206/article/details/81663614
INSTRUCTION PREFIXES (前缀只有固定的这几个)
The instruction prefixes are divided into four groups, each with a set of allowable prefix codes:
• Lock and repeat prefixes.
— F0H—LOCK prefix.
— F2H—REPNE/REPNZ prefix (used only with string instructions).
— F3H—REP prefix (used only with string instructions).
— F3H—REPE/REPZ prefix (used only with string instructions).
• Segment override.
— 2EH—CS segment override prefix.
— 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.
• Operand-size override, 66H
• Address-size override, 67H
For each instruction, one prefix may be used from each of these groups and be placed in any
order. The effect of redundant prefixes (more than one prefix from a group) is undefined and may
vary from processor to processor.
image.png image.png
32位
image.pngimage.png image.png image.png image.png image.png image.png
image.png
image.png image.png
image.png image.png image.png
例2:随便找一个机器码如:FF 15 D4 81 DF 00
那么它的汇编语句是什么呢?
解码器会依次读入第 1 个字节,第 2 个字节等 ... 进行判断:
(1)第 1 个字节是什么? prefix 还是 opcode
(2)同样再判断第 2 个字节是不是 prefix,如果不是 prefix ,那么它就是 opcode 码
(3)如果第 2 个字节是 opcode 码,再判这个 opcode 需不需 ModRM 字节,如果需要,第 3 个字节就是 ModRM 字节
(4)根据 ModRM 字节判断需不需要 SIB 字节,第 4 个字节如果需它就是 SIB 字节
(5)判断 ModRM 字节是否需要 displacment 字节和 immediate 字节
根据上面的逻辑,得出:
FF:这个字节是个具有 Group 属性的 Opcode 码,它进行什么操作需要依赖于 ModRM 字节的 Reg 域。
换句话来说,FF 并不是完整独立的 Opcode 码,它要联合 ModRM 才能确定具体的操作。
15:这个是 ModRM 字节(mod-reg-r/m): ModRM.mod = 00,ModRM.reg = 010,ModRM.r/m = 101。
其中 ModRM.reg 域被 FF(opcode) 作为确定具体操作码的参考。
● Opcode + ModRm.reg : FF /010 最终确定为:Call 指令。
● ModRM.mod:00 表示操作数是 memory
● ModRM.r/m:这是一个 32 位的 displacement 值。
所以,这个机器码最终被解码为: call dword ptr [00DF81D4]
下面的直观的图表
image.png下面来看看 x86/x64 指令 encode 的 2 个例子:
|
mov word ptr es:[eax + ecx * 8 + 0x11223344], 0x12345678
|
例子1:在当前 32 位系统下,有下面汇编语句(Intel 格式):
这是一条** mov** 指令,目标操作数是** memory**,源操作数是 immediate
注意:
我特地将目的操作数的大小定为是 word(2个字节),而不是 dword。但是,源操作数却是一个 dword 大小的 0x12345678。
那么:对于这条汇编语句,编译器应该如何处理呢?
- 应该怎样处理 immediate 部分
- 应该选择哪条 mov 指令
- operand size 是多少
- 在 32 位环境下,如何生成 16 位 operand 或 address 的代码
- 寻址模式是什么
这些问题是我们最终需要掌握的知识,这是本栏目的最终目的。
实际上,它最终形成的机器编码是:26 66 c7 84 c8 44 33 22 11 78 56
(1)dword 大小的源操作数,会被编译器截断为 word 大小
(2)选择 MOV Ev, Iz 指令,它的 opcode 是 C7
(3)它的 operand size 是 word 大小,取决于 first operand 的 size
(4)在 32 位下,通过使用 operand size override 可以造型为 16 位 operands size,使用 address size override 可以造型为 16 位 address size
(5)它的寻址模式是:基址+变址寻址,它需要提供 SIB 字节
下面的图直观的分解这条指令的组成部分:
image.png26:在指令序列里是:prefix 部分,它是 semgent overrride prefix ,作用是调整内存操作数的段选择子
66:在指令序列里是:prefix 部分,它是 operand size override prefix ,作用是调整操作数的缺省大小
C7:在指令序列里是:Opcode 部分,是 mov 指令是操作码
84:在指令序列里是:ModRM 值,定义操作数的属性
C8:在指令序列里:SIB 值定义内存操作数的属性
44332211:在指令序列里是: displacement 值
7856:在指令序列里是:immediate 值
这 2 个例子,作为对学习 x86/x64 指令编码的一个感性认识。
网友评论