Previous [TOC] Next

| 7 Assignment Instructions

The assignment instructions move words, double words, bytes, and arbitrary fields of words between the stack and memory. These include the immediate instructions, which obtain their operands from the code stream, the frame instructions, used to access local and global variables, and the instructions that dereference pointers (direct and indirect). The string and field instructions read and write substructures smaller than a word.

Design Note: In instructions that access both the stack and memory, if both a fault error and a stack error are possible, it is undefined which will occur first.

### 7.1 Immediate Instructions

The immediate instructions load one- or two-word constants onto the stack. Operands (if any) are obtained from the code stream.

#### LIN1 Load Immediate Negative One

    LIN1: PROCEDURE =
        BEGIN
        Push[177777B];
        END;

#### LINI Load Immediate Negative Infinity

    LINI: PROCEDURE =
        BEGIN
        Push[l00000B];
        END;

#### LI00 Load Immediate Double Zero

    LI00: PROCEDURE =
        BEGIN
        PushLong[LONG[O]];
        END;

#### LIn Load Immediate n

    LIn: PROCEDURE [n: [O..lO)] =
        BEGIN
        Push[n];
        END;

#### LIB Load Immediate Byte

    LIB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[alpha];
        END;

#### LINB Load Immediate Negative Byte

Note that alpha is not sign-extended.

    LINB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[BytePair[377B, alpha]];
        END;

#### LIHB Load Immediate High Byte

    LIHB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[BytePair[alpha, 0]];
        END;

#### LIW Load Immediate Word

    LIW: PROCEDURE =
        BEGIN u: UNSPECIFIED = GetCodeWord[];
        Push[u];
        END;

### 7.2 Frame Instructions

The local and global frame instructions move one or two words between the stack and the frame. The opcodes differ primarily in their addressing modes: for frequently addressed variables, the offset of the variable in the frame is given by the instruction's opcode. Less frequently referenced frame variables are addressed by a one-byte offset obtained from alpha. Instructions are also provided for generating the address of a local or global variable.

### 7.2.l Local Frame Access

The load local, store local, and put local instructions provide access to the local frame variables of the current context. The local-address instructions each generate a short pointer to a local variable, given its offset in the frame.

#### LAn Local Address n

    LAn: PROCEDURE [n: [0..3,6,8]] =
        BEGIN
        Push[LF + n];
        END;

#### LAB Local Address Byte

    LAB: PROCEDURE =
         BEGIN
         alpha: BYTE = GetCodeByte[];
         Push[LF + alpha];
         END;

#### LAW Local Address Word

    LAW: PROCEDURE =
        BEGIN
        word: UNSPECIFIED = GetCodeWord[];
        Push[LF + word];
        END;

Programming Note: Local variables at offsets larger than 255 words from the base of the frame can be accessed by generating their addresses on the stack and then using the direct pointer instructions defined in §7.3.1.

### 7.2.1.1 Load Local

The load local instructions move one or two words onto the stack from the local frame.

#### LLn Load Local n

    LLn: PROCEDURE [n: [O..ll]] =
        BEGIN
        Push[FetchMds[LF + n]];
        END;

#### LLB Load Local Byte

    LLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[FetchMds[LF + alpha]];
        END;

#### LLDn Load Local Double n

    LLDn: PROCEDURE [n: [0..8,10]] =
        BEGIN
        Push[FetchMds[LF + n]];
        Push[FetchMds[LF + n + 1]];
        END;

#### LLDB Load Local Double Byte

    LLDB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[FetchMds[LF + alpha]];
        Push[FetchMds[LF + alpha + 1]];
        END;

### 7.2.1.2 Store Local

The store local instructions move one or two words from the stack to the local frame.

#### SLn Store Local n

    SLn: PROCEDURE [n: [o..10]] =
        BEGIN
        StoreMds[LF + n]  Pop[];
        END;

#### SLB Store Local Byte

    SLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        StoreMds[LF + alpha]  Pop[];
        END;

