操作数寻址(operand addressing)

操作数寻址(operand addressing)

x86 机器指令可以有0或多个操作数,一些操作数显式指出,其他则隐式指出。

源操作数(source operand)可以放在如下地方:

  • 指令本身(立即数)
  • 寄存器
  • 内存
  • I/O端口

目标操作数(destination operand)

  • 寄存器
  • 内存
  • I/O端口

1、立即数(Immediate Operands)

一些指令的源操作数被编码在指令当中,这些操作数被称为立即数( immediate operands 或 immediates)。
例如:

83 C0 0E       对应汇编指令:add eax, 14

显然14的十六进制表示为 0E,被编码在机器指令中。

所有的算术指令(除了 DIVIDIV 指令)允许源操作数是立即数。
立即数所允许的最大值因指令而异,但决不能大于无符号32位整数的最大值(2^32)。

2、寄存器操作数(Register Operands)

源操作数和目标操作数可以是下面这些寄存器:

  • 32位通用寄存器(EAX, EBX,ECX,EDX,ESI,EDI,ESP,EBP
  • 16位通用寄存器(AX, BX,CX,DX,SI,DI,SP,BP
  • 8位通用寄存器(AH, BH,CH,DH,AL,BL,CL,DL
  • 段寄存器 (CS, DS, SS, ES, FS, GS)
  • EFLAGS 寄存器
  • x87 FPU 寄存器 (ST0 ~ ST7, status word, control word, tag word, data operand pointer, and instruction pointer)
  • MMX 寄存器 (MM0 ~ MM7)
  • XMM 寄存器 (XMM0 through XMM7)MXCSR 寄存器
  • control registers(CR0, CR2, CR3, CR4)system table pointer registers (GDTR, LDTR, IDTR, and task register)
  • debug registers (DR0, DR1, DR2, DR3, DR6, and DR7)
  • MSR 寄存器

某些指令(例如 DIVMUL 指令)使用64位操作数,这个64位操作数存放在一对32位寄存器中。 这对寄存器用冒号分隔它们来表示这个64位操作数。 例如,在寄存器对 EDX:EAX 中,EDX 存放64位操作数的高32位,而 EAX 存放64位操作数的低32位。

一些指令(例如 PUSHFDPOPFD 指令)用来 load 和 store EFLAGS 寄存器的内容,或者设置或清除该寄存器中的各个标志。 其他指令(例如 Jcc 指令)使用 EFLAGS 寄存器中的状态标志作为分支或其他操作的条件码。

处理器包含一系列系统寄存器,用于控制内存管理、中断和异常处理、任务管理、处理器管理和调试活动。 其中一些系统寄存器可由应用程序、操作系统或一组系统指令访问。 当使用系统指令访问系统寄存器时,寄存器通常是指令的隐含操作数。

2.1、64位模式下的寄存器操作数(Register Operands in 64-Bit Mode)

  • 64位通用寄存器 (RAX, RBX, RCX, RDX, RSI, RDI, RSP, RBP, 或 R8 - R15)
  • 32位通用寄存器 (EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP, 或 R8D - R15D)
  • 16位通用寄存器 (AX, BX, CX, DX, SI, DI, SP, BP, 或 R8W - R15W)
  • 8位通用寄存器:AL, BL, CL, DL, SIL, DIL, SPL, BPL, and R8B-R15B are available using REX prefixes; AL, BL, CL, DL, AH, BH, CH, DH are available without using REX prefixes.
  • 段寄存器 (CS, DS, SS, ES, FS, 和 GS)
  • RFLAGS 寄存器
  • x87 FPU 寄存器 (ST0 ~ ST7, status word, control word, tag word, data operand pointer, and instruction pointer)
  • MMX 寄存器 (MM0 ~ MM7)
  • XMM 寄存器 (XMM0 through XMM15)MXCSR 寄存器
  • control registers(CR0, CR2, CR3, CR4, 和 CR8)system table pointer registers (GDTR, LDTR, IDTR, and task register)
  • debug registers (DR0, DR1, DR2, DR3, DR6, and DR7)
  • MSR 寄存器
  • RDX:RAX 寄存器对 表示一个128位操作数

下图显示了64位下完整可用的通用寄存器:20个8位寄存器,16个16位、32位及64位寄存器。
在这里插入图片描述

3、内存操作数(Memory Operands)

我们使用 段选择子(segment selector)和 偏移量(offset)引用内存中的源操作数和目标操作数。
(看图 3-9)段选择子指定操作数所在的段,偏移量指定操作数的线性地址或有效地址。偏移量可以是 32位(用 m16:32 表示)或 16位(用 m16:16 表示)。
在这里插入图片描述

3.1、64位模式下的内存操作数(Memory Operands in 64-Bit Mode)

在64位模式下,一个内存操作数可以被一个段选择子和一个偏移量引用。这个偏移量可以是 16位32位64位(看图 3-10)。
在这里插入图片描述

4、指定一个段选择子(Specifying a Segment Selector)

可以隐式或显式指定段选择子。 指定段选择子的最常用方法是将其加载到段寄存器中,然后允许处理器根据正在执行的操作类型隐式选择寄存器。 处理器根据表 3-5 中给出的规则自动选择一个段。

往内存中存数据或从内存取数据时,可以覆盖 DS 段默认值以允许访问其他段。 在汇编程序中,段覆盖通常用 “冒号 :” 操作符处理。 例如,下面的 MOV 指令将寄存器 EAX 中的值移动到 ES 寄存器指向的段中。 段中的偏移量包含在 EBX 寄存器中:

MOV ES:[EBX], EA

在这里插入图片描述
在机器级别,段覆盖是用段覆盖前缀(segment-override prefix)指定的,它是放置在指令开头的一个字节。 以下默认的段选择子不能被覆盖:

  • 必须从代码段中取指令。
  • 字符串指令中的目标字符串必须存储在 ES 寄存器指向的数据段中。
  • Pushpop 操作必须始终引用 SS 段。

某些指令要求明确指定段选择子。 在这些情况,16位段选择子可以位于内存16位寄存器中。 例如,以下 MOV 指令将位于寄存器 BX 中的段选择子移动到段寄存器 DS

MOV DS, BX

段选择子也可以明确指定为内存中48 位远指针的一部分。 这里,内存中的第一个双字(doubleword 32位)是偏移量,下一个字(word 16位)是段选择子。

4.1、64位模式下的分段(Segmentation in 64-Bit Mode)

在 IA-32e 模式下,分段的效果取决于处理器是在兼容模式还是 64 位模式下运行。 在兼容模式下,分段功能就像在传统 IA-32 模式下一样,使用上述 16 位或 32 位保护模式语义。
在 64 位模式下,分段通常(但不是完全)被禁用,从而创建一个平坦的 64 位线性地址空间处理器将 CSDSESSS 的段基址视为零,创建一个等于有效地址的线性地址。 FSGS 段除外,它们的段寄存器(保存段基址)可用作某些线性地址计算中的附加基址寄存器。

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:

  • Displacement — An 8-, 16-, or 32-bit value.
  • Base — The value in a general-purpose register.
  • Index — The value in a general-purpose register.
  • Scale factor — A value of 2, 4, or 8 that is multiplied by the index value.
    由这些组件组合计算而成的 offset 称为有效地址。除了 scale factor 之外,每一个组件都可以具有正值或负值(补码)。 图 3-11 显示了可以组合这些组件以在所选段中创建有效地址的所有可能方式。
    在这里插入图片描述

将通用寄存器用作 baseindex 有以下限制:

  • ESP 寄存器不能用作 index 寄存器。
  • ESPEBP 寄存器用作 base 时,SS 段为默认段。 在所有其他情况下,DS 段是默认段。

baseindexdisplacement 可以任意组合,并且这些组件中的任何一个都可以为 NULL。 仅当使用 index 时才可以使用 scale factor。 每种可能的组合对于高级语言和汇编语言中常用的数据结构都很有用。

以下寻址模式展示了地址组件的常见组合。

  • Displacement ⎯ 单独使用 displacement* 表示一个直接(无需计算)的操作数 offset。因为 displacement 是被编码在指令中,所以这种形式的地址有时称为 绝对地址静态地址。它通常用于访问静态分配的标量操作数。

  • Base ⎯ 单独使用 base 表示一个间接的操作数 offset。由于base 寄存器中的值是可以改变的,因此可以用于变量和数据结构的动态存储。

  • Base + Displacementbase 寄存器和 displacement 可一起使用,主要有两个目的:

    • As an index into an array when the element size is not 2, 4, or 8 bytes — The displacement component encodes the static offset to the beginning of the array. The base register holds the results of a calculation to determine the offset to a specific element within the array.(displacement = 数组起始地址,base 寄存器 = 下标 * 元素大小)
    • To access a field of a record: the base register holds the address of the beginning of the record, while the displacement is a static offset to the field.

    An important special case of this combination is access to parameters in a procedure activation record. A procedure activation record is the stack frame created when a procedure is entered. Here, the EBP register is the best choice for the base register, because it automatically selects the stack segment. This is a compact encoding for this common function.(不清楚函数调用栈机制的,网上有很多相关资料)。

  • (Index ∗ Scale) + Displacement ⎯ This address mode offers an efficient way to index into a static array when the element size is 2, 4, or 8 bytes. The displacement locates the beginning of the array, the index
    register holds the subscript of the desired array element, and the processor automatically converts the subscript into an index by applying the scaling factor.

  • Base + Index + Displacement ⎯ Using two registers together supports either a two-dimensional array (the displacement holds the address of the beginning of the array) or one of several instances of an array of records (the displacement is an offset to a field within the record).

  • Base + (Index ∗ Scale) + Displacement ⎯ Using all the addressing components together allows efficient indexing of a two-dimensional array(2维数组) when the elements of the array are 2, 4, or 8 bytes in size.

5.1、64位模式下指定 offset(Specifying an Offset in 64-Bit Mode)

The offset part of a memory address in 64-bit mode can be specified directly as a static value or through an address computation made up of one or more of the following components:

  • Displacement — An 8-bit, 16-bit, or 32-bit value.

  • Base — The value in a 64-bit general-purpose register.

  • Index — The value in a 64-bit general-purpose register.

  • Scale factor — A value of 2, 4, or 8 that is multiplied by the index value.

    The base and index value can be specified in one of sixteen available general-purpose registers in most cases. See Chapter 2, “Instruction Format,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A.

The following unique combination of address components is also available.

  • RIP + Displacement ⎯ In 64-bit mode, RIP-relative addressing(RIP相对寻址) uses a signed 32-bit displacement to calculate the effective address of the next instruction by sign-extend the 32-bit value and add to the 64-bit value in RIP.

6、汇编器和编译器寻址模式(Assembler and Compiler Addressing Modes)

At the machine-code level, the selected combination of displacement, base register, index register, and scale factor is encoded in an instruction. All assemblers permit a programmer to use any of the allowable combinations of these addressing components to address operands. High-level language compilers will select an appropriate combination of these components based on the language construct a programmer defines.

7、I/O端口寻址

处理器支持包含多达 65,536 个 8 位 I/O 端口的 I/O 地址空间。 也可以在 I/O 地址空间中定义 16 位和 32 位端口。 I/O 端口可以通过立即数或 DX 寄存器中的值进行寻址。 有关 I/O 端口寻址的更多信息,可以参见 intel 手册第 19 章“输入/输出”。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值