如何阅读汇编指令参考?

3

我希望制作一个汇编语言编译器。为了达到这个目的,我需要研究汇编指令集,于是我在网上找到了以下信息。当我尝试使用NASM编译一些代码时,像这样:

add eax, eax

它在二进制上输出如下内容:
6601C0
但是,当我查看汇编操作码参考时,显示出以下屏幕: Snapshot 其中ADD操作码为00、01、02、03、04、05。 哪个操作码是正确的?我可以使用所有的操作码吗,还是应该使用01(基于NASM编译的二进制文件)?

1
你需要使用与操作数匹配的操作码。你应该下载英特尔手册并阅读前两卷,特别是第二卷,其中包含有关指令如何编码的所有细节。 - Ross Ridge
1个回答

7
您发现的只是一些互联网上某人汇总的参考资料。权威参考资料来自英特尔,可以在此处下载:Intel® 64 和 IA-32 架构软件开发手册
显然,您已经将代码组装到了16位实模式环境(如DOS),其中被组装为66 01 C0
  1. 观察第一个字节66。这被英特尔称为“操作数大小覆盖前缀”,在您的参考文献中称为“OPSIZE”。它将操作数从16位更改为32位(从AXEAX)。这就是我猜测环境是16位系统的原因。

  2. 第二个字节01是您参考文献中的ADD指令,在第一行的第二个位置。您的参考文献将其称为ADD Ev Gv。英特尔手册将其称为ADD r/m16, r16。使用操作数大小覆盖前缀,您可以将其读作ADD r/m32, r32

  3. 第三个字节C0是您参考文献中的“Ev Gv”(英特尔:“r/m32,r32”)。英特尔将其称为“ModR/M”字节。该字节中的某些位定义目标(“Ev”),某些位定义源(“Gv”)。请查看英特尔手册中的“表2-1.带有ModR/M字节的16位寻址形式”。

回答您的问题:不,您必须针对特定目的使用特定的ADD指令。 ADD指令执行不同的操作。

那么 EvGv 和 GvEv 有什么区别?请向我解释一下。 - Dana Prakoso
@DanaPrakoso:定义什么是源,什么是目标。首字母缩写为目标,第二个是源。这些缩写应该在您的参考资料中解释清楚。 - rkhb
我以前从来没有见过这种 Ev、Gv 等符号表示法。这看起来像是由该特定参考文献发明的,这是一个不好且令人困惑的选择。我不清楚为什么他们没有遵循英特尔文档中使用的标准符号表示法,就像你在你的答案中提到的那样。 - Cody Gray
感谢rkhb和Cody Gray,也许我应该重新阅读手册以理解它们。 - Dana Prakoso
1
@CodyGray:我以前从未见过这种 Ev、Gv 等符号表示法 - 请查看英特尔手册第2B卷中的“表A-2 单字节操作码映射”。感谢您纠正我的糟糕英语 :-) - rkhb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接