#### SLDn Store Local Double n

    SLDn: PROCEDURE [n: [0..6,8]] =
        BEGIN
        StofeMds[LF + n + 1]  Pop[];
        StoreMds[LF + n]  Pop[];
        END;

#### SLDB Store Local Double Byte

    SLDB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        StoreMds[LF + alpha + 1]  Pop[];
        StoreMds[LF + alpha]  Pop[];
        END;

### 7.2.1.3 Put Local

The put local instructions move one or two words from the stack into the local frame, leaving its operands on the stack.

#### PLn Put Local n

    PLn: PROCEDURE [n: [0..3]] =
        BEGIN
        SLn[n];
        Recover[];
        END;

#### PLB Put Local Byte

    PLB: PROCEDURE [n: [O..3]] =
        BEGIN
        SLB[];
        Recover[];
        END;

#### PLD0 Put Local Double Zero

    PLDO: PROCEDURE =
        BEGIN
        SLDn[O];
        Recover[];
        Recover[];
        END;

#### PLDB Put Local Double Byte

    PLDB: PROCEDURE =
        BEGIN
        SLDB[];
        Recover[];
        Recover[];
        END;

### 7.2.1.4 Add Local

The Add Local Zero to Immediate Byte instruction adds local zero and a small constant from alpha and pushes the sum on the stack.

#### AL0IB Add Local Zero to Immediate Byte

    AL0IB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[FetchMds[LF]  alpha];
        END;

### 7.2.2 Global Frame Access

The load global and store global instructions provide access to the global frame variables of the current context. The global address instruction generates a short pointer to a global variable, given its offset in the frame.

#### GAn Global Address n

    GAn: PROCEDURE [n: [0..1]] =
        BEGIN
        Push[GF + n];
        END;

#### GAB Global Address Byte

    GAB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[GF + alpha];
        END;

#### GAW Global Address Word

    GAW: PROCEDURE =
        BEGIN
        word: UNSPECIFIED = GetCodeWord[];
        Push[GF + word];
        END;

Programming Note: Global variables at offsets larger than 255 words from the base of the frame can be accessed by generating their addresses on the stack and then using the direct pointer instructions defined in §7.3.1.

### 7.2.2.l Load Global

The load global instructions move one or two words onto the stack from the global frame.

#### LGn Load Global n

    LGn: PROCEDURE [n: [0..2]] =
        BEGIN
        Push[FetchMds[GF + n]];
        END;

#### LGB Load Global Byte

    LGB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[FetchMds[GF + alpha]];
        END;

#### LGDn Load Global Double n

    LGDn: PROCEDURE [n: [0,2]] =
        BEGIN
        Push[FetchMds[GF+ n]];
        Push[FetchMds[GF + n + 1]];
        END;

#### LGDB Load Global Double Byte

    LGDB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        Push[FetchMds[GF + alpha]];
        Push[FetchMds[GF + alpha + 1]];
        END;

### 7.2.2.2 Store Global

The store global instructions move one or two words from the stack to the global frame.

#### SGB Store Global Byte

    SGB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        StoreMds[GF + alpha]  Pop[];
        END;

#### SGDB Store Global Double Byte

    SGDB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        StoreMds[GF + alpha + 1]  Pop[];
        StoreMds[GF + alpha]  Pop[];
        END;

### 7.3 Pointer Instructions

The pointer instructions are divided into two types: direct and indirect. They move a word or pair of words between the stack and memory using a pointer obtained from the stack or from the local or global frame. Most pointer instructions have variants that dereference either short or long pointers.

Implementation Note: In the long-pointer variants of these instructions, any addition to the pointer must be calculated using double-word arithmetic, to account for the case in which `ptr + offset` may carry into the most significant word of the pointer.

### 7.3.1 Direct Pointer Instructions

The direct pointer instructions obtain a pointer from the stack and move a single or double word stack operand to or from the specified location. The pointer is usually modified by a small offset contained in the opcode or alpha.

### 7.3.1.1 Read Direct

