关于 [base + index*scale + disp] 的几个问题 [英] A couple of questions about [base + index*scale + disp]

查看:26
本文介绍了关于 [base + index*scale + disp] 的几个问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The general form for memory addressing in Intel and AT&T Syntax is the following:

[base + index*scale + disp]
disp(base, index, scale)

我的问题如下:

  • baseindex 可以是任意寄存器吗?
  • scale 可以取什么值,是 1、2、4 和 8(1 是默认值)?
  • indexdisp 是否可以互换(唯一的区别是 index 是一个寄存器,而 disp 是立即值)?
  • Can base and index be any register?
  • What values can scale take, is it 1, 2, 4 and 8 (with 1 being the default)?
  • Are index and disp interchangeable (with the only difference being that index is a register while disp is an immediate value)?

推荐答案

这在 Intel 的手册中有描述:

This is described in Intel's manual:

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

3.7.5 Specifying an Offset
The offset part of a memory address can be specified directly as a static value (called a displacement) or through an address computation made up of one or more of the following components:

  • 位移 — 8 位、16 位或 32 位值.
  • Base — 通用寄存器中的值.
  • 索引 — 通用寄存器中的值.[不能是 ESP/RSP]
  • 比例因子 - 乘以索引值的 2、4 或 8 值.
  • Displacement — An 8-, 16-, or 32-bit value.
  • Base — The value in a general-purpose register.
  • Index — The value in a general-purpose register. [can't be ESP/RSP]
  • Scale factor — A value of 2, 4, or 8 that is multiplied by the index value.

添加这些组件所产生的偏移量称为有效地址.

The offset which results from adding these components is called an effective address.

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

The scale-factor is encoded as a 2-bit shift count (0,1,2,3), for scale factors of 1, 2, 4, or 8. And yes, *1 (shift count = 0) is the default if you write (%edi, %edx); that's equivalent to (%edi, %edx, 1)

在 AT&T 语法中,它是 disp(base, index, scale) - 常量在括号之外.一些 Intel 语法汇编器也允许像 1234[ebx] 这样的语法,其他的则不允许.但是 AT&T 语法很严格;寻址模式的每个组成部分都可以进入其适当的位置.例如:

In AT&T syntax, it's disp(base, index, scale) - constants go outside the parens. Some Intel-syntax assemblers also allow syntax like 1234[ebx], others don't. But AT&T syntax is rigid; every component of the addressing mode can only go in its proper place. For example:

movzwl  foo-0x10(,%edx,2), %eax

从地址 foo-0x10 + edx*2 将零扩展 16 位(字")加载到 EAX 中.EDX 是索引寄存器,比例因子为 2.没有基址寄存器.foo-0x10 都是位移的一部分,都是链接时间常数.foo 是链接器将填充的符号地址并从中减去 0x10(因为 -0x10 汇编时间偏移).

does a zero-extending 16-bit ("word") load into EAX, from the address foo-0x10 + edx*2. EDX is the index register, with scale-factor 2. There is no base register. foo and -0x10 are both part of the displacement, both link-time constants. foo is a symbol address that the linker will fill in and subtract 0x10 from (because of the -0x10 assemble-time offset).

如果可以选择,请仅使用基数而不是标度为 1 的索引.索引需要一个 SIB 字节进行编码,从而使指令更长.这就是为什么编译器选择像 8(%ebp) 这样的寻址模式来访问堆栈内存,而不是 8(,%ebp).

If you have the choice, use just a base instead of an index with a scale of 1. An index requires a SIB byte to encode, making the instruction longer. That's why compilers choose addressing modes like 8(%ebp) to access stack memory, not 8(,%ebp).

另见 引用内存位置的内容.(x86 寻址模式) 详细了解何时可以使用基数、和/或索引和/或位移.

See also Referencing the contents of a memory location. (x86 addressing modes) for more about when you might use a base, and/or index, and/or displacement.

16 位位移只能在 16 位寻址模式下编码,该模式使用 不同的格式,不能包含比例因子,并且具有非常有限选择哪些寄存器可以是基址或索引.

A 16-bit displacement is only encodeable in a 16-bit addressing mode, which uses a different format that can't include a scale factor, and has a very limited selection of which registers can be a base or index.

因此,像 1234(%edx) 这样的模式必须在 32 位机器代码中将 1234 编码为 32 位 disp32.

So a mode like 1234(%edx) would have to encode the 1234 as a 32-bit disp32 in 32-bit machine code.

从 -128 到 +127 的字节偏移量可以使用短格式的 8 位编码.您的汇编程序会为您处理这个问题,使用最短的有效位移编码.

Byte offsets from -128 .. +127 can use a short-form 8-bit encoding. Your assembler will take care of this for you, using the shortest valid encoding for the displacement.

所有这些在 64 位模式下对于 64 位寻址模式都是相同的,disp32 也像 disp8 一样被符号扩展到 64 位.

All of this is identical in 64-bit mode for 64-bit addressing modes, with disp32 also being sign-extended to 64-bit just like disp8.

这篇关于关于 [base + index*scale + disp] 的几个问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