A X86/ARM Emulator with source

Today Hardware Friday project isn't really hardware, but it's close and really kind of interesting and we just don't highlight projects like this often enough.

X86/ARM Emulator

A quick search reveals that the WWW holds a vast array of material and tools classed as emulators, virtual machines and interpreters. These range from the highly sophisticated to simple academic exercises. If you narrow your search and look for X86 assembler emulators, you will find commercial DOS emulators, Basic language tools, Java utilities such as Jasmin, and a CodeProject article, ASM.net X86, amongst others. Another large class of related tools are standalone X86 debuggers and disassemblers, which can be used both to step through code fragments and examine generated machine code statically or on the fly. This article offers something different. A Visual Studio Express based solution, written using C++ and assembler, that allows the user to write and execute X86, X86/64 and ARM assembler line by line as easily as using a text editor. As code is only emulated, errors are trapped and reported within the program without any wider impact.

Updates

The first version was a partial implementation for X86 code only. An updated set of solution files is now available via the DropBox link below that implements some ARM code, specifically the data processing sub-set of instructions. Operand syntax for ARM requires ...

...

Background

This article is not aimed at expert readers or professional application, but rather those seeking to develop their knowledge of C++ and assembler used in the .NET environment, or who like idea of such a tool for some anorak fun. For convenience, I have chosen to use and provide materials based on Visual Studio Express 2012 running under Windows 7 64bit (executables are X86 32 bit). My objective at the outset was to learn how to use Visual C++ to write multiform applications, to learn X86 assembler, and how to combine both of these to produce a single executable. Along the way I experimented with inline assembler, separate assembler modules, ARM assembler, and X64 bit assembler.

At this stage I am not presenting a finished project, but work in progress that others might like to experiment with or even develop. Under Windows 7 the basic framework executes reliably and the X86 virtual machine is fully functional for a core set of instructions (listed in the Help menu). The ARM and X64 elements are just illustrative at this stage, and X86 floating point is not yet implemented. I have utilized Windows Forms extensively, written classes and threading, and experimented with some of the C standard library. I have looked at new material such as the Atomic Class, but have been prevented from quick adoption by issues arising from using a mixture of managed and native code. I have even experimented with linking to FORTRAN modules as a basis for interpreting X86 floating point instructions, with binary files for data exchange, but effective use of FORTRAN requires close integration using the .net environment. Whilst such tools and compilers exist (Silverfrost FTN95, etc), I do not have access to the full commercial offerings and associated development environments to trial such ideas.

If your interest is bog standard object orientated development, or you are a professional C++ or assembler programmer, look away. I have not been a professional programmer since the late 1970s, at which time I used ICL System 4 assembler and Fortran IV. I have had a lifetime in ICT, but you soon have to leave the hands on technical behind. C++ is the perfect vehicle for me, it can be used and abused in many guises. I am retired so I can play, but my real aim is continuous learning.

I have learnt a great deal from hands on coding of this project. Professional Windows programmers may have no difficulty understanding the differences between Windows reference classes and classes, or the details of how header files for Windows Forms operate within Visual C++, or the issues arising from the need for static, global data sharing between assembler and multiple C++ forms. I have steered clear of a rigorous parent child form hierarchy, the niceties of professional parser and compiler writing, and strict object orientated development. I have even utilised the odd GOTO. My FORTRAN roots operate like weeds. If I were starting now, I would utilise a more hierarchical approach for header files and classes, with inheritance and conditional complilation to avoid the problems of duplicated definitions and ease code reuse.

The Idea

My initial attempts at learning X86 assembler using MASM32 and similar tools were hampered by a lack of understanding of the low level Windows environment, the limitations of input/output using Windows Console, and the fact that assembler mistakes could, at least pre-Windows 7, result in critical errors that would crash the PC rather than just the program being tested. As a learning exercise I decided to write an X86 assembly language interpreter that could be executed as a standard Windows Form application. C++, with its capability for everything from object orientated usage to low level code, seemed the perfect vehicle for this project. A critical requirement was the ability to mix managed code with native code, and to use assembler.... However, my first goal has been to produce a software framework that could be used as a 'test harness' for (my) learning, not just of C++ but for the target systems being emulated. The notion is similar to the prototypes often employed within business analysis to gauge the merits of competing technical solutions before real development work starts.

Pre-Requisites

I am currently developing this project using Visual Studio 2012 Express, running the executable directly from that environment. The executable is also capable of being run directly if you install the latest version of the Visual Studio 2012 X86 runtime, which can be downloaded free from Microsoft. My PC environment is Windows 7 64 bit, but I have also successfully run this project under Windows 8 (using VS2012 Express for Desktop).

Known Issues

When executing under VS2012, select Build and then 'Start without debugging' when the build completes. A variety of warning messages will be observed,mostly related to the use of native code and compiler command line options. If you opt for 'Start debugging' the application does not always run reliably. Very occasionally, and apparently randomly, during execution I have experienced a generic GDI+ error but execution can be 'continued' if the error occurs or just restart the application. This is not obviously a GDI objects overflow problem, but nor is it straightforward to diagnose the actual cause.

Limitations ...

...

A Visual Guide

image

image

...

Installation

The files provided via the DropBox link below comprise a set of screen snapshots (.jpgs) from the application running in each of the emulation modes, a compressed Windows 32 bit executable (.zip), and the Visual Studio solution folder, both zipped and uncompressed. Download the files and unzip the x64interprettest.zip to extract the executable. Install Visual Studio 2012 C++ X86 runtime, available on Microsoft's site, navigate to the folder containing the unzipped executable and double click the x64interprettest.exe file. Depending on your PC environment and user credentials, you may need to right click and run the .exe file with administrator rights, and/or override real time anti-virus warnings. Under Windows 8, if you see a box saying that the application is unauthorised, click more info and then select Run anyway. The MD5 checksum for the executable is:

...

Use

The initial screen offers a choice of emulation modes. Select X86. Once loaded, the cursor is positioned on the code entry line. As an example, tab to the Mneumonic field and enter add, and then tab to first and second operand fields and enter eax and 45. Click the Translate Code and then the Execute buttons immediately above the code entry line. Further lines of code can then be entered one by one in the same manner. Data can be entered directly in to registers, the stack and memory using the Data Entry menu....

...

Variables, Labels and Constants

The Emulator can accept data and label definitions. ...

The Code

The Emulator is a C++ Windows Form application comprising a number of linked forms which in turn utilise external functions. These latter functions are a mix of C++, unmanaged C++ employing inline assembler, and an X86 assembler only module. As the original purpose of the application was as a learning aid, it has developed into a 'test harness' for trying out coding ideas. It is not spaghetti code, but ...

...

X64 and ARM Emulation

The X86 64 bit emulation is only a framework at this stage. You can enter code or data definitions in a similar manner to the X86 32 bit emulation, but the interface has been simplified such that everything is entered on one line and a single Assemble button is provided to translate and execute the code entered. If you download and examine the detail of the screen dump ...

...

[Click through for the entire project for the link to the source files, the binary and more]

Tags:

Follow the Discussion

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.