8086中方向标记的用法

jac*_*ath 2 assembly x86-16

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

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

我在上述陈述中错了吗?

prl*_*prl 5

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

执行字符串指令时,确定是否增加或减少CPU使用方向标志SIDI

通常情况下,DF一直保持清零状态。应该DF在使用字符串指令之前对软件进行设置,SIDI为其减小。

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

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


根据目前的英特尔处理器(SKYLAKE微架构为例)向后std/ rep movsb多少不是向前拷贝要慢些。以16或32字节块为单位进行复制的优化微码仅在cld/ DF = 0前向复制的情况下才激活。

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

repe/ne cmpsbrepe/ne scasb始终很慢(一次仅1个字节),并且在DF = 1与DF = 0的情况下可能不会变慢。只有rep movs并且rep stos已经优化了微码。

在诸如原始8086到286之类的早期x86 CPU上,全rep字符串指令的优点是代码量小,并且在加载/存储数据时不需要取指令。而且没有SIMD矢量指令可用于提高速度。