__asm__ volatile("syscall"
: "=a"(ret)
: "a"(n), "D"(a0), "S"(a1), "d"(a2), "r"(r10), "r"(r8),
"r"(r9)
: "rcx", "r11", "memory"); __asm__ volatile("syscall"
: "=a"(ret)
: "a"(n), "D"(a0), "S"(a1), "d"(a2), "r"(r10), "r"(r8),
"r"(r9)
: "rcx", "r11", "memory");GCC does, however, know what to do with a .s file, so you can write your assembly routines outside your C(++) source and just compile them in like a C module, which is what I did last time I was hardcore slinging x86 opcodes.
It's very easy to get the constraints wrong and have the aggregate still "work", until unrelated changes months later perturb the register allocation slightly such that it no longer runs as hoped.
It's documented and usable but working with it is never a very good time.
A hidden feature of the D inline assembler is the compiler knows which registers are read/written, so there's no need for the programmer to explicitly specify it. The compiler will also figure out the right addressing mode for local variables, so the programmer is relieved of that, too.
I proposed doing the same for printf - have the compiler example the arguments and insert the appropriate formats in the format string.
The one in the parent comment does not; it's basically a black box and the compiler has to save and restore the entire state of the function around it. Total performance killer unless you write large chunks of code in inline assembly (and then you're probably better off just using an assembly file).