Dan*_*oso 3 x86 assembly machine-code opcode instruction-encoding
我想做汇编编译器。为此,我应该研究汇编操作码,所以我在网上找到了这个。当我测试用 NASM 编译一些代码时,如下所示:
add eax, eax
Run Code Online (Sandbox Code Playgroud)
它以二进制输出:
6601C0
其中 ADD 操作码是 00, 01, 02, 03, 04, 05。哪个操作码是正确的?我可以使用所有这些,还是应该使用 01(基于使用 NASM 编译的二进制文件)。
您找到的只是互联网上某人整理的一些参考资料。权威参考来自Intel,可以在这里下载:Intel\xc2\xae 64 and IA-32 Architectures Software Developer Manuals。
\n\n显然,您为 16 位实模式环境(如 DOS)汇编了代码,它被汇编为66
01
C0
.
看第一个字节66
。这被英特尔称为“操作数大小覆盖前缀”,在您的参考文献中称为“OPSIZE”。它将操作数的大小从 16 位更改为 32 位 (AX
到EAX
)。这就是为什么我猜测环境是16位系统。
第二个字节01
是ADD
参考文献中第一行第二个位置的指令。您的参考文献称其为ADD Ev Gv
。英特尔手册称其为ADD r/m16, r16
。使用操作数大小覆盖前缀,您可以将其读作ADD r/m32, r32
.
第三个字节C0
是您参考中的“Ev Gv”(Intel:“r/m32,r32”)。英特尔称其为“ModR/M”字节。该字节中的一些位定义目标(“Ev”),一些位定义源(“Gv”)。请参阅Intel 手册中的表“表 2-1. ModR/M 字节的 16 位寻址形式”。
回答您的问题:不可以,您必须ADD
针对特定目的使用特定指令。这些ADD
指令执行不同的操作。