操作数寻址(operand addressing)

2024-03-12 07:40

本文主要是介绍操作数寻址(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 章“输入/输出”。

这篇关于操作数寻址(operand addressing)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/800565

相关文章

将 x 减到 0 的最小操作数

题目简介:        给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。 算法思路:         通过上面的三个示例,我们可以看出如果直接从正面入手解题,那么我们该如何确定

将x减到零的最小操作数问题

欢迎跳转我的主页:羑悻的小杀马特-CSDN博客 目录 一·题目简述: 二·题目思路: 三·解答代码: 一·题目简述: leetcode题目链接:. - 力扣(LeetCode)  二·题目思路: 首先这道题,可能如果直接正面从最左最右开始找数值之和为x,这样看起来比较散,而我们不难发现中间肯定会有一段连续的区域,因此leetcode这道题肯定想让我们

【滑动窗口】将 x 减到 0 的最小操作数

将 x 减到 0 的最小操作数 将 x 减到 0 的最小操作数题目思路讲解代码书写 将 x 减到 0 的最小操作数 题目 题目链接: 将 x 减到 0 的最小操作数 思路讲解 按照题目的思路去做这一题是非常恶心的, 因此我们采用正难则反思路. 将问题转换为: 求中间某一个最长的数组长度, 使其和为sum - x, 其中 sum 是数组中所有数的总和 那么此时这个题目就被

【软件逆向】第30课,软件逆向安全工程师之(五)寄存器相对寻址,每天5分钟学习逆向吧!

寄存器相对寻址是汇编语言中的一种寻址方式,它结合了寄存器间接寻址和立即数偏移。在这种寻址方式中,操作数的有效地址是通过将一个寄存器的内容与一个固定的偏移量(立即数)相加来得到的。以下是关于寄存器相对寻址的详细信息: 寄存器相对寻址的特点: 操作数地址是寄存器内容与偏移量的和:有效地址是寄存器的内容加上一个固定的立即数偏移量。灵活且具体:提供了对特定内存位置的间接访问,同时允许通过改变寄存器的内

【软件逆向】第27课,软件逆向安全工程师之(二)寄存器寻址,每天5分钟学习逆向吧!

寄存器寻址是汇编语言中的一种寻址方式,在这种方式中,操作数位于CPU的寄存器中。寄存器是CPU内部的高速存储位置,用于快速访问数据。以下是关于寄存器寻址的详细信息: 寄存器寻址的特点: 操作数在寄存器中:数据直接存储在寄存器中,而不是内存地址或立即数。快速访问:由于寄存器位于CPU内部,因此访问速度远快于内存。指令简短:使用寄存器寻址的指令通常较短,因为不需要指定内存地址。 识别寄存器寻址:

32位操作系统寻址范围与支持的最大内存空间

32位的操作系统能够寻址的地址编号范围是1到2的32次方,而每一个地址都是指的内存中一个字节的地址,所以32位操作系统能够支持访问的的最大内存空间是2的32次方字节,也就是4G的内存空间,根据自己的理解,自己画了张图如下: 一个内存地址代表一个字节的地址不是一bit的地址 背景知识: 在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。

寄存器、寻址、一些问题的解释。

****************************************************************************************************************************************************寄存器,内存.存储器举报|2009-08-28 14:28若_水儿 | 分类:网站使用 | 浏览1252

HBASE的寻址机制和存储机制

HBASE的寻址机制和存储机制 hbase的寻址机制hbase的存储机制hbase的存储机制:0.96及之前版本hbase的寻址过程:0.96及之前版本hbase的存储机制:0.96之后版本hbase的寻址过程:0.96之后版本写机制读机制 hbase的寻址机制 hbase 的一个表最终拆分成 一个个region,每一个region可能会存储在不同的regionserver

【计算机组成原理】四、指令系统:2.指令的寻址方式(指令寻址、数据寻址)

指令的寻址方式 文章目录 指令的寻址方式3.指令寻址3.1顺序寻址3.2跳跃寻址 4.数据寻址4.1直接寻址4.2间接寻址4.3寄存器寻址4.4寄存器间接寻址4.5隐含寻址4.6立即寻址4.7偏移寻址4.7.1基址寻址4.7.2变址寻址4.7.3相对寻址 4.8堆栈寻址 3.指令寻址 指令寻址:确定下一条指令存放的地址。 程序计数器PC:指明一条指令的存放地址。 【注意

磁盘IO单线程顺序写时最快的,如果多线程写,磁盘的磁头要不断重新寻址,所以写入速度反而会慢

(1) 读写最好还是不要多线程,硬盘读写的速度有限,单线程时已经满负荷了,多线程又会增加线程之间的切换,会增加时间。            如果想增加读写速度,应该增加硬盘,做raid (2)首先是硬盘的写入是串行的,CPU的计算才是并行的,如果你偏重计算那么多线程能提高,要不怎么叫做并行计算呢;           如果侧重存储,除非数据量达到足以体现优势的程度,否则加上线程之间切换的损耗