23rd December, 2006

A Simple Python CPU Emulator   

Posted in design, programming | by evilbitz |



Emulators in computer science are computer software that emulates an environment for another software to run, it may include some hardware devices as well, but if a complete environment is emulated that it will be usually called a virtual machine. An example for such enironment is DOSEMU, a DOS operating system environment which is emulated and designed to run on top of Linux operating system. The core for any software emulator is the CPU emulation part, many virtual machines uses the CPU that the bochs project had created, it can run x86, AMD64, and PPC software.

I played a bit with emulators in the past, and I created a simple python CPU emulator that emulates “flat” assembly code that can be defined by a configuration file. In this post I’ll describe its features, how does it work and what can be achieved by using it.

Simple Python CPU Emulator

The CPU emulator itself has a couple of runtime variables that are being used by the parsers, it moves line by line over the assembly that you tell it to emulate, and if the current assembly line matches a pattern (defined in the configuration line) then it evaluates another pattern, according to the run-time state of the CPU registers.

The configuration file of the emulator has two parts, it defines the registers that the cpu holds and the instructions that the emulated CPU can execute. The design is very simple and elegant, when the emulator initializes it prepares an opcode python dictionary. For instance, the opcode INC is defined as follows in the configuration file:

INC $reg1 | $reg1 += 1

When the parser encounters that configuration line, it adds the following key => value to the dictionary:

opcodes[”INC (.*?)”] = “cpu[execed.group(1)] += 1″

Where cpu[execed.group(1)] is the run-time CPU register that is matched by the CPU emulator parser. When the parser reads a new assembly line, it first moves through all the keys of the opcodes dictionary, and tries to do a regular expression match. If it finds one, then the value of the dictionary is being simply evaluated. Here is the source code of the emulation loop:

01: while (cur_op_line < end_of_ops):
02: opcode = a_ops[cur_op_line]
03: execed, ptrn = get_exec(opcode)
04: if (execed):
05: if a_verbosity: print "%d:\t%s" % (cur_op_line+1, opcode)
06: exec(opcodes[ptrn])
07: else:
08: print "[-] havn't found a match for", opcode
09:
10: cur_op_line += 1

A Riddle For Fun

My friend Imri gave me this riddle when he took a course in complexity at the Tel Aviv University.

You a have a CPU with 4 registers (r0 through r3) and 3 basic opcodes that works as described:

  • INC reg - increases the value of reg by 1
  • DEC reg - decreases the value of reg by 1
  • TEST reg, line - if reg != 0 then start executing opcodes at the specified line

Download the source code, it comes ready with the configuration file for this exercise, and write a program that will end the execution when one of the registers contains the value 144.

  • The CPU starts when all the registers are initialized to zero.
  • The program length must not exceed 20 instructions.

Have pun! :-)



There are currently 2 responses to “A Simple Python CPU Emulator”

Why not let us know what you think by adding your own comment! Your opinion is as valid as anyone elses, so come on... let us know what you think.

  1. 1 On May 29th, 2008, David Hagler said:

    hey.. solved the puzzle, actually it took me longer to make the emulator work than to actually write the code
    # are comments (remove them for this to work ..)
    #R0 = 6
    INC r0
    INC r0
    INC r0
    INC r0
    INC r0
    INC r0
    # increment R1 by 6 …
    INC r1
    INC r1
    INC r1
    INC r1
    INC r1
    INC r1
    # while decrementing R0 by 1
    DEC r0
    # until R0 is 0 (effectively 6×6)
    TEST r0, 7

    #increment r0 by 4
    INC r0
    INC r0
    INC r0
    INC r0
    # while decrementing R1 by 1
    DEC r1
    # until R1 is 0 (effectively 36×4)
    TEST r1, 15

    R0 = 144, R1 = 0, R2 = 0, R3 = 0, R4 = 0

    .. it helps if you know brainfuck … :D

  2. 2 On May 29th, 2008, David Hagler said:

    Headsup and FYI for the curious, under unix’s (bsd, linux, macosx) - his CR/LF’s were causing me troubles, so .. convert his files.. and it all works

Leave a Reply

Top »
"If you can't join them, beat them!"
Search Evilbitz: