ASM (character [, any-type-arg])
Class: Nonelemental function - Generic
Lets you use assembler instructions in an executable program.
The first argument is a character constant or a concatenation of
character constants containing the assembler instructions. The
optional second argument can be of any type. It can be a source or
destination argument for the instruction, for example.
Arguments are passed by value. If you want to pass an argument by
reference (for example, a whole array, a character string, or a
record structure), you can use the %REF built-in function.
Labels are allowed, but all references must be from within the same
ASM function. This lets you set up looping constructs, for
example. Cross-jumping between ASM functions is not permitted.
In general, an ASM function can appear anywhere that an intrinsic
function can be used. Since the supplied assembly code, assembly
directives, or assembly data is integrated into the code stream,
the compiler may choose to use different registers, better code
sequences, and so on, just as if the code were written in Fortran.
You do not have absolute control over instruction sequences and
registers, and the compiler may intersperse other code together
with the ASM code for better performance. Better code sequences
may be substituted by the optimizer if it chooses to do so.
Only register names beginning with a dollar sign ($) or percent
sign (%) are permitted. For more information on register name
conventions, see the OpenVMS operating system documentation set.
+---------+-------------------+-------------+
| Generic | Specific | Result Type |
+---------+-------------------+-------------+
| ASM | ASM (see Note1) | INTEGER*8 |
| | FASM (see Note2) | REAL*4 |
| | DASM (see Note2) | REAL*8 |
+---------+-------------------+-------------+
Note1: The value must be stored in register $0 by the user code.
Note2: The value must be stored in register $F0 by the user code.
Example:
Consider the following:
! Concatenation is recommended for clarity.
! Notice that ";" separates instructions.
!
nine=9
type *, asm('addq %0, $17, $0;'// ! Adds the first two arguments
1 'ldq $22, %6;'// ! and puts the answer in
1 'ldq $23, %7;'// ! register $0
1 'ldq $24, %8;'// !
1 'mov $0, %fp;'// ! Comments are not allowed in the
1 'addq $18, %fp, $0;'// ! constant, but are allowed here
1 'addq $19, $0, $0;'//
1 'addq $20, $0, $0;'//
1 'addq $21, $0, $0;'//
1 'addq $22, $0, $0;'//
1 'addq $23, $0, $0;'//
1 'addq $24, $0, $0;',
1 1,2,3,4,5,6,7,8,nine) ! The actual arguments to the
! ASM (usually by value)
end
This example shows an integer ASM function that adds up 9 values
and returns the sum as its result. Note that the user stores the
function result in register $0.
All arguments are passed by value. The arguments not passed in
registers can be named %6, %7, and %8, which correspond to the
actual arguments 7, 8, and 9 (since %0 is the first argument).
Notice that you can reference reserved registers like %fp.
The compiler creates the appropriate argument list. So, in this
example, the first argument value (1) will be available in register
$16, and the eighth argument value (8) will be available in %7,
which is actually 8($30).