For example, this code:
void ppp(void);
void kkk()
{
__asm__ volatile("std":::"cc");
ppp();
}
Before calling ppp(), it need to execute cld
due to x86 API. Referencing Default state of Direction Flag (DF) during x86 program execution
How ever, the assemble comes out:
.globl kkk
.type kkk, @function
kkk:
#APP
# 5 "test.c" 1
std
# 0 "" 2
#NO_APP
jmp ppp@PLT
.size kkk, .-kkk
According to GCC doc( https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html ), "cc" means EFLAGS register in x86_64, why GCC not excuting cld
?
CodePudding user response:
As you already understand the i386 ABI (and AMD64 System V ABI) require the Direction Flag (DF) to be clear to enable forward direction for instructions that rely on that flag (ie. string instructions).
The FLAGS/EFLAGS/RFLAGS register on the x86/x86-64 contains many conditional flags but it also contains system flags (like the Direction Flag). Note: There are also conditional flags in the x87 FPU status word.
While inline assembly has a cc
clobber, at present it isn't used on all target CPUs. All asm
statements on GCC compilers that target x86/x86-64 processors have an implied cc
clobber and that clobber has no effect.
The GCC documentation is a bit vague in that what a conditional flag is for the x86/x86-64 targets. I believe the intent can be inferred from this statement in the 6.47.2.4 Flag Output Operands section for the x86/x86-64 targets which says:
The flag output constraints for the x86 family are of the form ‘=@cccond’ where cond is one of the standard conditions defined in the ISA manual for jcc or setcc.
In particular the last sentence that references the conditional flags supported by Jcc or SETcc gives us a clue as to what flags are assumed to not be preserved by inline assembly on x86/x86-64: Carry Flag (CF), Overflow Flag (OF), Parity Flag (PF), Sign Flag (SF), and Zero Flag(ZF).
Note: One flag in the FLAGS register that GCC doesn't care at all about is the Auxiliary Flag (AF) which can be used during the processing of certain instructions like AAA
.
To actually answer the Direction Flag (DF) question, GCC doesn't consider most of the flags in the FLAGS/EFLAGS/RFLAGS registers as conditional flags. Things like Direction Flag, Trap Flag, Interrupt Flag really don't apply. The Direction Flag is the odd man out since it is the one flag that's state is defined in the ABI. It must be cleared for forward direction.
To use the STD
instruction or other method to set the Direction Flag (backward processing) inside an inline assembly asm
statement without restoring it would be undefined behaviour. If you change the Direction Flag in an inline assembly asm
statement you are responsible for restoring it in the same asm
statement. It MUST be restored before control is return out of inline assembly.