RAM Model of Computation
- INC Ri, increment the contents of register Ri by 1.
- DEC Ri, decrement the contents of register Ri by 1; keep Ri unchanged if Ri is 0.
- CLR Ri, set the contents of register Ri to 0.
- MOV Ri Rj, replace the contents of register Ri by the contents of Rj, leaving Rj the same.
- JMP N, next instruction to execute is set to the one with label N.
- Rj JMP N, if contents of Rj is 0 the next instruction to execute is set to the one with label N, otherwise the instruction that follows executes as usual.
- CONTINUE, do nothing.
It is possible to use a register (in the second part of the program) without assigning it a value in the first part of the program. Such registers should be assumed to have a value of 0.
An example of a RAM program is shown below (p1.ram):
# Program to add two numbers
# inputs are in r1 and r2
# output, as always, is in r1
#
# initialize input registers
r1 = 9
R2 = 3
#
# begin program
n0: R2 JMP N1
INC R1
DEC R2
JMP N0
N1: CONTINUE
The execution of a RAM program starts with the assignment of values to registers
and then executing the instructions in the second part one at a time in sequence.
The sequence may be altered by one of the the JMP instructions.
The RAM program terminates when it executes the CONTINUE instruction.
Write a Python program that executes a RAM program stored in a file whose name is provided as command line input. An optional -d command line parameter may be provided to execute the RAM program in debug mode in which each instruction that is executed is displayed. Two sample runs are shown below:
Mac-mini:ram raj$ python3 RAM.py p1.ram Input: R1 ==> 9 R2 ==> 3 Output: R1 = 12 Mac-mini:ram raj$ python3 RAM.py -d p1.ram Input: R1 ==> 9 R2 ==> 3 Executing: N0: R2 JMP N1 Executing: INC R1 Executing: DEC R2 Executing: JMP N0 Executing: N0: R2 JMP N1 Executing: INC R1 Executing: DEC R2 Executing: JMP N0 Executing: N0: R2 JMP N1 Executing: INC R1 Executing: DEC R2 Executing: JMP N0 Executing: N0: R2 JMP N1 Executing: N1: CONTINUE Output: R1 = 12 Mac-mini:ram raj$
Dictionaries to the rescue!!
To solve this assignment, we will resort to the dictionary data structure of Python. In particular, we will record the values of registers, the instruction number for labels, and inner details of individual instructions in dictionaries. Here are the three variables that you would have to construct and manipulate in the program:
registers = {'R1': 9, 'R2': 3}
code = [ {'labeldef': 'N0', 'opcode': 'CJMP', 'register1': 'R2', 'jmplabel': 'N1'},
{'opcode': 'INC', 'register1': 'R1'},
{'opcode': 'DEC', 'register1': 'R2'},
{'opcode': 'UJMP', 'jmplabel': 'N0'},
{'labeldef': 'N1', 'opcode': 'CONTINUE'}
]
labels = {'N0': 0, 'N1': 4}
Few RAM programs for your testing purposes:
$ more p1.ram
# Program to add two numbers
# inputs are in r1 and r2
# output, as always, is in r1
#
# initialize input registers
r1 = 9
R2 = 3
#
# begin program
n0: R2 JMP N1
INC R1
DEC R2
JMP N0
N1: CONTINUE
$ more p2.ram
R1 = 19
R2 = 3
MOV R3 R2
N1: R1 JMP N4
MOV R2 R3
N2: R2 JMP N3
DEC R1
DEC R2
R1 JMP N4
JMP N2
N3: INC R4
JMP N1
N4: R2 JMP N5
MOV R1 R4
CONTINUE
N5: INC R4
MOV R1 R4
CONTINUE
$ more p3.ram
R1 = 3
R2 = 5
MOV R3 R1
N1: DEC R2
R2 JMP N4
MOV R6 R3
MOV R5 R1
N2: DEC R5
R5 JMP N1
MOV R4 R6
N3: R4 JMP N2
INC R3
DEC R4
JMP N3
N4: MOV R1 R3
CONTINUE
$ more p4.ram
r3 = 9
r2 = 3
n1: inc r1
dec r2
r2 jmp n3
n2: inc r1
dec r3
r3 jmp n2
n3: continue
p1.ram,
p2.ram,
p3.ram,
p4.ram.
Submit: RAM.py