Inline Assembly
C3 provides two ways to insert inline assembly code: asm strings and asm blocks.
Assembly strings¶
This form takes a single compile time string and passes it directly to the underlying backend without any changes.
Assembly blocks¶
Assembly blocks use a common grammar for all types of processors. C3's asm implementation assumes that all assembly statements can be reduced to variations of the following general format:
Where an arg is:
- An identifier, e.g.
FOO,x. - A numeric constant
10xFFetc. - A register name (always lower case with a '$' prefix) e.g.
$eax$r7. - The address of a variable e.g.
&x. - An indirect address:
[addr]or[addr + index * <const> + offset]. - Any expression inside of "()" (will be evaluated before entering the
asmblock).
An example:
int aa = 3;
int g;
int* gp = &g;
int* xa = &aa;
sz asf = 1;
asm
{
movl x, 4; // Move 4 into the variable x
movl [gp], x; // Move the value of x into the address in gp
movl x, 1; // Move 1 into x
movl [xa + asf * 4 + 4], x; // Move x into the address at xa[asf + 1]
movl $eax, (23 + x); // Move 23 + x into EAX
movl x, $eax; // Move EAX into x
movq [&z], 33; // Move 33 into the memory address of z
}
Note
The current state of inline asm is a work in progress. Only a subset of x86, aarch64 and riscv instructions are available, and other platforms have no support at all. It is likely that the grammar will be extended as more architectures are supported. More instructions can be added as they are needed, so please file issues when you encounter missing instructions you need.