WIDE (0xC4)


The WIDE instruction indicates that the following instruction (IINC, ILOAD, or ISTORE) will have a 2-byte offset rather than the normal 1-byte offset. With only a 1-byte offset, programs are limited to a maximum of 256 variables. With a 2-byte offset, a program can have as many as 65,536 variables.

Notes:

1. Tanenbaum did not implement the WIDE IINC in his interpreter. The interpreter supplied with this simulator does.

2. The assembler inserts the WIDE opcode when necessary (based on the offset of the variable identifier). The programmer cannot specify a wide instruction. In fact, the WIDE mnemonic is not recognized by the assembler.

Interpreter Microcode

The microinstructions are listed in the order in which they are executed; not the order in which they are stored in the control store. The microinstruction at address 0x002 branches to the section of microcode that interprets the instruction whose opcode is currently in the MBR:

0x002  PC=PC+1; fetch; goto (MBR OR 0x0)

This instruction also initiates a fetch of the next byte in the program. In this case that byte will be the opcode of an ILOAD (0x15), an ISTORE (0x36), or an IINC (0x84) instruction. Any other opcode will cause the program to crash. Since the MBR is ORed with 0x100, the first instruction in the microcode below will branch to one of the following addresses:  0x115 (to execute a WIDE ILOAD), 0x136 (to execute a WIDE ISTORE), or 0x184 (to execute a WIDE IINC).

0x0c4  PC=PC+1; fetch; goto (MBR OR 0x100) // 0x115 or 0x136

Interpret WIDE ILOAD. The last 3 lines (in italics) are
also included in the code that interprets ILOAD.

0x115  PC=PC+1; fetch; goto 0x21
...
0x021  H=MBRU<<8; goto 0x22
0x022  H=H OR MBRU; goto 0x23
0x023  MAR=H+LV; rd; goto 0x19
...
0x019  SP=MAR=SP+1; goto 0x1a
0x01a  PC=PC+1; wr; fetch; goto 0x1b
0x01b  TOS=MDR; goto 0x2

Interpret WIDE ISTORE. The last 4 lines (in italics) are
also included in the code that interprets ISTORE.

0x136  PC=PC+1; fetch; goto 0x24
...
0x024  H=MBRU<<8; goto 0x25
0x025  H=H OR MBRU; goto 0x26
0x026  MAR=H+LV; goto 0x1d
...
0x01d  MDR=TOS; wr; goto 0x1e
0x01e  SP=MAR=SP-1; rd; goto 0x1f
0x01f  PC=PC+1; fetch; goto 0x20
0x020  TOS=MDR; goto 0x2

Interpret WIDE IINC. The last 4 lines (in italics) are
also included in the code that interprets ISTORE.

0x184  PC=PC+1; fetch; goto 0x185
0x185  H=MBRU<<8; goto 0x186
0x186  H=H OR MBRU; goto 0x187
0x187  MAR=H+LV; rd; goto 0x2b
...
0x02b  PC=PC+1; fetch; goto 0x2c
0x02c  H=MDR; goto 0x2d
0x02d  PC=PC+1; fetch; goto 0x2e
0x02e  MDR=H+MBR; wr; goto 0x2

Example Program

//---------------------------------------------
// Demonstrate the WIDE instruction.
//
// The assembler generates WIDE instructions
// only as necessary. That means that the
// program must have more than 256 variables.
// All variables after the 256th must be
// accessed using WIDE instructions.
//
// In this demo, 257 variables are declared
// (a0 through a256). However, only variable
// a256 is actually accessed because it is
// the only variable that requires WIDE
// instructions.
//
// 1. Clear Memory
// 2. Assemble this program.
// 3. Reset the computer.
// 4. Click the "Display Words" radio button
//    below the memory display.
// 5. Click the "Run" button.
//
// After running this program
//     5 is stored at address 4097
//     5 is stored at address 8448 (LV+256)
// and the top of the stack is at 4097.
//---------------------------------------------
.main
.var
    a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 
    a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 
    a20 a21 a22 a23 a24 a25 a26 a27 a28 a29 
    a30 a31 a32 a33 a34 a35 a36 a37 a38 a39 
    a40 a41 a42 a43 a44 a45 a46 a47 a48 a49 
    a50 a51 a52 a53 a54 a55 a56 a57 a58 a59 
    a60 a61 a62 a63 a64 a65 a66 a67 a68 a69 
    a70 a71 a72 a73 a74 a75 a76 a77 a78 a79 
    a80 a81 a82 a83 a84 a85 a86 a87 a88 a89 
    a90 a91 a92 a93 a94 a95 a96 a97 a98 a99 
    a100 a101 a102 a103 a104 a105 a106 a107 a108 a109 
    a110 a111 a112 a113 a114 a115 a116 a117 a118 a119 
    a120 a121 a122 a123 a124 a125 a126 a127 a128 a129 
    a130 a131 a132 a133 a134 a135 a136 a137 a138 a139 
    a140 a141 a142 a143 a144 a145 a146 a147 a148 a149 
    a150 a151 a152 a153 a154 a155 a156 a157 a158 a159 
    a160 a161 a162 a163 a164 a165 a166 a167 a168 a169 
    a170 a171 a172 a173 a174 a175 a176 a177 a178 a179 
    a180 a181 a182 a183 a184 a185 a186 a187 a188 a189 
    a190 a191 a192 a193 a194 a195 a196 a197 a198 a199 
    a200 a201 a202 a203 a204 a205 a206 a207 a208 a209
    a210 a211 a212 a213 a214 a215 a216 a217 a218 a219 
    a220 a221 a222 a223 a224 a225 a226 a227 a228 a229 
    a230 a231 a232 a233 a234 a235 a236 a237 a238 a239 
    a240 a241 a242 a243 a244 a245 a246 a247 a248 a249 
    a250 a251 a252 a253 a254 a255 a256
.end-var

    bipush 4
    istore a256
    iinc a256 1
    iload a256
    halt
.end-main

Load this source program into the editor/assembler and assemble it. The machine language code can be seen in the memory window:

The disassembled code can be viewed in the disassembled code window:

Main:

   0:  BIPUSH 4
   2:  WIDE ISTORE 256
   6:  WIDE IINC 256 1
  11:  WIDE ILOAD 256
  15:  HALT