__asm Keyword in MIPS Inline Assembly (Windows Embedded CE 6.0)
1/5/2010
The __asm keyword invokes the inline assembler, and can appear anywhere in a C or C++ statement. The compiler treats the __asm statement as an intrinsic function call. You must include a #pragma intrinsic statement that declares an __asm keyword.
The following C++ code shows how to declare __asm with a #pragma directive.
extern "C" {
void _asm (char*,...);
};
#pragma intrinsic (__asm)
It is not necessary to perform these declarations in C source modules.
In an __asm declaration, the string argument is a null terminated character string consisting of one or more assembly language statements. The compiler passes any subsequent arguments to the assembly code described by the first string argument.
The following example generates instructions to multiply 4 and 5, and store the result in the t0 register. In this example, the reference to %0 refers the value "4" to the first argument in the generated assembly code. %1 refers the value "5" to the second argument in the generated assembly code.
__asm("mul t0, %0, %1", 4, 5);
Within the string argument of the __asm prototype, an embedded semicolon (;) or newline (\n) is used to separate multiple assembly language statements. The following example shows how to use a semicolon to signify multiple assembly language statements.
__asm(".set noat;"
"mult $1, $4, $5; "
".set at ");
Loading function addresses with inline assembly
The MIPS inline assembler uses the pseudo-op la to load the address of a function to a register. When compiling with /Og, this causes the compiler to generate the following error message:
Error C2759: inline assember reports function literal used with call optimization
If you want to compile your code with /Og, you will need to replace the la pseudo-op with with other constructions that do not cause a compiler error.
The following code example shows such a replacement.
Replace this code construction
__asm("la v0, f");
with the following code construction:
__asm("move v0,%0", f);