===== DRISC tools =====
The tools allow to test simple programs written in the DRISC assembler [1]. The tools are written in [[http://caml.inria.fr/ocaml/|Ocaml]] and have been tested on Linux (Ubuntu from 10.04 to 14.10, but other distributions also work).
Federico De Faveri produced an alternative D-RISC intepreter (with a much nicer interface) that runs within a browser page (see [[http://federico.defaveri.org/projects/WebDRisc/|this page]]). The interpreted uses the same syntax defined on this page (including memory location and register contents pseudo instructions).
==== Install the tools ====
In order to run the Drisc tools you need to have previously installed Ocaml. Ocaml can be installed from sources (available from the [[http://caml.inria.fr/ocaml/|Ocaml]] web site) or as packages (e.g. through Ubuntu Synaptics).
The tool source can be downloaded from the link below.
* [[http://backus.di.unipi.it/~marcod/AE1415/drisc_src_ven5dic2014_18.29.27_CET.tgz|drisc-1.1.tgz]]
In order to use the tools you need:
- uncompress the file
- change directory to the Drisc top level
- make
- insert the Drisc directory in your $PATH, or use commands as /path_to_drisc/Drisc/drisc
==== Syntax supported ====
The Drisc tools support the Drisc syntax introduced in [1], with the following limitations/feature
* "symbolic" register names (e.g. Ri or RbaseA) are not supported, only "number" registers are supported (e.g. R0, R63, R17)
* alfanumeric labels are supported
* instruction codes may be lowercase or uppercase
* several //pseudo instructions// are supported:
* **memloc L X** defines the contents of memory location L as X
* **memlocs L X1 X2 ... Xn** defines the contents of memory locations starting at L as X1 X2 ... Xn
* **regval R X** defines the initial contents of register R as X
* **loc X** the following instructions are placed in memory at address X
* **start X** defines the first instruction of the program (memory location X)
* memloc statements should be used for //any// location (either read or written) used in the program
* comments or empty lines are not supported
* error handling is really basic. In case you get an error, move an end instruction through the code to identify the instruction killing the parser and then analyze its syntax carefully
==== Sample code ====
Here is the code computing inner product:
memloc 1024 3
memloc 1025 2
memloc 1026 1
memloc 2048 4
memloc 2049 5
memloc 2050 6
memloc 4096 0
memloc 4097 0
memloc 4098 0
regval 1 1024
regval 2 2048
regval 3 4096
regval 4 3
start 1024
loc 1024
add R0,R0,R9
clear R10
loop: load R1,R9,R20
load R2,R9,R30
mul R20,R30,R20
add R20,R10,R10
incr R9
if< R9,R4,loop
end
The three memloc block define the three areas for input vector A (at mem[1024]), B (at mem[2048]) and the result block (at mem[4096]).
The regval statements initialize the RbaseA (R1) RbaseB (R2) Rresult (R3) and RN (R4) registers.
The program is stored starting at memory address 1024 (loc 1024 pseudo instruction) and starts at location 1024 (start 1024 pseudo instruction).
==== Tool usage ====
Two programs are compiled from the tools:
=== parse ===
parse file
parses the drisc program in //file//. If parsing succeeds, you should see the whole listing of the program to appear, including pseudo instructions. Otherwise you'll get an error with no output (error handling is not implemented in the parser).
Sample output (correct program):
marcod@marcod-ThinkPad-X220:~/Documents/Didattica/Architetture/Drisc$ ./parse SamplePrograms/ip.drisc
1. Mem[1024]=3
2. Mem[1025]=2
3. Mem[1026]=1
4. Mem[2048]=4
5. Mem[2049]=5
6. Mem[2050]=6
7. Mem[4096]=0
8. Mem[4097]=0
9. Mem[4098]=0
10. R[1]=1024
11. R[2]=2048
12. R[3]=4096
13. R[4]=3
14. START at 1024
15. 1024:
16. ADD R_0 R_0 R_9
17. ADD R_0 R_0 R_10
18. loop: LOAD R_1 R_9 R_20
19. LOAD R_2 R_9 R_30
20. MUL R_20 R_30 R_20
21. ADD R_20 R_10 R_10
22. ADDI R_9 #1 R_9
23. IF< R_9 R_4 loop:
24. END
DRisc parser: syntax error
Fatal error: exception Parsing.Parse_error
marcod@marcod-ThinkPad-X220:~/Documents/Didattica/Architetture/Drisc$
The error at the end is not an error.
Sample output (error):
marcod@marcod-ThinkPad-X220:~/Documents/Didattica/Architetture/Drisc$ ./parse err.drisc
DRisc parser: syntax error
Fatal error: exception Parsing.Parse_error
marcod@marcod-ThinkPad-X220:~/Documents/Didattica/Architetture/Drisc$
=== drisc ===
drisc file steps
parses the program in //file// and executes (up to) //steps// instructions according to the control flow of the program
Sample output:
Programs$ ../drisc p1.drisc 100
=================== Scanned program source:
1. R[1]=2
2. R[2]=4
3. ADD R_1 R_2 R_3
4. END
=================== Relocated program:
0 ADD R_1 R_2 R_3
1 END
=================== Final program (labels compiled)
0 ADD R_1 R_2 R_3
1 END
=================== Program starting at 0
--------------------------------------------------------------
PC:0
--------------------------------------------------------------
Register dump (10 per line)
R0-9 0 2 4 0 0 0 0 0 0 0
R10-19 0 0 0 0 0 0 0 0 0 0
R20-29 0 0 0 0 0 0 0 0 0 0
R30-39 0 0 0 0 0 0 0 0 0 0
R40-49 0 0 0 0 0 0 0 0 0 0
R50-59 0 0 0 0 0 0 0 0 0 0
--------------------------------------------------------------
Memory dump
--------------------------------------------------------------
0 ADD R_1 R_2 R_3
1 END
Executing instruction ==> 0: ADD R_1 R_2 R_3
--------------------------------------------------------------
PC:1
--------------------------------------------------------------
Register dump (10 per line)
R0-9 0 2 4 6 0 0 0 0 0 0
R10-19 0 0 0 0 0 0 0 0 0 0
R20-29 0 0 0 0 0 0 0 0 0 0
R30-39 0 0 0 0 0 0 0 0 0 0
R40-49 0 0 0 0 0 0 0 0 0 0
R50-59 0 0 0 0 0 0 0 0 0 0
--------------------------------------------------------------
Memory dump
--------------------------------------------------------------
Executing instruction ==> 1: END
Fatal error: exception Interp.EndOfProgram
marcod@marcod-ThinkPad-X220:~/Documents/Didattica/Architetture/Drisc/SamplePrograms$
==== Internals ====
The tools are organized in different parts, namely:
* **lexer.mll** hosts the lex source. In case an opcode is not recognized, look for a line such as | "div" { DIV }
and in case there is no such line, add it to the file. The returned token (DIV, in this case, should be defined at the beginning of the parser.mly file
* **parser.mly** hosts the parser (grammar of the recognized drisc instructions). An unrecognized instruction needs a proper entry in the file
* **asm.ml** defines the internal datatypes, used to return parsed program and to manipulate them
* **assembler.ml** defines the functions needed to assemble the program from the source
* **interp.ml** hosts the interpreter of the compiled drisc instructions
As an example, in order to handle a STORE instruction:
* the datatype **asm** in **asm.ml** has lines such as type asm = ...
| Load of reg*reg*reg
| Loadi of reg*const*reg
| ...
* the lexer.mll recognises the load keyword as long as registers with the lines
rule token = parse
...
| ['0'-'9']* as num { INT(int_of_string num) }
...
| "load" { LOAD }
| "LOAD" { LOAD }
...
| "R" { REG }
* the parser.mly has productions such as
%token LOAD LOADI STORE STOREI
...
main:
program { $1 }
;
program:
END { [Instr(End)] }
| anyinstr program { $1::$2 }
;
anyinstr:
LABEL COLON instr EOL { LabInstr(LabLab($1),$3) }
| instr EOL { Instr($1) }
| MEMVAL INT INT EOL { Instr(Memloc($2,$3))}
| REGVAL INT INT EOL { Instr(Regval($2,$3))}
instr:
...
| LOAD reg COMMA reg COMMA reg { Load($2,$4,$6)}
| LOADI reg COMMA imm COMMA reg { Loadi($2,$4,$6)}
...
* the interp.ml interprets the load as
let step i (Env(pc,m,r)) =
match i with
...
| Load(Reg(a),Reg(b),Reg(c)) ->
let ind = !(r.(a)) + !(r.(b)) in
r.(c) := (List.assoc ind !m); pc := !pc + 1
| Loadi(Reg(a),Const(b),Reg(c)) ->
let ind = !(r.(a)) + b in
r.(c) := (List.assoc ind !m); pc := !pc + 1
==== Example ====
This is the first example in Chapter V of [1].
start 1024
memloc 0 123
memloc 1 256
memloc 2 172
memloc 3 190
memloc 10 0
memloc 11 0
memloc 12 0
memloc 13 0
regval 1 0
regval 8 10
regval 2 0
regval 5 150
regval 6 200
regval 7 4
loc 1024
loop: load R1,R2,R3
if>= R3,R6,then2
if<= R3,R5,then1
move R3,R4
goto continua
then1: move R5,R4
goto continua
then2: move R6,R4
continua:store R8,R2,R4
incr R2
if< R2,R7,loop
end
==== Known problems =====
There are several instructions not completely managed by the tools. In particular, conditional jumps.
In case the tool does not work properly, please send the ASCII version of the drisc program not working with the tools to the professor, by email.
==== References ====
[1] M. Vanneschi, Architettura degli elaboratori, Edizioni Plus, 2009 (o seconda edizione 2013)