我想制作汇编编译器。为此,我应该对Assembly操作码进行研究,所以我在网上找到了这个。当我测试用NASM编译一些代码时,像这样:
add eax, eax
它在Binary上输出:
6601C0
但是,当我看到Assembly Opcodes的参考时,它会显示以下屏幕:
其中ADD操作码为00,01,02,03,04,05。 哪种操作码是对的?我可以使用所有这些,还是应该使用01(基于使用NASM编译的二进制文件)。
答案 0 :(得分:4)
您找到的只是互联网上某人的一些参考。 权威参考来自英特尔,可在此处下载:Intel® 64 and IA-32 Architectures Software Developer Manuals。
您显然已经为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”(英特尔:“r / m32,r32”)。英特尔称其为“ModR / M”字节。该字节中的一些位定义目标(“Ev”),一些位定义源(“Gv”)。请参阅英特尔手册中的“表2-1。带ModR / M字节的16位寻址表”表。
回答您的问题:不,您必须针对特定目的使用特定的ADD
指令。 ADD
指令执行不同的操作。