【问题标题】:Direction Flag in x86x86 中的方向标志
【发布时间】:2012-05-09 22:33:15
【问题描述】:

我无法理解方向标志在x86 中是如何工作的。我讲座中的文字说它递增递减 来源目的地寄存器,但这没有意义用它的名字。有人能解释一下它的作用吗?

【问题讨论】:

    标签: assembly x86 microprocessors eflags


    【解决方案1】:

    此标志用于字符串操作,并指定字符串是否从低地址开始并继续到更高地址,反之亦然。

    对于字符串指令,ECX 具有迭代次数,DS:ESI 具有源地址,ES:EDI 具有目标地址(因此 ESI 中的 s dEDI)。

    在每次迭代之后,ECX 减 1,ESIEDI 根据 EFLAGS.DF 增加或减少元素大小(字节操作为 1,字操作为 2 等)。

    如果EFLAGS.DF0,则ESIEDI 递增,否则递减。

    【讨论】:

    • 所以它会相应地增加或减少字符串。如果一个字符串以较低的地址开始,它将添加到它,或者在另一种情况下执行相反的操作,对吗?
    • Nathan Fellman,@Jerry Coffin,我认为默认行为是从内存块的开头复制(清除 DF)。在什么情况下需要从末尾复制一个内存块(DF 集)?
    • @golem:考虑复制通常向下增长的堆栈。考虑比较(而不是复制)字符串,您想在其中向后检查直到第一个差异。在这些情况下,方向很重要。
    • 我刚刚发现的另一个用例是当您想将子字符串插入字符串并将尾部向右移动时。在这种情况下,您必须将字节从 len(str) 位置复制到 len(str)+len(substr),然后将 len(str-1) 复制到 len(str-1)+len(substr),依此类推在记忆中向下。
    【解决方案2】:

    我们以rep movsb为例,说明一条依赖于方向标志的指令。

    当您执行rep movsb 时,您在esi 中提供源地址,在edi 中提供目标地址,并在ecx 中提供计数。处理器基本上执行一个循环。在正常情况下(当方向标志被清除时),它会在循环的每次迭代中递增esiedi,因此您将它们初始化为指向您正在复制的源块和目标块的开头。在执行REP MOVSB 时,处理器会递增源地址和目标地址,直到到达被复制块的末尾。

    当设置方向标志时,处理器会递减寄存器。这意味着您需要从它们指向您正在复制的内存块的 end 开始。它不是从头开始复制到结尾,而是从结尾开始并向后复制直到到达开头。

    【讨论】:

      猜你喜欢
      • 2017-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-31
      • 1970-01-01
      • 1970-01-01
      • 2013-04-04
      相关资源
      最近更新 更多