well, I know that CLD clears direction flag and STD sets direction flag. but what\'s the point in setting and clearing direction flag?
The direction flag is used to influence the direction in which string instructions offset pointer registers. These are the same instructions that can be used with the REP prefix to repeat the operation.
(Although lods
isn't very useful with rep
).
The string instructions are: MOVS (copy mem to mem), STOS
(store AL/AX/EAX/RAX), SCAS
(scan string), CMPS
(compare string), and LODS
(load string). There's also ins
/outs
for copying between memory and an IO port. Each of these instructions is available in byte, word, dword, and qword operand sizes.
In a nutshell, when the direction flag is 0, the instructions work by incrementing the pointer to the data after every iteration (until ECX
is zero or some other condition, depending on the flavour of the REP
prefix), while if the flag is 1, the pointer is decremented.
For example, movsd copies a dword from [ds:esi]
to [es:edi]
(or rdi in 64-bit mode), and does this: (See the "Operation" section in the linked ISA reference manual entry extracted from Intel's PDFs)
dword [es:edi] = dword [ds:esi] // 4-byte copy memory to memory
if (DF == 0)
esi += 4;
edi += 4;
else // DF == 1
esi -= 4;
edi -= 4;
fi
With a REP prefix, it does this ECX times, and modern x86 CPUs have optimized "fast strings" microcode that does the copying (or stos
storing) with 16-byte or 32-byte internal operations. See also this Q&A about memory bandwidth and the ERMSB feature. (Note that only rep stos
and rep movs
are optimized this way, not repne/repe scas
or cmps
).