The read direct instructions obtain a long or short pointer from the stack, add to it a small displacement from the opcode or alpha, and perform a single- or double-word push to the stack from memory.

#### Rn Read n

    Rn: PROCEDURE [n: [0..1]] =
        BEGIN
        ptr: POINTER = Pop[];
        Push[FetchMds[ptr + n]];
        END;

#### RB Read Byte

    RB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: POINTER = Pop[];
        Push[FetchMds[ptr + alpha]];
        END;

#### RLO Read Long Zero

    RLO: PROCEDURE =
        BEGIN
        ptr: LONG POINTER = PopLong[];
        Push[Fetch[ptr]];
        END;

#### RLB Read Long Byte

    RLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: LONG POINTER = PopLong[];
        Push[Fetch[ptr + LONG[alpha]]];
        END;

#### RD0 Read Double Zero

    RD0: PROCEDURE =
        BEGIN
        ptr: POINTER = Pop[];
        u: UNSPECIFIED = FetchMds[ptr];
        v: UNSPECIFIED = FetchMds[ptr + 1];
        Push[u]; Push[v];
        END;

#### RDB Read Double Byte

    RDB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: POINTER = Pop[];
        u: UNSPECIFIED = FetchMds[ptr + alpha];
        v: UNSPECIFIED = FetchMds[ptr + alpha + 1];
        Push[u]; Push[v];
        END;

#### RDL0 Read Double Long Zero

    RDL0: PROCEDURE =
        BEGIN
        ptr: LONG POINTER = PopLong[];
        u: UNSPECIFIED = Fetch[ptr];
        v: UNSPECIFIED = Fetch[ptr + 1];
        Push[u]; Push[v];
        END;

#### RDLB Read Double Long Byte

    RDLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: LONG POINTER = PopLong[];
        u: UNSPECIFIED = Fetch[ptr + LONG[alpha]];
        v: UNSPECIFIED = Fetch[ptr + LONG[aipha] + 1];
        Push[u]; Push[v];
        END;

#### RC Read Code

    RC: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        offset: CARDINAL = Pop[];
        Push[ReadCode[offset + alpha]];
        END;

### 7.3.1.2 WriteDirect

The write direct instructions obtain a long or short pointer from the stack, add to it a small displacement from the opcode or alpha, and perform a single- or double-word pop from the stack to memory.

#### W0 Write Zero

    W0: PROCEDURE =
        BEGIN
        ptr: POINTER = Pop[];
        StoreMds[ptr]  Pop[];
        END;

#### WB Write Byte

    WB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: POINTER = Pop[];
        StoreMds[ptr + alpha]  Pop[];
        END;

#### WLB Write Long Byte

    WLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: LONG POINTER = PopLong[];
        Store[ptr + LONG[alpha]]  Pop[];
        END;

#### WDB Write Double Byte

    WDB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: POINTER = Pop[];
        StoreMds[ptr + alpha + 1]  Pop[];
        StoreMds[ptr + alpha]  Pop[];
        END;

#### WDLB Write Double Long Byte

    WDLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        ptr: LONG POINTER = PopLong[];
        Store[ptr + LONG[alpha] + 1]  Pop[];
        Store[ptr + LONG[alpha]]  Pop[];
        END;

### 7.3.1.3 Put Swapped Direct

The put swapped direct instructions obtain a short pointer from the stack, add to it a small displacement from the opcode or alpha, and perform a single- or double-word store to memory. They leave the pointer on the stack for use by subsequent instructions. ("Swapped" refers to the order of the address and the data on the stack. The data is given first (from the top down) followed by the address for swapped instructions).

#### PSB Put Swapped Byte

    PSB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        u: UNSPECIFIED = Pop[];
        ptr: POINTER = Pop[];
        StoreMds[ptr + alpha]  u;
        Recover[];
        END;

#### PSD0 Put Swapped Double Zero

    PSD0: PROCEDURE =
        BEGIN
        v: UNSPECIFIED = Pop[];
        u: UNSPECIFIED = Pop[];
        ptr: POINTER = Pop[];
        StoreMds[ptr + 1]  v;
        StoreMds[ptr]  u;
        Recover[];
        END;

