8086指令集:MODR/M字节

2023-11-30

当提到 MODR/M 字节时,8086 文档站点似乎有点模糊,并且很难理解它是什么和做什么。

MODR/M 字节中所有位的用途是什么以及可能的选项是什么?

我找到的一些文档:https://www.scs.stanford.edu/05au-cs240c/lab/i386/s17_02.htm

The ModR/M byte contains three fields of information:
The mod field, which occupies the two most significant bits of the byte, combines with the r/m field to form 32 possible values: eight registers and 24 indexing modes
The reg field, which occupies the next three bits following the mod field, specifies either a register number or three more bits of opcode information. The meaning of the reg field is determined by the first (opcode) byte of the instruction.
The r/m field, which occupies the three least significant bits of the byte, can specify a register as the location of an operand, or can form part of the addressing-mode encoding in combination with the field as described above

什么是索引模式?什么是注册号?寄存器是如何表示的? ETC。


英特尔自己的 PDF 手册详细记录了这一点;看SDM 第 2 卷,特别是每条指令条目之前的介绍章节。

各个网站上也有详细的说明,例如https://wiki.osdev.org/X86-64_Instruction_Encoding#ModR.2FM_and_SIB_bytes(涵盖 16 位 ModRM,因此它不仅仅是谈论 x86-64 长模式。)现代 x86 使用与 8086 相同的指令编码(在 16 位实模式下);向后兼容是 x86 的全部要点,也是它如此令人讨厌的原因。

当然,您可以找到实际 8086 手册本身的 PDF 副本,以防省略仅与其他模式相关的内容更有帮助。

