x86指令编码(硬编码)的结构
可以看到前缀指令的说明有一个小括号里面写的optional,表示可以有,也可以没有。
如何判断某个指令是前缀指令还是后面的opcode?
- CPU判断某个指令是否是前缀指令还是opcode,是根据当前指令的内容判断的。
- 当前指令如果是55,那就是opcode。
- 如果当前指令值是66,无论后面是什么,那就是前缀指令。
- 判断是否是前缀指令是根据当前指令它本身的内容来判断的。
- 前缀指令是有限的。
- 前缀指令最多4个,最少0个。
前缀指令是分组的
前缀指令 | 硬编码 | 分组 | 作用 |
---|---|---|---|
LOCK | F0 | LOCK 和 REPEAT 前缀指令 | 锁地址总线。 例如0x00412345地址,在前面加上LOCK的话。 如果有多个CPU来执行,在某一个时刻,只能有一个核的CPU才能读这个地址,其他核CPU不能读这个地址。 该指令在多核下才有意义。 |
REPNE/REPNZ | F2 | LOCK 和 REPEAT 前缀指令 | 重复执行。当eFlag寄存器中的ZeroFlag为0时,才执行。 |
REP/REPZ | F3 | LOCK 和 REPEAT 前缀指令 | 重复执行。当eFlag寄存器中的ZeroFlag为1时,才执行。 |
CS | 2E | 段前缀指令 | 段寄存器,明确告诉CPU使用哪个段。 读写内存,涉及到内存地址时,如果没有特殊的提示或指令,那么默认的段寄存器都是DS段寄存器。 如果涉及到ESP或EBP,默认的是SS段寄存器。 |
SS | 36 | 段前缀指令 | 段寄存器,明确告诉CPU使用哪个段。 读写内存,涉及到内存地址时,如果没有特殊的提示或指令,那么默认的段寄存器都是DS段寄存器。 如果涉及到ESP或EBP,默认的是SS段寄存器。 |
DS | 3E | 段前缀指令 | 段寄存器,明确告诉CPU使用哪个段。 读写内存,涉及到内存地址时,如果没有特殊的提示或指令,那么默认的段寄存器都是DS段寄存器。 如果涉及到ESP或EBP,默认的是SS段寄存器。 |
ES | 26 | 段前缀指令 | 段寄存器,明确告诉CPU使用哪个段。 读写内存,涉及到内存地址时,如果没有特殊的提示或指令,那么默认的段寄存器都是DS段寄存器。 如果涉及到ESP或EBP,默认的是SS段寄存器。 |
FS | 64 | 段前缀指令 | 段寄存器,明确告诉CPU使用哪个段。 读写内存,涉及到内存地址时,如果没有特殊的提示或指令,那么默认的段寄存器都是DS段寄存器。 如果涉及到ESP或EBP,默认的是SS段寄存器。 |
GS | 65 | 段前缀指令 | 段寄存器,明确告诉CPU使用哪个段。 读写内存,涉及到内存地址时,如果没有特殊的提示或指令,那么默认的段寄存器都是DS段寄存器。 如果涉及到ESP或EBP,默认的是SS段寄存器。 |
66 | 操作数宽度前缀指令 | 改变默认操作数宽度。例如在32位模式下使用16位操作数,在16位模式下使用32位操作数。 | |
67 | 地址宽度前缀指令 | 改变默认寻址方式。例如在32位模式下使用16位寻址方式,在16位模式下使用32位寻址方式。 |