Okay, I understand the question now, I hope.
my understanding of all this is:
- if you want it set a certain way, you have to set it
Yes.
- don't ever assume it has any particular value.
For inline asm? Yes.
The ABI says that DF=0 whenever a function is called. For GCC, this means that it will make sure it is like that whenever it calls some (external) function; and (in newer GCC versions) it assumes all functions are called with DF=0, so it doesn't have to use the cld insn that often, which is a good thing because it is quite expensive.
Now, _within_ a function GCC can do as it bloody well pleases. This includes functions that are inlined etc.; the ABI only applies to externally visible functions.
"GCC relies on the ABI mandate that the direction flag is cleared before entry to a function"
That means if you call the payload via a pointer, gcc will make sure the direction flag is cleared (either by clearing it directly before the call or by never changing it after the start of the program).
Yes.
AFAIK calling a function via inline asm is not something gcc can see,
Indeed. It usually isn't such a great thing to do either; you will have to take care of saving all regs etc. yourself, keeping the stack balanced, all that. Often you get much nicer code if you write this in actual (not inline) asm, that you call with the usual calling conventions.
so this special case might be an exception. Then again, it's pretty unlikely that gcc sets the direction flag for some operations and defers clearing to the last possible moment.
You do not want to rely on what GCC does if it doesn't guarantee that behaviour.
Turns out gcc developers disagreed with each other about direction flag guarantees for inline asm.
Not really. There are two things: what GCC does right now, and what should be the guaranteed behaviour (if any).
Michael Matz said there are no guarantees for inline asm, but he also said that std is not emitted lazily, so having cld inside inline asm will not break any code afterwards, i.e. code after an inline asm does never depend on the DF being set. Chris Lattner said it's reasonable for inline asm to expect the DF to be cleared. Richard Guenther said inline asm shouldn't make assumptions about DF. Jan Hubicka said gcc does not emit std at the moment.
The safest way to write inline asm that changes the direction flag is to push eflags, change the flag, do your thing, and finally pop eflags. This should work no matter what, and you are crazy if you care about the performance or tiny code size of this ;-)
Or, write an assembler stub for this, and all your problems magically go away.
Segher