x86 / x64添加位移寻址

时间:2012-11-11 08:17:37

标签: assembly x86 64-bit

我正在为x86 / x64 CPU指令编写一个编译器,我似乎无法弄清楚“置换”地址的含义。例如,这里详细说明了Add指令: http://www.c-jump.com/CIS77/CPU/x86/X77_0150_encoding_add_edx_displacement.htm

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

3 个答案:

答案 0 :(得分:10)

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

  1. [条]
  2. [reg + displacement]
  3. [位移]
  4. [reg * constant + reg]
  5. [reg * constant + reg + displacement]
  6. “displa”只是一个常量,会被添加到地址的其余部分。如果除了常量之外没有地址的组成部分,它仍称为“位移​​”。这主要是为了与其他寻址形式保持一致。

    另一种看待它的方法是所有地址都是

    形式

    [reg * constant + reg + displacement]

    每个组件允许值为0。

    [displacement]形式只是编码,其中除位移之外的所有组件都为零。

    作为编译器编写者,最后两种形式特别有趣。它们可以轻松地在单个指令中对pArray[index]->field + 1之类的内容进行编码。

答案 1 :(得分:4)

没有“特殊添加占用位移”,该页面不必要地混淆 - 这只是普通内存操作数编码的一部分。

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

这只是add r/m, r的特例,其中add r, r/m采用置换形式:请参阅ModRM encoding的注释#1。

所以他们只是指r/m。 (但他们错误编码了注册字段,add edx, [sdword]对应edx,而不是010

答案 2 :(得分:4)

该页面不准确。它正在讨论的“添加取一个位移”指的是add r[16|32], r/m[16|32]add edx, [0xdisp]形式,因为您可能会在反汇编程序的输出中看到它。假设它正在讨论带有操作码0x03的ADD指令,

  • edx寄存器目的地进行编码并将32位位移指定为ModR / M字节中的有效地址将使其值为0x15(请参阅英特尔®64和IA-32架构软件开发人员手册第2卷,第41页,表2-2)。
  • 此说明的效果是将内存地址disp的dword添加到edx的内容。
  • 因此,指令的实际编码为:\x03\x15\x00\x00\x00\x01,位移为1个字节。