#### PSDB Put Swapped Double Byte

    PSDB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        v: UNSPECIFIED = Pop[];
        u: UNSPECIFIED = Pop[];
        ptr: POINTER = Pop[];
        StoreMds[ptr + alpha + 1]  v;
        StoreMds[ptr + alpha]  u;
        Recover[];
        END;

#### PSLB Put Swapped Long Byte

    PSLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        u: UNSPECIFIED = Pop[];
        ptr: LONG POINTER = PopLong[];
        Store[ptr + LONG[alpha]]  u;
        Recover[];
        Recover[];
        END;

#### PSDLB Put Swapped Double Long Byte

    PSDLB: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        v: UNSPECIFIED = Pop[];
        u: UNSPECIFIED = Pop[];
        ptr: LONG POINTER = PopLong[];
        Store[ptr + LONG[alpha] + 1]  v;
        Store[ptr + LONG[alpha]]  u;
        Recover[];  Recover[];
        END;

### 7.3.2 Indirect Pointer Instructions

The indirect pointer instructions obtain a pointer from the local or global frame or the stack and move a single- or double-word stack operand to or from the specified location. The pointer is modified by a small offset contained in the opcode or alpha.

### 7.3.2.1 Read Indirect

The read indirect instructions perform a single- or double-word push using a pointer obtained from the local or global frame. Most of these instructions treat alpha as a pair; pair.left specifies the offset of the pointer in the frame, and pair.right is added to the pointer.

