Indice

DRISC tools

The tools allow to test simple programs written in the DRISC assembler [1]. The tools are written in 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 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 Ocaml web site) or as packages (e.g. through Ubuntu Synaptics).

The tool source can be downloaded from the link below.

In order to use the tools you need:

  1. uncompress the file
  2. change directory to the Drisc top level
  3. make
  4. 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

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:

As an example, in order to handle a STORE instruction:

* 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)