8086 入门书从第 23 页开始介绍操作数的指令编码。它被写成一本书,而不仅仅是一本技术手册。它可以在 Stephen Morse 的网站上免费获得(https://stevemorse.org/8086/),他在英特尔时设计了它。

但也许它会有助于描述 ModRM 用途的基本概述,以便您知道在这些文档中寻找什么。


ModR/M 目的和基础知识

大多数(但不是全部)x86 指令都有一个 ModRM 字节。它可以对 2 个操作数进行编码,最多其中之一是内存,或者两个操作数都是寄存器。例如add cx, ax, or add cx, [bx+si].

操作码本身确定 r/m 和 r 操作数中哪一个是源和/或目标,或者是否是/r字段充当额外的操作码位。 (例如,对于移位,这就是为什么它们不能复制和移位,或使用 CL 以外的计数寄存器。)add [bx+si], cx具有相同的 ModRM 字节add cx, [bx+si]但操作码不同。

仅寄存器操作数由 3 位 /r 字段编码。 3 位可以为 x86 的 8 个通用寄存器中的任何一个进行编码。这是一个“寄存器号”,就像任何具有 2^n 个寄存器的普通 ISA 一样,每个指令代码中的 n 位组用于寄存器操作数。

The r/m操作数也可以是寄存器,但2位“模式”字段决定3位r/m字段是寄存器号(mod=0b11)还是存储器寻址模式。 (再加上 8 位或 16 位位移,因此 disp0/8/16 的编码会占用模式字段的其他 3 种编码。)

https://wiki.osdev.org/X86-64_Instruction_Encoding#ModR.2FM_and_SIB_bytes显示 16 位地址大小的字段和解释,包括寄存器编号。

因此只有 3 位来指定一个寄存器或寄存器组合的内存地址。 386 为 SIB 字节添加了转义码,允许完全选择寻址模式,例如[eax + ecx*4],但 8086(以及任何 CPU 上的 16 位地址大小)必须是[BX|BP] + [SI|DI] + disp0/8/16.

See 8086 中通用寄存器之间的差异:[bx] 有效,[cx] 无效? / 为什么 x86 16 位寻址模式没有比例因子,而 32 位版本有?

组装示例foo.asm进而ndisasm -b16 foo,或者要求 NASM 本身列出清单nasm -l/dev/stdout foo.asm。然后进行编辑以简化输出字段。

 00 00           add [bx+si],al      ; opcode=0x00 (add byte, mem dst)  mod=00 r=000 r/m=000

 01 C0           add ax, ax          ; add r/m, r   mod=11 (register) r=000 (AX) r/m=0 (AX)
 01 08           add [bx+si], cx     ; add r/m, r
 03 08           add cx, [bx+si]     ; mod=0, r=001 (CX) r/m=000 ([bx+si])

 03 0F           add cx, [bx]        ; mod=00 r=001 (CX) r/m=111 ([BX])
 03 4F 04        add cx, [bx + 4]    ; mod=01 r=001 (CX) r/m=111  disp8=4

 01 F2           add dx, si          ; mod=11 r=110 (SI) r/m=010 (DX)

要创建更多示例,请使用汇编器自行创建机器代码。

See also

  • 为什么 x86 16 位寻址模式没有比例因子,而 32 位版本有?
  • rbp 不允许作为 SIB 基础?- 意味着 [bp] 的编码实际上意味着没有基址寄存器,只是位移。
  • Intel x86 Assembly 文档中的 [--][--] 是什么意思?(32/64 位模式 ModR/M 和 SIB)。
  • 如何阅读英特尔操作码符号当。。。的时候/rModRM 的字段用作额外的操作码位,例如FF /2CALL r/m16 调用近端,绝对间接。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

8086指令集:MODR/M字节 的相关文章

  • 为什么 Solaris 汇编器生成的机器代码与 GNU 汇编器在这里不同?

    我为 amd64 编写了这个小汇编文件 对于这个问题来说 代码的作用并不重要 globl fib fib mov edi ecx xor eax eax jrcxz 1f lea 1 rax ebx 0 add rbx rax xchg r
  • NASM 轮班操作员

    您将如何在寄存器上进行 NASM 中的位移位 我读了手册 它似乎只提到了这些操作员 gt gt lt lt 当我尝试使用它们时 NASM 抱怨移位运算符处理标量值 您能解释什么是标量值并举例说明如何使用 gt gt and lt lt 另外
  • Visual Studio 2017 上的简单装配程序

    386 model flat c stack 100h printf PROTO arg1 Ptr Byte data msg1 byte Hello World 0Ah 0 code main proc INVOKE printf ADD
  • 汇编8086监听键盘中断

    我有与此完全相同的问题 边画边听键盘 https stackoverflow com questions 13970325 8086 listen to keyboard while drawing 但第一个答案 接受的答案 只听键盘一次
  • 为什么当大小大于 50 时,该程序花费的时间会呈指数级增长?

    所以我正在为类编写一个 ARM 汇编快速排序方法 我对大部分内容都有了解 除了复杂性没有意义 我们将其与我们制作的另一种冒泡排序方法进行比较 它对于具有 1 个参数和 10 个参数的示例表现更好 然而 我什至无法比较 100 个参数测试 因
  • 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
  • CPU寄存器和多任务处理

    我目前正在学习汇编 我很困惑 CPU 寄存器如何与多任务一起工作 所以在多任务系统中 CPU可以随时暂停某个程序的执行并运行另一个程序 那么在这一步中寄存器值是如何保存的呢 寄存器是压入堆栈还是以其他方式 CPU 寄存器如何与多任务一起工作
  • AVX-512 指令编码 - {er} 含义

    在 Intel x86 指令集参考中 有许多 AVX 512 指令在指令中具有可选的 er 例如 VADDPD 的一种形式定义为 EVEX NDS 512 66 0F W1 58 r VADDPD zmm1 k1 z zmm2 zmm3 m
  • 这个反斜杠在这段汇编代码中起什么作用?

    我不确定这些推线有什么区别 修剪下来来自 Linux 的 x86 entry calling h https github com torvalds linux blob 241e39004581475b2802cd63c111fec43b
  • FreePascal x64 上系统单元函数的汇编调用

    我有一些 Delphi 汇编代码 可以在 Win32 Win64 和 OSX 32 上编译并正常工作 XE2 但是 由于我需要它在 Linux 上工作 所以我一直在考虑编译它的 FPC 版本 到目前为止 Win32 64 Linux32 6
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 如何使用 Bochs 运行汇编代码?

    我想使用 Bochs 作为 8086 模拟器 是否有捷径可寻 我想要的是类似 emu8086 的东西 http www emu8086 com http www emu8086 com 如果程序的初始部分适合 512 字节 并且您不介意将自
  • 长多字节 NOP:通常理解的宏或其他符号

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

    有谁知道 memcspn 函数的有效实现吗 它的行为应该类似于 strcspn 但在内存缓冲区中查找跨度 而不是在以 null 结尾的字符串中查找跨度 目标编译器是 VisualC 谢谢 卢卡 一种近乎最佳的实现 size t memcsp
  • 为什么在展开的 ADD 循环内重新初始化寄存器会使其运行速度更快,即使循环内有更多指令?

    我有以下代码 include
  • 整数溢出问题

    我不断遇到整数溢出问题 我不知道如何解决它 有人可以帮忙吗 edx 包含 181 eax 包含 174 xor eax edx mov edx 2 div edx 假设你谈论的是x86 div edx这实际上没有意义 32位div将edx
  • movzbl(%rdi, %rcx, 1), %ecx 在 x86-64 汇编中意味着什么?

    我想我明白 movzbl rdi rcx 1 ecx 意思是 将零扩展字节移至长整型 并表示将 ecx 扩展为 32 位 但我不完全确定语法 rdi rcx 1 指的是什么 我在某处看到该语法指的是 Base Index Scale 但我找
  • Grub 和进入实模式(低级汇编语言编程)

    我一直在开发一个玩具操作系统 并一直使用 grub 作为我的引导加载程序 最近尝试使用 VGA 时 我发现无法使用硬件中断 我发现这是因为我被 grub 置于保护模式 有人知道如何在不删除 grub 的情况下回到实模式吗 如果您使用 GRU
  • 使用 Gas 生成与位置无关的代码 (-fPIC)

    我尝试在 x86 64 上创建共享库但失败 问题归结为以下代码 请不要介意 它没有多大意义 section data newline ascii n section text globl write newline type write n

随机推荐

  • 重载 +/- 一元运算符

    当你重载 一元运算符时 对于不可变类型 你可以这样写 public static Point3 operator Point3 p return new Point3 p X p Y p Z 但是对于 一元运算符 应该如何实现呢 像这样 p
  • QTableWidget列大小调整事件

    我想知道 QTableWidget 的列是否正在通过鼠标调整大小 每当调整任何列的大小时 如何发出信号 列大小调整是通过水平方向执行的QHeaderView 通过调用访问它QTableWidget horizontalHeader cons
  • 如何通过 XSSF 事件 API 评估 Excel 公式

    我正在使用 Apache POI 的事件 API 读取 XLSX 文件 即我通过 SAX 解析器读取 XLSX 表的内容 我想知道如何使用 XSSF 事件 API 获取公式的计算值 我知道做到这一点的方法是使用FormulaEvaluato
  • Rails - 如何存储像 100000076685963 这样的大数字

    我需要存储大量数字 例如 100000076685963 对于整数的数据库字段类型来说太大了 在我的数据库迁移中我使用 t integer fb uid 对于这样的大数字我应该使用什么字段类型 Thanks 您可以使用定点数据类型 例如具有
  • Node.js代理,处理gzip解压缩

    我目前正在开发一个代理服务器 在这种情况下我们必须修改我们推送的数据 通过使用正则表达式 在大多数情况下 它工作得很好 除了使用 gzip 作为内容编码的网站 我认为 我遇到过一个名为compress并尝试通过解压缩 gunzip流推送我收
  • 让批处理文件最小化 DOS 窗口?

    所以我又有点喜欢 MS DOS 之类的东西 但我问自己 如何最小化 DOS 窗口 任何类型都可以 最小化 缩小到一个小的蓝色块 我似乎找不到一种方法让它在我的 Windows XP 计算机上运行 真的一切都被排除在 XP 中了吗 您可以使用
  • 用于获取只读(不可变)PostgreSQL 表行数的索引?

    我有一个每天运行几次的脚本 它记录了几个 PostgreSQL 表的行数 但有些表是只读的并且永远不会改变 没有添加或删除行 也没有更改任何值 有没有办法可以快速从 PostgreSQL 获取行数 例如 我可以创建索引吗select cou
  • ZMQ PUB 发送文件

    我第一次尝试 PY ZMQ 想知道是否可以使用 PUB SUB 发送完整的文件 二进制 我需要向许多订阅者发送数据库更新 我看到了短信的示例 但没有看到文件 是否可以 出版商 您应该能够使用 zmq 和 PUB SUB 模式将文件分发给多个
  • Swift:如何使用 SwiftUI 4 根据侧栏选择状态更改 DetailView?

    Context 我对新的 SwiftUI 有疑问SideBar NavigationLink概念 我创建了一个简单的2 Column NavigationSplitView with a SideBar and a DetailView 应
  • MySQL 查询中的 NAND/NOR 操作

    任何人都可以帮我解释如何编写 NAND 和 NOR 查询吗 我越来越困惑了 有没有什么好的例子可以帮助理解查询中的 NAND 和 NOR 操作 我在两个 SQL 查询之间进行 AND 和 OR 操作 但是当我搜索一些与 NAND NOR 相
  • 可以按列而不是按行填充“类似网格”的视图吗?

    我使用 GridView 显示电视频道列表 使用 SimpleCursorAdapter 从数据库检索频道名称 默认行为是填充网格左侧 gt 右侧 顶部 gt 底部 如下所示 1 2 3 4 5 6 GridView 固定为 2 列 并且如
  • 在 ubuntu 中使用 Python 中的 matplotlib 从 csv 文件绘制 2D 图形

    我必须使用 python 将 csv 文件中的值绘制成图表 我在 python 中使用以下代码 代码 import numpy as np import matplotlib pyplot as plt def graph cv dv np
  • 如何获得Java程序的可执行文件? [复制]

    这个问题在这里已经有答案了 可能的重复 如何将我的 java 程序转换为 exe 文件 我正在尝试将用 Java 6 编写的程序导出到 JAR 文件 我的项目包含一个来自 Internet 的 Java 库和一些 Java 源文件 当我创建
  • 没有mvc可以进行模型绑定吗?

    说我有一个Dictionary
  • 如何在 Laravel 中进行即时重定向

    我想在 Laravel 的控制器中进行即时重定向 我知道我可以使用 public function show page return Redirect url http example com 但我想在许多控制器中重复此代码添加条件 例如我
  • .htaccess 无法在使用 XAMPP 的 localhost 上工作

    我正在使用 XAMPP 但我无法在本地主机上使用 htaccess 文件 我尝试了很多次 在线工作良好 但本地主机显示 在此服务器上找不到所请求的 URL 我的根文件夹是真实的 localhost acre real property av
  • 如何在 iOS 中打开文件?

    我正在尝试打开一个 pdf下载后的文件是用阿拉莫菲尔 但我只见过使用 webview 因此 该应用程序会消耗大量内存并且不可行 我想要的是用本机设备应用程序打开它 有什么建议么 谢谢 Edit 这是我的下载文件代码 var localPat
  • GAE:断言错误:找不到服务“datastore_v3”的 api 代理

    我正在编写简单的代码来访问开发服务器 开发服务器和模拟的数据存储都已在本地启动 from google appengine ext import ndb class Account ndb Model name ndb StringProp
  • 底部垂直对齐+行内块

    我有以下 HTML 结构 div class box div class box1 item div div class box2 item div div class box3 item div div class box4 item d
  • 8086指令集:MODR/M字节

    当提到 MODR M 字节时 8086 文档站点似乎有点模糊 并且很难理解它是什么和做什么 MODR M 字节中所有位的用途是什么以及可能的选项是什么 我找到的一些文档 https www scs stanford edu 05au cs2