All instructions of x86 processor can not be written in C language. So you will need to write some assembly. For only few instructions you can write it directly in your C code.
Because of gcc options, you can not use
asm keyword. You can use
__asm__ instead. Add the keyword
volatile to avoid compiler move your code for optimizations:
__asm__ volatile("instruction\n" "instruction");
By default gcc uses AT&T assembly syntax (
operation source, destination). Register names are prefixed by
% and immediate operands by
__asm__ volatile("movw $0x10, %ax"); //put 16 in ax register, movw means mov word
Assembly with C expression operands
__asm__ volatile("instructions %[id]" : output_variables : input_variables : clobber);
The format for output and input is : [id] “constraint” (expression), where:
- [id] is the matching identifier in the instructions part.
- “constraint” is a constraint on the operand. For example “r” means that the value should be in a general register, “i” is for integers. All output constraints must start by ‘=’. More about constraints in gcc documentation.
- (expression) is a C expression.
To avoid any confusion with registers names, they must be prefixed by
%% instead of
Identifiers are not necessary, you can number the operands. In this case, you have to number them according to their order in both output and input lists.
__asm__ volatile("mov %0, %%eax": : "i"(42)); //result and new_angle are C variables: __asm__ volatile ("fsinx %1,%0" : "=f" (result) : "f" (new_angle)); //with identifiers: __asm__ volatile ("fsinx %[angle],%[output]" : [output] "=f" (result) : [angle] "f" (new_angle));