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).