Lab 5: PIP machine code

Goals:

The textbook uses the PEP/7 virtual machine. The Explorations CD uses the "supersimple" machine. We don't have access to the PEP/7 simulator, and the supersimple machine is a wee bit too simple, so I've decided to use the PIP virtual machine. You can't watch the internal data flow, but you can write modest programs.

The PIP virtual machine is written in python (though we won't look at that code yet). Download the zip file pipfiles.zip, and unzip it somewhere convenient (eg D:\userfiles\pip). To run it, don't use idle. Instead, start a command window (Start=>Programs=>Accessories=>Command), navigate to your directory, and then type python pipGui.py to start the program. A red, blue, and yellow window should open. (Or type the command "pip" or "pip.bat"; hopefully that will work too.)

A PIP opcode is 8 bits, followed by an optional 8-bit operand representing either an address or a numeric literal. Thus, the address space is 28 = 256 bytes; our implementation makes the limit much smaller. Actually, there are <=16 opcodes in use, so 4 bits would be enough, plus one bit to specify immediate mode (operand is a numeric literal) or direct mode (operand is an address). The extra three bits could be used to support more opcodes, or else could be used to identify one of 23 = 8 cpu registers.

Like supersimple and PEP/7, PIP has a single cpu data register: the accumulator.

Immediate mode is indicated by placing a # sign in front of the numeric value:
    LOD  #22

would load the accumulator with the numeric value 22. Without the # sign,
    LOD 22

    would load the accumulator with the contents of memory location 22. Normally, direct operand addresses are given in terms of a symbolic label; eg
    LOD X
In the PIP assembler, a LOD X instruction would result in automatic allocation of the memory location for X.

Pip Assember Summary
Symbols Used:
    X for a symbolic or numeric data address.
    #N for a literal number N as data
    Acc refers to the accumulator
    L refers to a symbolic code label or numeric code address

Data Flow
    LOD X (or #N)                Accumulator = X (or N)
    STO X                              X = Acc (copy Accumulator to location X)
Control
    JMP L                              IP = L (go to instruction L unconditionally)
    JMZ L                             if Accumulator==0: go to instruction L
    NOP                                No operation; just go to next instruction
    HLT                                Halt execution
Arithmetic-Logic
    ADD X (or #N)             Add the contents of X (or the value of N) to Acc.
    SUB X (or #N)             Accumulator = Accumulator - X (or N)
    MUL X (or #N)            Accumulator = Accumulator * X (or N)
    DIV X (or #N)             Accumulator = Accumulator / X (or N)
    AND X (or #N)           if Accumulator != 0 and X != 0: Accumulator=1
                                         else: Accumulator=0; not bitwise
    NOT                            if Accumulator == 0: Accumulator = 1
                                         else: Accumulator = 0
    CPZ X                         if X == 0: Accumulator = 1 else: Accumulator = 0
    CPL X                         if X < 0: Accumulator = 1 else: Accumulator = 0

Input and Output

We won't actually use any I/O instructions in PIP. Instead, we'll just store input data in PIP memory locations before beginning, and look at other memory locations for our results when the run is finished. PIP doesn't have a direct way to define memory contents, so if we want location W to contain the value 17 we run the following at the beginning of the program:
    LOD   #17
    STO   W
Alternatively, you can leave them 0, load the program, and then enter values in the DATA panel before running the program. If you do this, be sure to click UPDATE before running.


Running PIP

You first create an asm file, and type its name into PIP and click LOAD. You can then change some data memory locations (or, for that matter, instructions); if you do, be sure to click UPDATE. Click STEP or RUN to run. To re-run, click INIT, which will reset the PC to 0 (called IP, "Instrution Pointer", here). Or you can enter 0 in the IP box and click UPDATE.

Sample Programs

simple.asm: code to store 4+3 into N.
arith.asm:    code to evaluate the expression Z = (W+X)*Y/2
ifElse.asm, ifElse2.asm: code to execute a couple if-else statements
sum2n.asm: finds n+(n-1)+...+3+2+1
gcd.asm
exp.asm

Your assignment

1. Write PIP code to evaluate the expression (3+X)*(Y*Y-1). Note that you will need at least one TEMP location, to store 3+X while you work on Y*Y-1.

2. Write PIP code to evaluate FACTORIAL(N). The program should begin by initializing N through, eg,
    LOD #5
    STO  N
It should end with the value of N! in the accumulator. Note that, because of overflow, 5! is the best you can do.