【问题标题】:What does CLD do here?CLD 在这里做什么?
【发布时间】:2014-01-27 17:46:34
【问题描述】:

我看过代码

procedure FillDWord(var Dest; Count, What: dword); assembler ;
asm
  PUSH EDI
    MOV EDI, Dest
    MOV EAX, What
    MOV ECX, Count
    CLD
    REP STOSD
  POP EDI
end;

我用谷歌搜索了 CLD,它说它清除了方向标志......所以它在这里很重要吗?在我删除它后,该功能似乎工作正常。

【问题讨论】:

  • CLD 可以省略,因为根据 Delphi 汇编代码规则必须清除方向标志。

标签: delphi assembly


【解决方案1】:

方向标志控制是否 - 在REP STOSD 执行期间EDI 寄存器将递增或递减。

在清除方向标志的情况下(例如在执行CLD 之后)指针将递增,因此该函数会填充内存。

CLD 在此代码中是因为程序员可能无法保证方向标志已被清除。因此他确保在执行REP STOSD之前清除它。

如果代码在CLD 被删除时有效,则方向标志在函数入口处被清除。由于方向标志不是幸运的调用约定的一部分。下一次可能是另一种方式,在这种情况下你的程序很可能会崩溃。

清除/设置标志是一个非常快速的操作,因此最好将它们添加到汇编代码中。这也使其他程序员更容易理解您的函数,因为方向标志的状态是明确定义的。

【讨论】:

  • 替代措辞的建议:“是否增加”听起来有点像寄存器可以保持不变。如果它说“增加或减少”会更清楚。
  • @Michael 感谢您对我的回答所做的工作。
【解决方案2】:

stosd 命令既可以减少内存,增加 EDI,也可以增加内存,减少它。这取决于方向(“D”)标志的值。如果该标志在函数入口时设置为 1 并且从未显式清除,则它将表现异常。该标志的默认值没有约定;所以这个函数很安全。

编辑:Egor 说 Delphi 有一个约定 :) 不过,安全总比抱歉好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-28
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多