Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Ron's IA-32 Virtual Machine (lite.)
C
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
sample
.gitignore
Makefile
README
code.c
code.h
cpu.c
cpu.h
cycle.c
cycle.h
fct.h
hashtable.c
hashtable.h
hashtable_private.h
mem.c
mem.h
micro_table.h
rvm.c
test_code.c
test_cpu.c
test_cycle.c
test_mem.c
test_rvm.c
test_type.c
type.h

README

                Ron's x86 Virtual Machine (lite)
           ==========================================

Content
---------

 1. Introduction
 2. Directory Contents
 3. How to Build, Test, and Run
 4. License
 5. Reporting Bugs
 6. Limitations
 7. Sample Outputs


1. INTRODUCTION
-----------------

This tree contains sources, tests, and samples for Ron's x86 Virtual
Machine (lite) package, or `rvm'.

`rvm' can disassemble and execute instructions from a text file with
x86 machine codes. For each instruction executed, it will dump the
registers and flags of the CPU. `rvm' also emulates the registers,
flags, stack, and memory. They are updated according the executed
instructions. The memory is implemented via a hash table and supports
full 32-bit range address.

`rvm' uses the interpretation technique to execute the x86
instructions. The interpreter is driven by the predefined opcode map
table roughly equivalent to "Table A-2. One-byte Opcode Map" in the
Intel manual. Each of the opcode has an entry in the table and is
encoded into four fields: load, process, save, and extra. These four
fields are like states in a state machine. The interpreter can follow
these state and successful decode and execute the instructions. By
extending the entries in the table, `rvm' can be easily extended to
support more instructions.

But due to the nature of variable-length instruction in x86
architecture, the interpreter does not have distinct separation of the
three instruction execution phases, fetch, decode, and
dispatch. Instead, parts of the instruction are fetched and decoded
first. Then depending on the partial decoded instruction, more parts
might need to be fetched.

This make it harder to perform optimizations like threaded
interpretation. But like what Donald Knuth said: "We should forget
about small efficiencies, say about 97% of the time: premature
optimization is the root of all evil." And also since `rvm' is still
at it's infancy, not much optimization was implemented in `rvm'.

Samples of the machine code files that `rvm' takes are as follow:

  # Sample I:
  50 c1 f8 02 34 2e 89 e5

  # Sample II:
  50                       # push eax
  c1 f8 02                 # sar eax,0x02
  34 2e                    # xor al,0x2e
  89 e5                    # mov ebp,esp

The code can be all on a single line or on multiple lines. The pound
sign (#) indicates that the rest of the characters on the same line
are comments. More samples are located in the `sample' folder (see
below for list of directory and files.)

Test-driven development was used when developing `rvm'. Unit test
cases are written prior the implementation. If you encounter bugs when
executing `rvm', please try running the test cases first (see below on
how to run tests.)

`rvm' is part of the programming assignment 1 for CS6270 – Virtual
Machines.


2. DIRECTORY CONTENTS
-----------------------

README          This file.
Makefile        Makefile to build `rvm' and its test cases.

type.h          Define common data types used in `rvm'.
mem.[hc]        Memory emulation.
cpu.[hc]        CPU states, such as registers, flags, stack.
code.[hc]       Code reader, reads code from file or buffer.
micro_table.h   Predefined opcode map table.
cycle.[hc]      Main implementation of the interpreter.
rvm.c           Front-end for the `rvm'.

test_*.c        Unit test cases for the above components.
sample/         Sample machine code file used for testing.

fct.h           FCT (Fast C Test) Unit Testing Framework.
hashtable.[hc]  C Hash Table by Christopher Clark.


3. HOW TO BUILD, TEST, RUN
----------------------------

This package comes with a Makefile to build `rvm' and its test
cases. It has been tested on the following configurations:
  * Mac OS X 10.6.2
    * GCC 4.2.1
    * GNU make 3.81
  * Linux 2.6.31
    * GCC 4.4.3
    * GNU make 3.81
  * Cygwin 1.7.1 (Windows 7)
    * GCC 4.3.4
    * GNU make 3.81

To build the test cases and run them:
  $ make test
  $ ./test_rvm

To build and run `rvm':
  $ make
  $ ./rvm <insert code filename>