#### RLI0n Read Local indirect Zero n

    RLI0n: PROCEDURE [n: [0..3]] =
        BEGIN
        ptr: POINTER = FetchMds[LF];
        Push[FetchMds[ptr + n];
        END;

#### RLIP Read Local Indirect Pair

    RLIP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: POINTER = FetchMds[LF + pair.left];
        Push[FetchMds[ptr + pair.right]];
        END;

#### RLILP Read Local Indirect Long Pair

    RLILP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: LONG POINTER = ReadDblMds[LF + pair.left];
        Push[Fetch[ptr + LONG[pair.right]]];
        END;

#### RGIP Read Global Indirect Pair

    RGIP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: POINTER = FetchMds[GF + pair.left];
        Push[FetchMds[ptr + pair.right]];
        END;

#### RGILP Read Global Indirect Long Pair

    RGILP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: LONG POINTER = ReadDblMds[GF + pair.left];
        Push[Fetch[ptr + LONG[pair.right]]];
        END;

#### RLDIOO Read Local Double Indirect Zero Zero

    RLDIOO: PROCEDURE =
        BEGIN
        ptr: POINTER = FetchMds[LF];
        u: UNSPECIFIED = FetchMds[ptr];
        v: UNSPECIFIED = FetchMds[ptr + 1];
        Push[u]; Push[v];
        END;

#### RLDIP Read Local Double Indirect Pair

    RLDIP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        Ptr: POINTER = FetchMds[LF + pair.left];
        u: UNSPECIFIED = FetchMds[ptr + pair.right];
        v: UNSPECIFIED = FetchMds[ptr + pair.right + 1];
        Push[u]; Push[v];
        END;

#### RLDILP Read Local Double Indirect Long Pair

    RLDILP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: LONG POINTER = ReadDblMds[LF + pair.left];
        u: UNSPECIFIED = Fetch[ptr + LONG[pair.right]];
        v: UNSPECIFIED = Fetch[ptr + LONG[pair.right] + 1];
        Push[u]; Push[v];
        END;

### 7.3.2.2 Write Indirect

The write indirect instructions perform a single- or double-word pop to memory using a pointer obtained from the local frame. They treat alpha as a pair, in which pair.1eft specifies the offset of the pointer in the frame, and pair.right is added to the pointer.

#### WLlP Write Local Indirect Pair

    WLIP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: POINTER = FetchMds[LF + pair.left];
        StoreMds[ptr + pair.right]  Pop[];
        END;

#### WLlLP Write Local Indirect Long Pair

    WLILP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: LONG POINTER = ReadDblMds[LF + pair.left];
        Store[ptr + LONG[pair.right]]  Pop[];
        END;

#### WLDILP Write Local Double Indirect Long Pair

    WLDILP: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        ptr: LONG POINTER = ReadDblMds[LF + pair.left];
        Store[ptr + LONG[pair.right] + 1]  Pop[];
        Store[ptr + LONG[pair.right]]  Pop[];
        END;

### 7.4 String Instructions

The string instructions read or write eight-bit bytes contained in packed arrays. The address of the word containing the byte is computed as the sum of a short or long pointer obtained from the stack plus a byte offset divided by two. The offset is the sum of an index taken from the stack and the instruction's alpha byte.

Figure 7.1 String Indexing

The least significant bit of the offset selects the byte that is read or written; zero specifies the most significant byte. The data byte is obtained from the stack, ignoring the high order byte of the stack word, or written to the stack, clearing the high-order byte. The following routines are used by the string instructions (and elsewhere) to fetch and store a byte:

    FetchByte: PROCEDURE [ptr: LONG POINTER, offset: LONG CARDINAL]
        RETURNS [BYTE] =
        BEGIN
        word: BytePair = Fetch[ptr + offset/2];
        RETURN[IF (offset MOD 2) = 0 THEN word.left ELSE word.right];
        END;

    StoreByte: PROCEDURE [ptr: LONG POINTER, offset: LONG CARDINAL, data: BYTE] =
        BEGIN
        word: BytePair = Fetch[ptr + offset/2];
        Store[ptr + offset/2]  IF (offset MOD 2) = 0
            THEN BytePair[data, word.right]
            ELSE BytePair[word.left, data];
        END;

Implementation Note: In the long-pointer variants of these instructions, the offset must be calculated using double-word arithmetic, to account for the case in which alpha + index may carry into the most significant word of the pointer.

### 7.4.1 Read String

The read string instructions clear the high-order byte of the data word written to the stack.

#### RS Read String

    RS: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        index: CARDINAL = Pop[];
        ptr: POINTER = Pop[];
        Push[FetchByte[ptr: ptr, offset: alpha + index]];
        END;

#### RLS Read Long String

    RLS: PROCEDURE =
    BEGIN
        alpha: BYTE = GetCodeByte[];
        index: CARDINAL = Pop[];
        ptr=: LONG POINTER = PopLong[];
        Push[FetchByte[ptr: ptr, offset: LONG[aipha] + LONG[index]]];
        END;

### 7.4.2 Write String

The write string instructions ignore the high-order byte of the data word obtained from the stack.

#### WS Write String

    WS: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        index: CARDINAL = Pop[];
        ptr: POINTER = Pop[];
        data: BYTE = LowByte[Pop[]];
        StoreByte[ptr: ptr, offset: alpha + index, data: data];
        END;

#### WLS Write Long String

    WLS: PROCEDURE =
        BEGIN
        alpha: BYTE = GetCodeByte[];
        index: CARDINAL = Pop[];
        ptr: LONG POINTER = PopLong[];
        data: BYTE = LowByte[Pop[]];
        StoreByte[ptr: ptr, offset: LONG[alpha] + LONG[index], data: data];
        END;

### 7.5 Field Instructions

The field instructions either read or write a field of a word in memory. The word is usually addressed by a short or long pointer found on the stack. The read indirect operations obtain the required pointer from the local frame.

The field is described by a field specifier or a field descriptor, which is usually found in the alpha and beta bytes of the instruction. The stack operations take their field descriptors from the stack. Field specifiers are defined as follows:

    FieldSpec: TYPE = MACHINE DEPENDENT RECORD [
        pos(0: 0..3): NIBBLE,
        size(0: 4..7): NIBBLE];

The pos specifies the most significant bit of the field (the most significant bit of a word is bit zero), and size is one less than the width of the field in bits (a field never has zero width). Figure 7.2 illustrates some examples of field specifiers.

Note that fields described by field specifiers do not cross word boundaries.

In addition to field specifiers, some instructions include an offset, a quantity added to the pointer to obtain the address of the word containing the field. This offset is included in a field descriptor.

Figure 7.2 Field Specifiers

    FieldDesc: TYPE = MACHINE DEPENDENT RECORD[
        offset(0: 0..7): BYTE,
        field(0: 8..15): FieldSpec]];

