Intel x86 手册中是否存在诸如直接/间接寻址模式之类的术语

2023-12-10

为了提供一些背景知识,我想研究如何手动编码/解码 x86 指令。我遇到了ModR/M and SIB字节,似乎理解 x86 寻址模式是理解指令编码方案的基础。

因此,我在 Google 上搜索了 x86 寻址模式。搜索返回的大多数博客/视频都是 8086 处理器的寻址模式。通过其中一些,不同的寻址模式是注册、直接、间接、索引、基于,还有更多。但博客在引用这些寻址模式时使用了不一致的名称。多个不同的源使用多种不同的寻址模式。英特尔手册中甚至没有提及不同的术语here。例如,我似乎在英特尔手册中找不到任何称为直接或间接的寻址模式。另外,Mod位在ModRMbyte 是一个 2 位字段,这让我想知道是否可以有 4 种以上的寻址模式。

我的问题是,诸如“直接寻址模式”、“间接寻址模式”之类的术语是否是英特尔手册中不再使用的较旧术语,而是由公众使用。如果这些术语在技术上确实存在,我在哪里可以找到手册中对它们的引用。


大多数形式的 x86 寻址模式都没有真正的正式名称。他们都有这样的形式[base + index*scale + disp8/disp32](或其任何 1 或 2 个组件的子集),64 位 RIP 相对寻址除外。看引用内存位置的内容。 (x86 寻址模式)了解您可以对每个子集执行哪些操作的详细信息。

英特尔确实在第 1 卷第 3.7.5 节中正式使用这些名称来表示寻址模式的组件(如下引用)。他们还使用寄存器、立即数和内存来对操作数进行分类,但通常不会对内存操作数的不同形式的寻址模式大做文章。 (在 x86 机器代码中,操作数通常是 r/m,即它可以是 reg 或 mem,具体取决于 ModRM 字节中的 2 位“mod”字段,而另一个操作数绝对是寄存器或绝对是一个立即,如操作码所暗示的。例如,参见的形式add)

ModRM字节中的Mod位是2位字段,这让我想知道是否可以有4种以上的寻址模式。

