HP OpenVMS Systems Documentation

Content starts here

VAX MACRO and Instruction Set Reference Manual

Previous Contents Index

3.6 Unary Operators

A unary operator modifies a term or an expression and indicates an action to be performed on that term or expression. Expressions modified by unary operators must be enclosed in angle brackets. You can use unary operators to indicate whether a term or expression is positive or negative. If unary plus or minus is not specified, the default value is assumed to be plus. In addition, unary operators perform radix conversion, textual conversion (including ASCII conversion), and numeric control operations, as described in the following sections. Table 3-3 summarizes the unary operators.

Table 3-3 Unary Operators
Unary Operator Operator Name Example Operation
+ Plus sign +A Results in the positive value of A
- Minus sign -A Results in the negative (two's complement) value of A
^B Binary ^B11000111 Specifies that 11000111 is a binary number
^D Decimal ^D127 Specifies that 127 is a decimal number
^O Octal ^O34 Specifies that 34 is an octal number
^X Hexadecimal ^XFCF9 Specifies that FCF9 is a hexadecimal number
^A ASCII ^A/ABC/ Produces an ASCII string; the characters between the matching delimiters are converted to ASCII representation
^M Register mask #^M<R3,R4,R5> Specifies the registers R3, R4, and R5 in the register mask
^F Floating-point ^F3.0 Specifies that 3.0 is a floating-point number
^C Complement ^C24 Produces the one's complement value of 24 (decimal)

More than one unary operator can be applied to a single term or to an expression enclosed in angle brackets. For example:


This construct is equivalent to:


3.6.1 Radix Control Operators

VAX MACRO accepts terms or expressions in four different radixes: binary, decimal, octal, and hexadecimal. The default radix is decimal. Expressions modified by radix control operators must be enclosed in angle brackets.




A string of characters that is legal in the specified radix. The following are the legal characters for each radix:
Format Radix Name Legal Characters
^Bnn Binary 0 and 1
^Dnn Decimal 0 to 9
^Onn Octal 0 to 7
^Xnn Hexadecimal 0 to 9 and A to F

Radix control operators can be included in the source program anywhere a numeric value is legal. A radix control operator affects only the term or expression immediately following it, causing that term or expression to be evaluated in the specified radix.

For example:

.WORD   ^B00001101              ; Binary radix
.WORD   ^D123                   ; Decimal radix (default)
.WORD   ^O47                    ; Octal radix
.WORD   <A+^O13>                ; 13 is in octal radix
.LONG   ^X<F1C3+FFFFF-20>       ; All numbers in expression
                                ;   are in hexadecimal radix

The circumflex (^) cannot be separated from the B, D, O, or X that follows it, but the entire radix control operator can be separated by spaces and tabs from the term or expression that is to be evaluated in that radix.

The default decimal operator is needed only within an expression that has another radix control operator. In the following example, "16" is interpreted as a decimal number because it is preceded by the decimal operator ^D even though the "16" is in an expression prefixed by the octal radix control operator.

.LONG    ^O<10000 + 100 + ^D16>

3.6.2 Textual Operators

The textual operators are the ASCII operator (^A) and the register mask operator (^M). ASCII Operator

The ASCII operator converts a string of printable characters to their 8-bit ASCII values and stores them 1 character to a byte. The string of characters must be enclosed in a pair of matching delimiters.

The delimiters can be any printable character except the space, tab, or semicolon. Use nonalphanumeric characters to avoid confusion.




A delimited ASCII string from 1 to 16 characters long.

The delimited ASCII string must not be larger than the data type of the operand. For example, if the ^A operator occurs in an operand in a Move Word (MOVW) instruction (the data type is a word), the delimited string cannot be more than 2 characters.

For example:

.QUAD   ^A%1234/678%    ; Generates 8 bytes of ASCII data
MOVL    #^A/ABCD/,R0    ; Moves characters ABCD
                        ;   into R0 right justified with
                        ;   "A" in low-order byte and "D"
                        ;   in high-order byte
CMPW    #^A/XY/,R0      ; Compares X and Y as ASCII
                        ;   characters with contents of low
                        ;   order 2 bytes of R0
MOVL    #^A/AB/,R0      ; Moves ASCII characters AB into
                        ;   R0; "A" in low-order byte; "B" in
                        ;   next; and zero the 2 high-order bytes Register Mask Operator

The register mask operator converts a register name or a list of register names enclosed in angle brackets into a 1- or 2-byte register mask. The register mask is used by the Push Registers (PUSHR) and Pop Registers (POPR) instructions and the .ENTRY and .MASK directives (see Chapter 6).




One of the register names or the DV or IV arithmetic trap-enable specifiers.


A list of register names and the DV and IV arithmetic trap-enable specifiers, separated by commas.

The register mask operator sets a bit in the register mask for every register name or arithmetic trap enable specified in the list. The bits corresponding to each register name and arithmetic trap-enable specifier follow.

Register Name Arithmetic Trap Enable Bits
R0 to R11   0 to 11
R12 or AP   12
FP   13
SP IV 14
  DV 15

When the POPR or PUSHR instruction uses the register mask operator, R0 to R11, R12 or AP, FP, and SP can be specified. You cannot specify the PC register name and the IV and DV arithmetic trap-enable specifiers.

When the .ENTRY or .MASK directive uses the register mask operator, you can specify R2 to R11 and the IV and DV arithmetic trap-enable specifiers. However, you cannot specify R0, R1, FP, SP, and PC. IV sets the integer overflow trap, and DV sets the decimal string overflow trap.

The arithmetic trap-enable specifiers are described in Chapter 8.

For example:

.ENTRY RT1,^M<R3,R4,R5,R6,IV>   ; Save registers R3, R4,
                                ;   R5, and R6 and set the
                                ;   integer overflow trap

PUSHR  #^M<R0,R1,R2,R3>         ; Save registers R0, R1,
                                ;   R2, and R3

POPR   #^M<R0,R1,R2,R3>         ; Restore registers R0, R1,
                                ;   R2, and R3

3.6.3 Numeric Control Operators

The numeric control operators are the floating-point operator (^F) and the complement operator (^C). The use of the numeric control operators is explained in Section and Section Floating-Point Operator

The floating-point operator accepts a floating-point number and converts it to its internal representation (a 4-byte value). This value can be used in any expression. VAX MACRO does not perform floating-point expression evaluation.




A floating-point number (see Section 3.2.2).

The floating-point operator is useful because it allows a floating-point number in an instruction that accepts integers.

For example:

MOVL      #^F3.7,R0      ; NOTE: the recommended instruction
                         ;   to move this floating-point
MOVF      #3.7,R0        ;   number is the MOVF instruction Complement Operator

The complement operator produces the one's complement of the specified value.




Any term or expression. If an expression is specified, it must be enclosed in angle brackets.

VAX MACRO evaluates the term or expression as a 4-byte value before complementing it.

For example:

.LONG      ^C^XFF      ; Produces FFFFFF00 (hex)
.LONG      ^C25        ; Produces complement of
                       ;   25 (dec) which is
                       ;   FFFFFFE6 (hex)

3.7 Binary Operators

In contrast to unary operators, binary operators specify actions to be performed on two terms or expressions. Expressions must be enclosed in angle brackets. Table 3-4 summarizes the binary operators.

Table 3-4 Binary Operators
Binary Operator Operator Name Example Operation
+ Plus sign A+B Addition
- Minus sign A-B Subtraction
* Asterisk A*B Multiplication
/ Slash A/B Division
@ At sign A@B Arithmetic shift
& Ampersand A&B Logical AND
! Exclamation point A!B Logical inclusive OR
\ Backslash A\B Logical exclusive OR

All binary operators have equal priority. Terms or expressions can be grouped for evaluation by enclosing them in angle brackets. The enclosed terms and expressions are evaluated first, and remaining operations are performed from left to right. For example:

.LONG      1+2*3      ; Equals 9
.LONG      1+<2*3>    ; Equals 7

Note that a 4-byte result is returned from all binary operations. If you use a 1-byte or 2-byte operand, the result is the low-order bytes of the 4-byte result. VAX MACRO displays an error message if the truncation causes a loss of significance.

The following sections describe the arithmetic shift, logical AND, logical inclusive OR, and logical exclusive OR operators.

3.7.1 Arithmetic Shift Operator

You use the arithmetic shift operator (@) to perform left and right arithmetic shifts of arithmetic quantities. The first argument is shifted left or right by the number of bit positions that you specify in the second argument. If the second argument is positive, the first argument is shifted left; if the second argument is negative, the first argument is shifted right. When the first argument is shifted left, the low-order bits are set to zero. When the first argument is shifted right, the high-order bits are set to the value of the original high-order bit (the sign bit).

For example:

        .LONG   ^B101@4              ; Yields 1010000 (binary)
        .LONG   1@2                  ; Yields 100 (binary)
A = 4
        .LONG   1@A                  ; Yields 10000 (binary)
        .LONG   ^X1234@-A            ; Yields 123(hex)
        MOVL    #<^B1100000@-5>,R0   ; Yields 11 (binary)

3.7.2 Logical AND Operator

The logical AND operator (&) takes the logical AND of two operands.

For example:

A = ^B1010
B = ^B1100
        .LONG   A&B             ; Yields 1000 (binary)

3.7.3 Logical Inclusive OR Operator

The logical inclusive OR operator (!) takes the logical inclusive OR of two operands.

For example:

A = ^B1010
B = ^B1100
        .LONG   A!B             ; Yields 1110 (binary)

3.7.4 Logical Exclusive OR Operator

The logical exclusive OR operator (\) takes the logical exclusive OR of two arguments.

For example:

A = ^B1010
B = ^B1100
        .LONG   A\B             ; Yields 0110 (binary)

3.8 Direct Assignment Statements

A direct assignment statement equates a symbol to a specific value. Unlike a symbol that you use as a label, you can redefine a symbol defined with a direct assignment statement as many times as you want.




A user-defined symbol.


An expression that does not contain any undefined symbols (see Section 3.5).

The format with a single equal sign (=) defines a local symbol and the format with a double equal sign (==) defines a global symbol. See Section 3.3.3 for more information about local and global symbols.

The following three syntactic rules apply to direct assignment statements:

  • An equal sign (=) or double equal sign (==) must separate the symbol from the expression which defines its value. Spaces preceding or following the direct assignment operators have no significance in the resulting value.
  • Only one symbol can be defined in a single direct assignment statement.
  • A direct assignment statement can be followed only by a comment field.

By Compaq convention, the symbol in a direct assignment statement is placed in the label field.

For example:

A == 1                  ; The symbol 'A' is globally
                        ;   equated to the value 1

B = A@5                 ; The symbol 'B' is equated
                        ;   to 1@5 or 20(hex)

C = 127*10              ; The symbol 'C' is equated
                        ;   to 1270(dec)

D = ^X100/^X10          ; The symbol 'D' is equated
                        ;   to 10(hex)

3.9 Current Location Counter

The symbol for the current location counter, the period (.), always has the value of the address of the current byte. VAX MACRO sets the current location counter to zero at the beginning of the assembly and at the beginning of each new program section.

Every VAX MACRO source statement that allocates memory in the object module increments the value of the current location counter by the number of bytes allocated. For example, the directive .LONG 0 increments the current location counter by 4. However, with the exception of the special form described below, a direct assignment statement does not increase the current location counter because no memory is allocated.

The current location counter can be explicitly set by a special form of the direct assignment statement. The location counter can be either incremented or decremented. This method of setting the location counter is often useful when defining data structures. Data storage areas should not be reserved by explicitly setting the location counter; use the .BLKx directives (see Chapter 6).




An expression that does not contain any undefined symbols (see Section 3.5).

In a relocatable program section, the expression must be relocatable; that is, the expression must be relative to an address in the current program section. It may be relative to the current location counter.

For example:

. = .+40        ; Moves location counter forward

When a program section that you defined in the current module is continued, the current location counter is set to the last value of the current location counter in that program section.

When you use the current location counter in the operand field of an instruction, the current location counter has the value of the address of that operand; it does not have the value of the address of the beginning of the instruction. For this reason, you would not normally use the current location counter as a part of the operand specifier.

Previous Next Contents Index