The following routines are used by the field instructions (and elsewhere) to perform the basic functions of field extraction and insertion:

    MaskTable: ARRAY [0..WordSize) OF UNSPECIFIED = [
        1, 3, 7, 17B, 37B, 77B, l77B, 377B, 777B,1777B,
        3777B, 7777B, 17777B, 37777B, 77777B, 177777B];

    ReadField: PROCEDURE [source: UNSPECIFIED, spec: FieldSpec]
        RETURNS [UNSPECIFIED] =
        BEGIN
        shift: CARDINAL[O..WordSize);
        IF spec.pos + spec.size + 1 > WordSize THEN ERROR;
        shift  WordSize - (spec.pos + spec.size + 1);
        RETURN[And[Shift[source, -shift], MaskTable[spec.size]]];
        END;

    WriteField: PROCEDURE [dest: UNSPECIFIED, spec: FieldSpec, data: UNSPECIFIED]
        RETURNS [UNSPECIFIED] =
        BEGIN
        mask: UNSPECIFIED;
        shift: CARDlNAL[O..WordSize);
        IF spec.pos + spec.size + 1 > WordSize THEN ERROR;
        shift  WordSize-(spec.pos + spec.size + 1);
        mask  Shift[MaskTable[spec.size], shift];
        data  And[Shift[data, shift], mask];
        RETURN[Or[And[dest, Not[mask]], data]];
        END;

Design Note: If an instruction contains a field specifier in which pos + size + 1 > WordSize, the results are undefined.

### 7.5.1 Read Field

The read field instructions push a field from a word in memory onto the stack. They righ-justify the word and supply high-order zeros if necessary.

#### RF Read Field

    RF: PROCEDURE =
        BEGIN
        desc: FieldDesc = GetCodeWord[];
        ptr: POINTER = Pop[];
        Push[ReadField[FetchMds[ptr + desc.offset], desc.field]];
        END;

#### ROF Read Zero Field

    ROF: PROCEDURE =
        BEGIN
        spec: FieldSpec = GetCodeByte[];
        ptr: POINTER = Pop{];
        Push[ReadField[FetchMds[ptr], spec]];
        END;

#### RLF Read Long Field

    RLF: PROCEDURE =
        BEGIN
        desc: FieldDesc = GetCodeWord[];
        ptr: LONG POINTER = PopLong[];
        Push[ReadField[Fetch[ptr + LONG[desc.offset]], desc.field]];
        END;

#### RL0F Read Long Zero Field

    RLOF: PROCEDURE =
        BEGIN
        spec: FieldSpec = GetCodeByte[];
        ptr: LONG POINTER = PopLong[];
        Push[ReadField[Fetch[ptr], spec]];
        END;

#### RLFS Read Long Field Stack

    RLFS: PROCEDURE =
        BEGIN
        desc: FieldDesc = Pop[];
        ptr: LONG POINTER = PopLong[];
        Push[ReadField[Fetch[ptr + LONG[desc.offset]], desc.field]];
        END;

#### RCFS Read Code Field Stack

    RCFS: PROCEDURE =
        BEGIN
        desc: FieldDesc = Pop[];
        offset: CARDINAL = Pop[];
        Push[ReadField[ReadCode[offset + desc.offset], desc.field]];
        END;

Programming Note: The Read Code Field Stack instruction is used for accessing constant structures (arrays and records) located in the current code segment when the offset of the word containing the field is not constant.

#### RLIPF Read Local Indirect Pair Field

    RLIPF: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        spec: FieldSpec = GetCodeByte[];
        ptr: POINTER = FetchMds[LF + pair.left];
        Push[ReadFieldfFetchMds[ptr + pair.right], spec]];
        END;

