2014-01-27 98 views
2

我见过的代码CLD在这里做什么?

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; 

我GOOGLE了CLD和它说,它会清除方向标志...所以这很重要吗?我删除它后,功能似乎工作正常。

+4

'CLD'可能被省略,因为方向标志必须由于汇编代码的Delphi规则而被清除。 –

回答

6

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

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

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

如果代码在CLD被删除时起作用,那么方向标志在函数的入口处被清除。由于方向标志不是仅仅靠运气的调用约定的一部分。这可能是下一次的其他方式,在这种情况下,您的程序很可能会崩溃。

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

+1

对于替代措辞的建议:“增加或不增加”听起来有点像寄存器可以保持不变。如果它表示“递增或递减”,则会更清楚。 – Michael

+0

@迈克尔感谢您的阅读作品。 –

2

stosd命令可以减少内存,递增EDI或增加内存,减少内存。这取决于方向(“D”)标志的值。如果在函数入口时该标志被设置为1,并且从未明确清除,它将会非常糟糕。关于该标志的默认值没有约定;所以功能起到安全的作用。

编辑:叶戈尔说德尔福有一个约定:)仍然,比对不起安全。