好的,所以我通读了 AMD64 手册并且知道这nop
确实是一个xchg eax, eax
,我查看了xchg
并且发现了一些有趣的东西,似乎一个字节可以被编码到用于指定寄存器的指令中(抱歉我在我的 iPod 上):图片。
所以我想知道的是处理器如何知道后面是否有一个字节可以使用,或者额外的寄存器是否必须是某种类型,rAX
导致它实际上仍然是一个字节0x90
答案1
我查看了 xchg,发现了一些有趣的东西,似乎可以将一个字节编码到指定寄存器的指令中
是的,大多数 x86 指令都是这样工作的。指令每次以 32 位或 64 位(机器的字长)为单位获取,而不是每次以字节为单位获取。
指定XCHG
的(其中在 32 位机器上为,在 64 位机器上为 )将是,因为 的寄存器多路复用代码是(实际上是一个不执行任何操作的单周期操作)。类似地,指令将汇编为(rAX
的多路复用代码是)。rAX
rAX
EAX
RAX
0x90
rAX
0x00
XCHG rBX, rAX
0x93
rBX
0b011
操作码编码应该列在手册的其他地方,或者你可以查看 x86 操作码映射(这有助于理解所有内容是如何混合在一起的)。你可以在Intel 64 和 IA-32 架构软件开发人员手册(第 2 卷,附录 A.3)。
所以我想知道的是处理器如何知道后面是否有一个字节可以使用,或者那个额外的寄存器必须是 rAX 类型,导致它实际上仍然是一个字节 0x90
这里则相反。对于 64 位模式,实际上有一个字首在指令字本身中表示(REX
前缀)。处理器根据前缀的存在与否知道要查找什么REX
- 而如果没有前缀,指令仍然只是0x90
。