#### RLILPF Read Local Indirect Long Pair Field

    RLILPF: PROCEDURE =
        BEGIN
        pair: NibblePair = GetCodeByte[];
        spec: FieldSpec = GetCodeByte[];
        ptr: LONG POINTER = ReadDblMds[LF + pair.left];
        Push[ReadField[Fetch[ptr + LONG[pair.right]], spec]];
        END;

### 7.5.2 Write Field

The write field instructions pop a value from the stack into a field of a word in memory. The value is right-justified in the field, ignoring leftover significant bits. Write Swapped Zero Field takes the pointer and the data in the opposite order on the stack, so that the pointer can be obtained using a Recover instruction.

#### WF Write Field

    WF: PROCEDURE =
        BEGIN
        desc: FieldDesc = GetCodeWord[];
        ptr: POINTER = Pop[];
        data: UNSPECIFIED = Pop[];
        StoreMds[ptr + desc.offset]  WriteField[
            FetchMds[ptr + desc.offset], descfield, data];
        END;

#### W0F Write Zero Field

    WOF: PROCEDURE =
        BEGIN
        spec: FieldSpec = GetCodeByte[];
        ptr: POINTER = Pop[];
        data: UNSPECIFIED = Pop[];
        StoreMds[ptr]  WriteField[FetchMds[ptr], spec, data];
    END;

#### WLF Write Long Field

    WLF: PROCEDURE =
        BEGIN
        desc: FieldDesc = GetCodeWord[];
        ptr: LONG POINTER = PopLong[];
        data: UNSPECIFIED = Pop[];
        Store[ptr + LONG[desc.offset]]  WriteField[
            Fetch[ptr + LONG[desc.offset]], desc.field, data];
        END;

#### WLOF Write Long Zero Field

    WLOF: PROCEDURE =
        BEGIN
        spec: FieldSpec = GetCodeByte[];
        ptr: LONG POINTER = PopLong[];
        data: UNSPECIFIED = Pop[];
        Store[ptr]  WriteField[Fetch[ptr], spec, data];
        END;

#### WLFS Write Long Field Stack

    WLFS: PROCEDURE =
        BEGIN
        desc: FieldDesc = Pop[];
        ptr: LONG POINTER = PopLong{];
        data: UNSPECIFIED = Pop[];
        Store[ptr + LONG[desc.offset]]  WriteField[
            Fetch[ptr + LONG[desc.offset]], desc.field, data];
        END;

#### WSOF Write Swapped Zero Field

    WSOF: PROCEDURE =
        BEGIN
        spec: FieldSpec = GetCodeByte[];
        data: UNSPECIFIED = Pop[];
        ptr: POINTER = Pop[];
        StoreMds[ptr]  WriteField[FetchMds[ptr]], spec, data];
        END;

### 7.5.3 Put Swapped Field

The put swapped field instructions leave the pointer on the top of the stack.

#### PS0F Put Swapped Zero Field

    PS0F: PROCEDURE =
        BEGIN
        WSOF[];
        Recover[];
        END;

#### PSF Put Swapped Field

    PSF: PROCEDURE =
        BEGIN
        desc: FieldDesc = GetCodeWord[];
        data: UNSPECIFIED = Pop[];
        ptr: POINTER = Pop[];
        StoreMds[ptr + desc.offset]  WriteField[
            FetchMds[ptr + desc.offset], desc.field, data];
        Recover[];
        END;

#### PSLF Put Swapped Long Field

    PSLF: PROCEDURE =
        BEGIN
        desc: FieldDesc = GetCodeWord[];
        data: UNSPECIFIED = Pop[];
        ptr: LONG POINTER = PopLong[];
        Store[ptr + LONG[desc.offset]]  WriteField[
            Fetch[ptr + LONG[desc.offset]], desc.field, data];
        Recover[];
        Recover[];
        END;

Previous [TOC] Next

[last edited 5/20/99 12:08AM]