The asm keyword allows you to embed assembler instructions within D
code. GNU D provides two forms of inline asm statements. A basic
asm statement is one with no operands, while an extended
asm statement includes one or more operands.
asm FunctionAttributes {
AssemblerInstruction ;
}
asm FunctionAttributes {
AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers
[ : GotoLabels ] ] ] ;
}
The extended form is preferred for mixing D and assembly language within a
function, but to include assembly language in a function declared with the
naked attribute you must use basic asm.
uint incr (uint value)
{
uint result;
asm { "incl %0"
: "=a" (result)
: "a" (value);
}
return result;
}
Multiple assembler instructions can appear within an asm block, or the
instruction template can be a multi-line or concatenated string. In both
cases, GCC’s optimizers won’t discard or move any instruction within the
statement block.
bool hasCPUID()
{
uint flags = void;
asm nothrow @nogc {
"pushfl";
"pushfl";
"xorl %0, (%%esp)" :: "i" (0x00200000);
"popfl";
"pushfl";
"popl %0" : "=a" (flags);
"xorl (%%esp), %0" : "=a" (flags);
"popfl";
}
return (flags & 0x0020_0000) != 0;
}
The instruction templates for both basic and extended asm can be any
expression that can be evaluated at compile-time to a string, not just string
literals.
uint invert(uint v)
{
uint result;
asm @safe @nogc nothrow pure {
genAsmInsn(`invert`)
: [res] `=r` (result)
: [arg1] `r` (v);
}
return result;
}
The total number of input + output + goto operands is limited to 30.