risc386: Reduced instruction set i386 simulator

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

risc386 is a symbolic Intel(R) 386 assembler interpreter which allows infinitely many registers (temporaries). Its purpose is to debug the output of a MiniJava compiler (from Andrew Appel's book, Modern Compiler Implementation in JAVA) before register allocation has been performed.

risc386 supports only a small fragment of i386 instructions. It expects its input to be a list of procedures in .intel_syntax each of which is started by a label and terminated by a return statement.

Control flow is restricted, so, only jumps to procedure-local labels are allowed. Reading from an uninitialized memory location will lead to an exception.


[Skip to Readme]

Properties

Versions 0.0.20130624, 0.0.20130701, 0.0.20130718, 0.0.20130719, 0.0.20210125, 0.0.20210812, 0.0.20210812, 0.0.20220128, 0.0.20230928
Change log CHANGELOG.md
Dependencies array (>=0.3 && <0.6), base (>=4.6 && <5), containers (>=0.3 && <0.7), mtl (>=2.0 && <2.1 || >=2.1.1 && <2.3), pretty (>=1.0 && <1.2) [details]
License BSD-3-Clause
Author Andreas Abel with contributions by Robert Grabowski and Ulrich Schoepp
Maintainer Andreas Abel <andreas.abel@ifi.lmu.de>
Category Compilers/Interpreters, Education
Home page https://github.com/andreasabel/risc386
Source repo head: git clone git://github.com/andreasabel/risc386.git
Uploaded by AndreasAbel at 2021-08-12T11:57:10Z

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for risc386-0.0.20210812

[back to package description]

risc386 -- Restricted Instruction Set i386 simulator

(C) 2013, Andreas Abel, Ludwig-Maximilians-University Munich

The main purpose of this simulator is to test i386 code generated by a compiler before register allocation. Therefore, it supports temporaries, an potentially infinite amount of extra registers t<number>. (Of course, it can also be used to execute symbolic assembler after register allocation.)

The supported instruction set is very restricted but sufficient to write a compiler for MiniJava [Andrew Appel, Modern Compiler Implementation in Java].

I. System requirements:

You need a recent version of GHC and Cabal (e.g. via the Haskell Platform).

II. Installation:

The executable risc386 can be installed with cabal install risc386. Here are more manual instructions starting from the tarball:

  1. Change to a temporary directory.

  2. Unpack the tar ball

    tar xzf risc386-x.y.z.tar.gz
    
  3. Change to the unpacked directory

    cd risc386-x.y.z
    
  4. Install using Haskell's packet manager cabal

    cabal install
    

III. Running the simulator:

risc386 input-file.s

IV. Format of the input file:

The input file must be symbolic assembler in Intel format.

Here is a small example:

            .intel_syntax
            .global Lmain
            .type Lmain, @function
    Lmain:
            #args
            enter   0, 0
    L0:     push    8
            call    L_halloc
            add     %esp, 4
            mov     t1001, %eax
            push    t1001
            call    LC$value
            add     %esp, 4
            mov     t1002, %eax
            push    t1002
            call    L_println_int
            add     %esp, 4
    L1:     leave
            ret

            .global LC$value
            .type LC$value, @function
    LC$value:
            #args LOC 0
            enter   0, 0
    L2:     mov     t1004, DWORD PTR [%ebp+8]
            mov     DWORD PTR [t1004+4], 555
            mov     t1003, DWORD PTR [%ebp+8]
            mov     %eax, DWORD PTR [t1003+4]
    L3:     leave
            ret

Lexing rules: (If you want to be sure, read the .x file, the lexer specification.)

Parsing rules: (If you want to know all of them, read the .y file)

  1. The input file must be a sequence of procedures.

    There must be one procedure whose name ends in main. This one is taken as the entry point.

  2. Each procedure starts with a label and ends with a return instruction. Optionally, it can be preceded by a declaration of its arguments

             #args REG %eax, LOC 0, LOC 4
    Lmyproc:
             ...
             RET
    

    Lmyproc expects its first argument in register %eax, its second at [%esp+0] and its third at [%esp+4]. The stack addresses are to be taken before the CALL is executed (which will put the return address on the stack and shift the relative location of the arguments by +4).

  3. The body of each procedure is a list of i386 assembler instructions in Intel syntax. The supported instructions are listed above.

    Each instruction my be preceded by a label.

    Conditional and unconditional jumps are only allowed to a label, and only to one defined in the same procedure. Cross-procedure jumps or jumps to a calculated address are not supported.

    CALLs are only defined to a procedure label. risc386 assumes the cdecl calling convention.

  4. Restrictions for individual instructions:

    RET does accept arguments ENTER is only supported in the form ENTER <number>, 0

Runtime:

Execution specialties: