【问题标题】:8086 memory to memory instructions. What do they exist for?8086内存到内存指令。他们存在是为了什么?
【发布时间】:2019-04-08 07:17:43
【问题描述】:

据我所知,8086指令有3种关于数据移动的指令集:

  1. 要注册的内存
  2. 注册到内存
  3. 注册即可注册

但是,昨天我发现了一些指令集,例如movsboutsb
使用这些指令,memory to memory(M2M) 操作是可能的!

这一次,我很好奇为什么存在M2M指令。
我发现使用它们有很多限制。

  • 这些指令会消耗大量 CPU 周期,
  • 这些指令要求使用段寄存器作为操作数。

这些M2M操作也可以结合以上1,2,3种指令运行。

问题:
我很难同意那些 M2M 指令的存在。
那些只是为了制作更短的汇编代码而存在吗?

【问题讨论】:

  • 架构师推断,硬件可以支持一些常见的高级功能。所以movsb 可以实现memcpy 和朋友,outsb 在对缺乏足够辅助硬件的哑设备执行 IO 时非常有帮助(这在过去很常见)。当然,这不是一个原创的想法或什么——在 RISC 运动出现之前,这种指令在任何地方都相当普遍(除了非常小的 8 位“微”)。
  • 注意只有 8088/8086 有内存移动,早期 PC 时代的 8237 DMA 芯片包括内存到内存传输功能,使用通道 0 作为源,通道 1 作为目标。
  • @rcgldr 哦,哇,我不知道。真的有人用过这个功能吗?
  • @fuz - 我没有使用它。我似乎记得在 1980 年代曾在我工作的一家公司对其进行测试,可能是在 1980 年代的各种台式机上对 dma 内存移动和/或 cpu 内存移动进行基准测试,以了解内存带宽。
  • 所有内存操作数都有一个段寄存器,无论是显式指定的还是隐式的。

标签: assembly x86 intel x86-16


【解决方案1】:

movs*cmps* 指令非常方便,因为它们可以让您执行复制数据和比较数据等常见任务。

ins*outs* 在本质上类似于 movs*,它们只是在内存和 I/O 设备之间移动数据。它们对于以完整扇区(通常为 512 字节)读取/写入磁盘特别有用。当然,DMA 消除了这些,因为基于 DMA 的 I/O 效率更高,但在过去它们并不像今天那样普遍。

模拟这些指令(尤其是它们的重复形式(查找rep 前缀))需要更多代码并且速度会更慢。因此它们的存在。

顺便说一句,xchg 指令和任何其他读取-修改-写入指令(例如 add)在内存中的目标也是有效的内存到内存指令。并非所有 CPU 都有这些,许多主要提供从内存读取或写入内存的指令,但不能同时提供两者(例外是用于实现对内存的独占/原子访问的指令,想想xchgxaddcmpxchg8/16)。具有此类指令集的 CPU 属于所谓的加载存储架构。

另外,pushpop 指令可以让它们的显式操作数指定一个内存位置。这是另一种形式的内存到内存指令。

至于段,几乎所有读取或写入内存的指令都涉及段(某些系统指令的工作方式不同),因此如果您决定不使用您提到的指令,则无法以某种方式避免段管理和开销并选择其他一些说明。

【讨论】:

  • 相关:What x86 instructions take two (or more) memory operands? 列出了具有 2 个独立内存操作数的指令,而不是同一操作数的 RMW。
  • 一些加载存储 ISA 也有原子交换(例如 32-bit ARM's deprecated swp instruction)和/或 CAS,但大多数 RISC ISA 仅支持 Load-Linked / Store-Conditional 所以lock add 转换为重试环形。 (只有 compare_exchange_weak 不需要循环,因为它允许在争用时失败,而不仅仅是数据差异)。
  • LL/SC 在中断延迟方面具有优势,因为它基本上使原子事务可中止。您可以实现任何原子操作(在一个位置),但您可以使用 CAS 重试循环来执行相同的操作。 LL/SC 确实可以更轻松地避免 ABA 问题......无论如何,这里离开话题。 LL/SC 仍然是 2 条单独的指令,每条指令仅加载或仅存储。但是它们链接在一起以作为 RMW 事务提交,所以是的,它们解决了与 8086 xchg 或更高版本 x86 lock cmpxchg / lock add / lock xadd / 等相同的问题。
  • Segments:字符串指令写入es:di,这使得一次处理2个段变得容易,而不会使带有段覆盖前缀的代码膨胀。代码大小对 8086 的性能至关重要。
猜你喜欢
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2016-02-21
  • 2017-01-06
  • 1970-01-01
  • 2011-11-06
相关资源
最近更新 更多