8

我正在为 x86/x64 CPU 指令编写编译器,但我似乎无法弄清楚人们所说的“位移”地址是什么意思。例如此处详细介绍了添加指令: http ://www.c-jump.com/CIS77/CPU/x86/X77_0150_encoding_add_edx_displacement.htm

我只是想实现将寄存器添加到正常内存地址的添加指令。问题是,该地址是一个“位移地址”。这是否意味着地址是一个有符号值,它是指令位置的偏移量?

4

3 回答 3

13

x86 中有几种不同形式的间接操作数:

  1. [注册]
  2. [注册+位移]
  3. [移位]
  4. [reg * 常量 + reg]
  5. [reg * 常数 + reg + 位移]

“位移”只是添加到地址其余部分的常数。如果地址中除了常量之外没有任何分量,它仍然被称为“位移​​”。这主要是为了与其他寻址形式保持一致。

另一种看待它的方式是所有地址的形式

[reg * 常数 + reg + 位移]

每个组件都允许值为 0。

[位移] 形式只是位移以外的所有分量都为零的编码。

作为编译器作者,最后两种形式特别有趣。pArray[index]->field + 1它们使在单个指令中编码事物变得容易。

于 2012-11-11T11:19:02.110 回答
4

没有“需要位移的特殊添加”,该页面不必要地令人困惑 - 这只是正常内存操作数编码的一部分。

add是一条相当标准的指令,其编码方式与所有 alu-ops 相同:有一种特殊情况,使用al作为目标和立即数作为源(04 ib),使用ax/eax/rax作为目标和立即数作为源(+ 05 imm),三个版本add r/m, imm(一个用于 8 位目标,一个用于更广泛的目标和一个符号扩展的 8 位源,一个用于更广泛的目标和一个宽源),当然还有一个add r, r/mand add r/m, r

这只是 的一种特殊情况add r, r/m,其中采用位移的形式:参见ModRM encodingr/m的注释 #1 。

所以他们的意思是add edx, [sdword]。(但他们对 reg 字段进行了错误编码,edx对应于010,而不是011

于 2012-11-11T09:13:50.190 回答
4

该页面不准确。它所说的“进行位移的添加”是指形式add r[16|32], r/m[16|32],或者add edx, [0xdisp]您可能在反汇编程序的输出中看到它。假设它正在谈论带有 opcode 的 ADD 指令0x03

  • 对寄存器目标进行编码edx并在 ModR/M 字节中指定一个 32 位位移作为有效地址,将得到 0x15 的值(请参阅英特尔® 64 和 IA-32 架构软件开发人员手册第 2 卷,第 41 页,表2-2)。
  • 该指令的作用是将内存地址处的 dword 添加dispedx.
  • 因此,指令的实际编码将是:\x03\x15\x00\x00\x00\x01,对于 1 个字节的位移。
于 2012-11-11T10:32:45.253 回答