There are four main ways in which code written for one architecture (such as the 80x86 or 680x0 or an IBM mainframe) can be ported to run on a different architecture.
Software written in a high-level language such as C or Pascal should of course be re-compiled to produce a new executable for the target architecture, taking advantage of the latest advances in high-performance compiler design. This may be very straightforward, but any non-portable or system-dependent parts of the program may need to be changed (in complex systems this can be a non-trivial task, especially if the runtime architecture is also different).
Of course, this assumes that a suitable compiler is available for the target architecture. If the original code was written in a non-mainstream language, or if it made heavy use of proprietary language extensions, other approaches will have to be explored. Sometimes the source code of the original compiler is available and can be modified to generate code for a different target (this approach was successfully used by MicroAPL to allow the porting of a large base of Pascal code with proprietary real-time extensions). Alternative approaches include emulation, using PortAsm to convert the output from the compiler, and using a high-level code converter to translate the original source into a different high-level language.
It used be thought that software written in assembly language had to be re-written by hand. However, advances in automatic assembly-language translation software make the burden much lighter.
The first of MicroAPL's translation tools is our advanced Relogix assembler-to-C translator. Relogix can be used to carry out a one-time conversion from assembler source code to ANSI C, after which you maintain the C version.
Because Relogix produces high-quality, readable, commented code in a natural C style, this approach has the advantage that the translated code can be easily maintained and developed further, and it becomes processor-independent.
On the other hand, because of the fundamental architectural differences between assembler and C, the conversion process is not fully automatic and some manual intervention may be required. This is because the translation process very substantially alters the code-flow of the program (replacing internal branches with structured control constructs, and external branches with function calls). In addition, you may want to supplement the data-type and variable-naming information which Relogix automatically determines, for example by specifying your own C header files.
If you have 680x0 or 80x86 assembler source code, an alternative to Relogix is to use PortAsm, an assembler-to-assembler translator for use in situations where you are happy to continue maintaining the original assembler program but want it to run on a new architecture. For example your code might be written in 680x0 assembler but you now want to run it on an Intel 80x86-based device. In this case an almost entirely automatic translation is possible, producing good-quality, optimized assembler code for the target processor.
You can think of PortAsm as a bit like a compiler which takes the original assembler source code as the input and outputs assembler source code for the target architecture. When you need to add new features to your code you do so in the original assembler version and retranslate as part of the build process. Typically you never even need to look at the output that PortAsm produces.
PortAsm can also be used to translate the listing file of a compiler which produces code for one architecture, and port it to another architecture. This can be used to run an application using big-endian data layout on a little-endian machine.
The software can be left in its original form (as object code), and run under an emulator program which simulates the instruction set of the original processor family. This option requires no changes to the software itself, although it does incur a significant performance penalty compared with a native (re-compiled or translated) program. In this solution, every original machine instruction is read, decoded, and emulated on the target architecture; the emulator is effectively a language interpreter, where the ‘language’ is the instruction set of the CPU for which the program was originally written.
MicroAPL's Mimic/68K is an example of such an emulator program, designed specifically for the embedded market. It allows software written for the 680x0 family to run unchanged on modern processors. It does this by reading the 680x0 code, interpreting the meaning of each instruction, and carrying out an equivalent series of instructions in the target architecture.
Because of the optimised design of Mimic/68K and advances in hardware performance, code normally runs much faster than on the original 68K processor.
Sometimes it makes sense to combine these different approaches, and therefore MicroAPL's tools are designed to work together. MicroAPL's Porting Consultancy Sevices can help in all four areas, as well as in providing custom tools and solutions for more difficult porting problems.