To run `rvm' with the sample machine code files that come with this
package, you can:
  $ ./rvm sample/cycle_basic
  $ ./rvm sample/code_single_line


4. LICENSE
------------

`rvm' is licensed under the New BSD License.

FCT (Fast C Test) Unit Testing Framework is licensed under the New BSD
License.

C Hash Table is licensed under the New BSD License.


5. REPORTING BUGS
-------------------

If you encounter bugs or have trouble running `rvm', please contact:

  Yih-Lun Huang <ylhuang@nus.edu.sg>


6. LIMITATIONS
----------------

There is actually quite many limitations in `rvm':
 * Support only IA-32 architecture. 64-bit instructions are not
   supported.
 * Roughly only 10 instructions with specific operands are currently
   supported.
 * Opcode map table currently on support one-byte opcodes. But this
   can be easily extended.
 * Support only flat memory model. Segment registers are not used.
 * A lot more...


7. SAMPLE OUTPUTS
-------------------

Sample output for running the test cases:

  $ ./test_rvm
  type_sizeof ....................................................... PASS
  type_assign ....................................................... PASS
  mem_rw ............................................................ PASS
  mem_reset ......................................................... PASS
  mem_alignment ..................................................... PASS
  cpu_reset ......................................................... PASS
  cpu_push .......................................................... PASS
  cpu_pop ........................................................... PASS
  cpu_flags_mask .................................................... PASS
  cpu_flags_set ..................................................... PASS
  cpu_flags_get ..................................................... PASS
  code_single_line .................................................. PASS
  code_multiple_lines ............................................... PASS
  code_multiple_lines_with_comment .................................. PASS
  code_read_multi_bytes ............................................. PASS
  code_read_buffer .................................................. PASS
  cycle_inst_lea .................................................... PASS
  cycle_inst_and .................................................... PASS
  cycle_inst_push ................................................... PASS
  cycle_inst_sar .................................................... PASS
  cycle_inst_xor .................................................... PASS
  cycle_inst_mov .................................................... PASS
  cycle_inst_inc .................................................... PASS
  cycle_inst_sub .................................................... PASS
  cycle_inst_cmp .................................................... PASS
  cycle_inst_pop .................................................... PASS
  cycle_step_mnemonic ............................................... PASS
  cycle_steps ....................................................... PASS

  ----------------------------------------------------------------------------

  PASSED (28/28 tests in 0.002690s)

Sample output for running `rvm':

  $ ./rvm sample/cycle_basic
  Step 0: (Initial state)
  eax           0x00000000
  ecx           0x00000000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003ffc
  ebp           0x00002000
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 1: lea
  eax           0x00000000
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003ffc
  ebp           0x00002000
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 2: and
  eax           0x00000000
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003ff0
  ebp           0x00002000
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 3: push
  eax           0x00000000
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fec
  ebp           0x00002000
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 4: sar
  eax           0x00000000
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fec
  ebp           0x00002000
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000040
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 5: xor
  eax           0x0000002e
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fec
  ebp           0x00002000
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 6: mov
  eax           0x0000002e
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fec
  ebp           0x00003fec
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 7: inc
  eax           0x0000002e
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fec
  ebp           0x00003fed
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 8: sub
  eax           0x0000002e
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fe8
  ebp           0x00003fed
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000000
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 9: cmp
  eax           0x0000002e
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fe8
  ebp           0x00003fed
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000001
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Step 10: pop
  eax           0x0000002e
  ecx           0x00004000
  edx           0x00000000
  ebx           0x00000000
  esp           0x00003fec
  ebp           0x00000000
  esi           0x00000000
  edi           0x00000000
  eip           0x00001000
  eflags        0x00000001
  cs            0x0000
  ss            0x0000
  ds            0x0000
  es            0x0000
  fs            0x0000
  gs            0x0000
Something went wrong with that request. Please try again.