In each C++ compilation unit that uses assembly statements, you are responsible for including function prototypes to declare each assembly statement that you will be using in that module. In addition, you must include a #pragma intrinsic statement declaring each assembly statement type you wish to use. For example, the following C++ code can be used to accomplish this definition:
extern “C” {
long __asm(char *, ...);
double __dasm(char *, ...);
float __fasm(char *, ...);
};
#pragma intrinsic (__asm, __dasm, __fasm)
Note It is not necessary to perform these declarations in C source modules.
As can be inferred from the declaration above, assembly statements have function call semantics:
Assembly statements are specified using the function names _ _asm, _ _fasm, and _ _dasm. Code supplied via the _ _asm function name is assumed to return an integral result in $0; the other forms of assembler statements return single (_ _fasm) and double-precision (_ _dasm) floating-point results in $f0. You are responsible for arranging your assembly code so as to place the result in the appropriate register. As with any C/C++ function, it is possible to use an assembler statement without using the result, in which case the contents of the result register are ignored.
The assembly statement “body” (first argument) must contain valid assembler input. There may be assembler strings that the compiler fails to fully analyze. When this occurs, the compiler will generate a .S file directly from the assembler “body” and call the assembler to process them. Conservative optimization assumptions will be made when a .ASM file is necessary.
Because the Alpha compiler (unlike the x86 compiler) allows full optimization to occur in the presence of inline assembly code and performs minimization of instruction overhead when entering and leaving the inline assembly code, the following assembly code practices are illegal:
Use caution when using direct references to the stack pointer for anything other than referring to arguments.