Mod使用 disp0/8/32 选择寄存器与内存。有更多模式的“转义”代码

  • 的模式[rbp]没有位移意味着 disp32 没有底座。 (这就是为什么你看到[rbp+0]反汇编:最佳编码[rbp]是base=rbp,disp8为0。(注意[rbp]当它是帧指针时没有用。)
  • ModR/M 编码为 base=rsp 意味着有一个 SIB 字节。
  • 索引 = RSP 的 SIB 编码意味着没有索引。 (考虑到前面的规则,这使得编码成为可能[rsp],而不是不太有用的[rsp+rsp].)

当用英语撰写有关汇编语言的文章时,很自然地使用具有明显含义的术语,包括您提到的一些术语。例如,Intel优化手册说(我的重点):

2.3.2.4 微操作队列和循环流检测器 (LSD)

...(具有索引寻址模式的微融合微指令在 SnB 上的 IDQ 中未层压)

...对于主要由索引寻址(经常 发生在数组处理中),要使用的重新编码算法基址(或基址+位移)寻址能 有时通过融合加载加操作和存储指令来提高性能。

索引寻址模式包括使用的任何组合idx*scale,无论它是使用基本 reg 还是使用 disp32,或两者都使用。 (idx单独是不可编码的;[rax*1]实际上编码为disp32+idx*1 with disp32=0.)在某些时候,他们会说“任何带有索引的寻址模式”或类似的内容,否则可能不清楚他们的确切含义。当然,使用性能计数器进行测试可以验证解释。

但他们不会过度地为事物起名字。当没有明显的英语短语时,他们可以坚持某些内容,他们会写道(仍在桑迪布里奇部分):

常见的加载延迟是五个周期。当使用简单寻址时 模式,基址加上小于 2048 的偏移量,加载延迟可以是四个周期。

在表 2-19 中,它们有两列,一列用于Base + Offset > 2048; or Base + Index [+ Offset],另一个为Base + Offset < 2048延迟降低 1 个周期(256b AVX 负载除外)。 (有趣的事实,[rdi+8]延迟比以下低 1c[rdi-8].)

(从技术上讲,他们可能应该说“位移”,因为整个寻址模式计算(有效地址)是 x86 术语中 seg:off 逻辑地址的偏移量,当添加到段基址时形成线性地址。但是“offset”还用于描述非 x86 通用术语中寻址模式的直接常量部分。幸运的是,现在 x86 分段并不是您通常需要考虑的问题。)


在第 1 卷手册中,英特尔确实使用了您描述的一些术语。他们将仅具有位移分量的寻址模式描述为“直接”(某种程度上),并且[reg]称为“间接”,因为在谈论指令集及其支持的寻址模式时确实会使用这些术语。

vol.1 3.7.5 指定偏移量

以下寻址模式建议使用常见的组合 地址组件。

  • 移位——单独的位移代表direct操作数的(未计算的)偏移量。因为位移是 编码在指令中,这种形式的地址是有时 称为绝对地址或静态地址。它通常用于访问 静态分配的标量操作数。

  • Base——单独的一个碱基代表一个indirect到操作数的偏移量。 ...

  • (索引 * 比例)+ 位移 — 这种地址模式提供了一种有效的方法来索引静态数组...

  • 基数+索引+位移...

  • 基址 +(索引 * 比例)+ 位移 — 一起使用所有寻址组件可实现高效 当数组元素大小为 2、4 或 8 字节时,对二维数组进行索引。

但正如您所看到的,它们不会为更复杂的形式命名。

不过,它们确实区分了立即操作数、寄存器操作数和内存操作数。 (3.7 操作数寻址)。不过,他们通常很少或根本不区分使用寄存器编码的 r/m32 操作数与必须是寄存器的其他操作数。


分支指令术语

直接与间接也适用于分支。这有点像谈论到达接下来要运行的代码字节的寻址模式。

6.3.7 64 位模式下的分支函数

...

地址大小影响用于JCXZ和LOOP的RCX的大小;它们还会影响地址计算记忆 间接分支机构。此类地址默认为 64 位;但它们可以通过地址大小覆盖为 32 位 字首。

内存间接是jmp [rax],其中 RIP 的最终值来自内存,而不是像这样的寄存器间接分支jmp rax设置 RIP=RAX。 x86 没有用于数据加载/存储的内存间接寻址模式;采取分支后的代码获取引入了术语中额外的间接级别。 (某种程度上,由于在将新地址加载到 RIP 中后,RIP 被代码提取取消引用)。

第2卷手动输入jmp确实谈论了间接跳跃与相对或绝对跳跃。 (尽管注意 x86 没有绝对的直接near跳转(如果不能使用相对,请将地址放入寄存器和 jmp reg);唯一绝对的直接跳跃是缓慢的“远”jmp ptr16:16 or jmp ptr16:32立即指针作为机器代码的一部分。)

当描述近间接跳跃时,jmp r/m32(或 64),他们说“在 GP 寄存器或内存中间接指定的绝对偏移量”。 (此处 seg:off 意义上的“偏移量”将用作 cs:eip 或 cs:rip 的一部分以进行代码获取。)。

分段使得 x86 寻址变得更加复杂,尤其是在比较可以显式包含段的特殊寻址模式与不包含显式段的特殊寻址模式时。


命名寻址模式被高估了

记住 x86 寻址模式在一般情况的子集方面可以做什么要容易得多,而不是用索引、基于等名称单独记住所有不同的可能性。

你会在像这样的教程中看到类似的东西https://www.tutorialspoint.com/microprocessor/microprocessor_8086_addressing_modes.htm or http://www.geeksforgeeks.org/addressing-modes/这对寻址模式的分类非常重要。后者甚至有一个测验,要求您将 C 语句与一些寻址模式名称相匹配。

对于不太灵活的 16 位寻址模式,您可以尝试命名它们,而基于与索引的寻址模式实际上为您提供了不同的寄存器选择。但是当你编程时,你真正需要记住的是,这是你对任何子集的选择[bx|bp] + [di|si] + disp0/8/16。就是这样di/si(dst/src 索引)也许bx/bp得到了他们的名字。


此类术语可用于比较不同 ISA 的功能。例如,维基百科说像 PDP-8 这样的旧 ISA 大量使用了内存间接,因为它们的寄存器很少,并且寄存器的寻址范围只有 8 位。

维基百科还说:

请注意,没有普遍接受的方式来命名各种寻址模式。

大肆渲染模式的命名是没有意义的。如果您正在写一些东西,请确保您的意思清晰,而不依赖于某些术语的特定技术含义。例如如果您说“索引寻址模式”,请确保读者从上下文中知道您是否包含base+index*scale or not.

我想知道命名模式的某些愿望是否源于 8086 之前的 8 位微处理器。您可能想在https://retrocomputing.stackexchange.com/。我不太了解 8 位 CPU 上可用的寻址模式,这些 CPU 大多是固定的一字节指令。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Intel x86 手册中是否存在诸如直接/间接寻址模式之类的术语 的相关文章

  • 使用 Easy 68K (68000) 组装范围内的随机数

    我正在使用 Easy 68K 模拟器创建一个简单的黑杰克游戏 需要使用随机数来分配牌 我的牌必须在 2 到 11 的范围内 我似乎每次都得到相同的数字 但它不在我预期的范围内 我的卡值需要以 D3 结束 因此我有以下随机数代码 CLR L
  • 为什么在强度降低乘法和循环进位加法之后,这段代码的执行速度会变慢?

    我正在读书阿格纳 雾 https en wikipedia org wiki Agner Fog s 优化手册 https en wikipedia org wiki Agner Fog Optimization 我遇到了这个例子 doub
  • 68HC11计算sin(x)的汇编代码

    68HC11 使用泰勒级数或查找表计算正弦值的汇编代码是什么 显示值只能是整数 查找表如何工作 在这种情况下 如何使用它来实现泰勒级数 http en wikipedia org wiki Taylor series 如果您正在寻找浮点解决
  • 大会,你好世界问题

    我正在 Linux 上学习 asm noobuntu 10 04 我得到了以下代码 http asm sourceforge net intro hello html http asm sourceforge net intro hello
  • 如何在 Debian 上编译 DOS 程序?

    在我的汇编语言课程中 我们使用 DPMI 编写 DOS 程序 不幸的是 我无法一直使用 32 位 Windows 机器 我在我使用的几乎每台计算机上都安装了 Debian 虚拟机 我已经安装了 DOSBox 和 DOSEMU 有什么办法可以
  • 阴影空间示例

    EDIT 我接受了下面的答案 并添加了我自己的代码的最终修订版 希望它向人们展示影子空间分配的实际示例 而不是更多的文字 编辑 2 我还设法在 YouTube 视频 所有内容 的注释中找到了一个调用约定 PDF 的链接 其中有一些关于 Li
  • 如何将 x86 GCC 风格的 C 内联汇编转换为 Rust 内联汇编?

    我在 C 中有以下内联汇编 unsigned long long result asm volatile byte 15 byte 49 shlq 32 rdx orq rdx rax a result rdx return result
  • X86 预取优化:“计算 goto”线程代码

    我有一个相当重要的问题 我的计算图有循环和多个 计算路径 我没有制作一个调度程序循环 其中每个顶点将被一一调用 而是将所有预先分配的 框架对象 放置在堆中 代码 数据 这有点类似于线程代码 甚至更好 CPS 只是在堆中跳转 执行代码 每个代
  • 为什么 clang 使用 -O0 生成低效的 asm(对于这个简单的浮点和)?

    我正在 llvm clang Apple LLVM 版本 8 0 0 clang 800 0 42 1 上反汇编此代码 int main float a 0 151234 float b 0 2 float c a b printf f c
  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • Visual Studio 2012 本机 C++ DLL x86 编译

    我最近将我的工具集从 Win 7 x86 Visual Studio 2010 升级到 Win 8 x64 Visual Studio 2012 但是 现在我的本机 C dll 编译为 x64 而不是 x86 除了将代码移至新操作系统并将其
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • 为什么我的代码显示垃圾?

    当我也想打印列表中的每个数字时 我的代码显示垃圾 有什么问题吗 输出应如下所示 给定的数组是 2G 4 PT为什么这是垃圾总数是 7 Code ASSUME CS CODE DS DATA SS STK ORG 0000H DATA SEG
  • 如何使用 Bochs 运行汇编代码?

    我想使用 Bochs 作为 8086 模拟器 是否有捷径可寻 我想要的是类似 emu8086 的东西 http www emu8086 com http www emu8086 com 如果程序的初始部分适合 512 字节 并且您不介意将自
  • 在 x86 汇编中将 64 位常量移至内存

    我正在使用 Intel x64 程序集 NASM 编译器 尝试将 0x4000000000000000 常量移至内存 该常量在 ieee 754 标准双精度中应等于 2 0 我正在使用的代码是 define two 0x4000000000
  • 错误 LNK2019:函数 main 中引用的外部符号无法解析

    我正在尝试在 C 中运行我的简单汇编代码 我只有两个文件 cpp 文件和 asm 文件 编译时出现错误 见下文 如果有人可以提供帮助 我将不胜感激 这是我的 main cpp 文件 include
  • 长多字节 NOP:通常理解的宏或其他符号

    x86 和 x86 64 处理器不仅具有单字节 这不是什么大秘密NOP指令 还包括各种类型的多字节类 NOP 指令 这些是我设法找到的 AMD 推荐 参考 AMD 系列 15h 处理器的 AMD 软件优化指南 文档 47414 http s
  • 避免 gcc 函数序言开销?

    我最近遇到了很多 gcc 在 x86 上生成非常糟糕的代码的函数 它们都符合以下模式 if some condition do something really simple and return else something comple
  • movzbl(%rdi, %rcx, 1), %ecx 在 x86-64 汇编中意味着什么?

    我想我明白 movzbl rdi rcx 1 ecx 意思是 将零扩展字节移至长整型 并表示将 ecx 扩展为 32 位 但我不完全确定语法 rdi rcx 1 指的是什么 我在某处看到该语法指的是 Base Index Scale 但我找
  • 汇编器8086将32位数字除以16位数字

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw

随机推荐

  • 将值从一个脚本返回到另一脚本

    我有以下脚本将 顺序 运行目录中的每个脚本 import os directory for dirpath dirnames filenames in os walk path to scripts for filename in f fo
  • 不使用 Invoke-Expression 扩展字符串

    想象一下下面的代码 Script Start WelcomeMessage Hello UserName today is Date DayOfWeek 100 lines of other functions and what not f
  • MATLAB/Octave:从图像中切出很多圆圈

    我有一个矩阵 图像 和有关圆圈内有趣部分的信息 给出中心坐标和半径 我想剪掉所有的圆 矩阵的一部分 以便对每个圆进行更多计算 或者至少我想要一个带有所有圆圈的位掩码 我使用 Octave 但也可以使用 MATLAB 但由于许可证问题 这会很
  • 验证失败,但无法在 DataGridView 中删除

    这是我的 DataGridView 的 RowValidation 函数 DataGridViewRow row viewApplications Rows e RowIndex if row Cells colApplyTo Index
  • 如何从两个 Openshift 应用程序访问 MongoDB 数据库?

    我希望能够从 2 个 Openshift 应用程序访问我的 MongoDB 数据库 一个应用程序是通过浏览器的交互式数据库维护应用程序 另一个是通过 Openshift 应用程序在移动设备上运行的主要 Web 应用程序 正如我在 Opens
  • 通过 Java lib Apache Commons 上传文件的简明示例

    编辑 我已经删除了我的复杂且严重畸形的问题 这样它就不会影响下面非常简洁和正确的答案 考虑到找到一个在线示例来完成这项极其常见的任务非常困难 令人惊讶 我希望 Yoni 的回答能得到更多支持 所以 简而言之 这个问题 如何使用 Apache
  • Firebase 已获得 FedRAMP 授权?

    我使用 Firebase 作为后端 我看到谷歌服务已获得FedRAMP授权 并且firebase已与谷歌云集成使用 那么firebase也获得了FedRAMP的授权吗 如果没有 有什么办法可以在firebase中获得FedRAMP授权吗 T
  • 使用 PHPExcel 从 Excel 读取数字时出现问题

    我正在尝试使用 PHPExcel 从 Excelsheet 中读取数字 我读取数据的代码 objReader PHPExcel IOFactory createReaderForFile upload file objReader PHPE
  • 带原始数据的 Volley 请求

    在我的应用程序中 我必须使用 JSON req param 发送 POST 请求 我尝试使用 Postman Rest Client 创建请求 它工作正常 但无法使用下面的代码 在作为原始数据发送的 Postman req 参数中 但我不确
  • R XML 解析网址

    我正在尝试下载天气数据 类似于此处提出的问题 如何将XML解析为R数据帧但是当我运行示例中的第一行时 我收到 错误 1 无法加载 HTTP 资源 我已检查该 URL 是否有效 这是我指的行 data lt xmlParse http for
  • 如何确定目录中的任何文件是否已更改

    Chef 有没有办法确定它是否更改了给定目录中的任何文件 如果conf d 目录中的任何设置被更新 我想重新启动服务器进程 我确信可以在每次厨师客户端运行时将 md5sum 列表写入文件 并将当前迭代与之前的迭代进行比较 但这是解决常见场景
  • 错误 DEP0001:意外错误:-2147009287 部署 Windows Phone Universal 10

    当我尝试将应用程序部署到 Windows Phone 10 时 出现以下错误 错误 2147009287 来自 Visual Studio 2015 社区 我该如何解决这个问题 正如 Jay Zuo 在他的评论中所说 通过链接 解决此问题的
  • 使用 Gradle 编译项目时 IntelliJ 到底在做什么?

    IntelliJ IDEA 2016 3 添加了将构建 运行委托给 Gradle 的功能 很明显 当 Gradle 上有委托选项时 Gradle 就会执行所有操作 我的问题是 当此选项关闭时 IntelliJ 到底在做什么 我问这个问题是因
  • 将 xls 文件从 url 下载到数据框(Rcurl)中?

    我正在尝试将以下网址下载到 R 数据框中 http www fantasypros com nfl rankings qb php export xls 这是公共页面上的 导出 链接 http www fantasypros com nfl
  • 使用 HTML 或 JavaScript 在 WhatsApp 网页版上发送消息

    我想通过 Whatsapp 网络发送消息 我正在使用以下代码 但它不起作用 https wa me text urlencodedtext 我无法查看联系人列表来发送此编码消息 我参考了 WhatsApp com如何使用点击聊天 尝试更改域
  • SQL - 加载数据内文件 - UTF8 问题

    我很少将大型数据库导出到 txt 每个大约 5GB 所以我发现我可以轻松导入它 将数据本地 INFILE path pet txt 加载到表 pet 它工作得很好 但我在那里遇到 UTF 8 的问题 因为有些文本显示为 PODB H Z L
  • F# 中的通用类型注释

    我收到以下错误 错误 2 值限制 价值 gbmLikelihood 已被推断为具有泛型类型val gbmLikelihood float gt a gt float gt float when a gt seq
  • 将 Excel UDF 放入 Worksheet 对象中(而不是放在模块中)

    我怀疑答案是 不可能 但是询问这个优秀的社区总没有坏处 我有一个 Excel 2013 UDF 用户定义函数 它对于某个工作表来说是唯一的 目前 我将此 UDF 放在包含工作簿的 模块 中 但我想做的是将 UDF 代码放置在 工作表对象 中
  • 数据仓库的日历表

    对于我的数据仓库 我正在创建一个日历表 如下所示 SET NOCOUNT ON DROP Table dbo Calendar GO Create Table dbo Calendar CalendarId Integer NOT NULL
  • Intel x86 手册中是否存在诸如直接/间接寻址模式之类的术语

    为了提供一些背景知识 我想研究如何手动编码 解码 x86 指令 我遇到了ModR M and SIB字节 似乎理解 x86 寻址模式是理解指令编码方案的基础 因此 我在 Google 上搜索了 x86 寻址模式 搜索返回的大多数博客 视频都