关于[base + index*scale + disp]的几个问题

7 x86 assembly att intel-syntax addressing-mode

英特尔和AT&T语法中内存寻址的一般形式如下:

[base + index*scale + disp]
disp(base, index, scale)
Run Code Online (Sandbox Code Playgroud)

我的问题如下:

  • 可以baseindex任意注册?
  • 可以scale采用什么值,是1,2,4和8(默认值为1)?
  • indexdisp可互换的(唯一的区别index是寄存器disp是一个常数)?

Mic*_*ael 6

英特尔手册对此进行了描述:

3.7.5指定偏移
量可以直接将内存地址的偏移量部分指定为静态值(称为位移),也可以通过由以下一项或多项组成的地址计算来指定:

  • 位移-8位,16位或32位值。
  • 基本 —通用寄存器中的值。
  • 索引 —通用寄存器中的值。[不能是ESP / RSP]
  • 比例因子-2、4或8的值乘以索引值。

由添加这些分量导致的偏移量称为有效地址。

对于1、2、4或8的比例因子,比例因子被编码为2位移位计数(0、1、2、3)。是的,*1如果您选择(移位计数= 0),则默认为写(%edi, %edx); 相当于(%edi, %edx, 1)


16位位移只能在16位寻址模式下进行编码,该寻址模式使用的格式不能包含比例因子,并且只能选择哪些寄存器可以作为基址或索引。因此,类似的模式1234(%edx)必须将1234符号扩展disp32为机器代码中的32位。

从-128 .. +127的字节偏移量可以使用简短的8位编码。汇编程序将使用最短的有效位移编码为您解决此问题。


对于64位寻址模式,所有这些在64位模式下都是相同的。

  • 让我们再说一句* base *和* index *之间的细微差别:当EBP或ESP用作* base *寄存器时,默认段为SS,否则为DS。MOV EAX,[EDI + EBP]从数据段加载EAX,而MOV EAX,[EBP + EDI]从堆栈段加载。不过,在Window平面模型中这并不重要,因为DS和SS都包含相同的段描述符。 (2认同)