【问题标题】:Direction flag usage in 80868086 中方向标志的使用
【发布时间】:2019-07-23 00:05:32
【问题描述】:

我在书中读到,当SI 寄存器小于DI 寄存器(在字符串操作中)时,方向标志等于0,否则方向标志等于1。

但我也读过指令通常不会改变方向标志,那么它的确切用法是什么?我们应该根据我们的字符串第一个和最后一个索引设置还是取消设置这个标志? (应该我们处理这个标志还是让 CPU 处理它?)

我在上面的陈述中错了吗?

【问题讨论】:

  • 这不是它的工作原理。这与SI 是否小于DI 无关。它只与您在使用字符串指令时是否希望它们增加或减少有关。
  • 好的,那么问题的另一部分我们应该始终设置它还是 CPU 处理呢?
  • 例如查看movsbrep movsb的Operation部分:他们只读取DF。

标签: assembly x86-16


【解决方案1】:

CPU 永远不会自动设置或清除方向标志。这只能通过软件完成。

CPU在执行字符串指令时使用方向标志来判断是递增还是递减SIDI

通常DF 始终保持空白。软件应该在使用字符串指令之前设置DF,而SIDI应该递减。

您可能希望减少SIDI 的一个原因是在执行缓冲区重叠且源地址小于目标地址的内存复制时。在这种情况下,正常的正向复制将在读取之前覆盖源缓冲区的一部分,而反向复制将起作用。

反向复制需要(DS:)SIES:DI 指针最初指向要移动的最高元素,而不是最低元素。 (仍然是要复制的第一个字节。)


在当前的 Intel CPU(例如 Skylake)上,向后 std/rep movsb 比向前复制慢很多。以 16 或 32 字节块复制的优化微码仅在 cld / DF=0 前向复制情况下激活。

例如,在大约 4.1GHz 的 i7-6700k Skylake 上,围绕 4096 字节 rep movsb 且源和目标对齐的 1000000 次迭代重复循环总共花费了大约 42 毫秒,或向后总共花费了大约 1000 毫秒模式。实模式下的性能应该类似。

repe/ne cmpsbrepe/ne scasb 总是很慢(一次只有 1 个字节),并且在 DF=1 与 DF=0 时可能不会更慢。只有rep movsrep stos 优化了微码。

在早期的 x86 CPU(如原始 8086 到 286)上,所有rep-string 指令都具有代码量小的优点,并且在加载/存储数据时不需要提取指令。而且没有 SIMD 矢量指令可以让您更快地运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 2013-10-02
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多