MARS is a Java JAR, you can easily use it as a library or reverse engineer it (though the sources are available).
In fact, if you do, you easily discover that it has a command-line interface:
java -jar Mars4_5.jar h
While there is an a
switch for "Assembly only", that doesn't generate an output file - it is a validation phase only.
But, as stated above, luckily this is Java, so we can simply reuse all of the MARS classes:
import mars.*;
import java.util.*;
public class MarsCompiler
{
public static void main(String... args) throws Exception
{
if (args.length != 1)
{
System.err.println("Usage: java MarsCompiler input");
System.exit(1);
}
Globals.initialize(false);
MIPSprogram program = new MIPSprogram();
program.readSource(args[0]);
ErrorList errors = null;
try
{
program.tokenize();
errors = program.assemble(new ArrayList(Arrays.asList(program)), true, true);
}
catch (ProcessingException e)
{
errors = e.errors();
}
if (errors.errorsOccurred() || errors.warningsOccurred())
{
for (ErrorMessage em : (ArrayList<ErrorMessage>)errors.getErrorMessages())
{
System.err.println(String.format("[%s] %s@%d:%d %s",
em.isWarning() ? "WRN" : "ERR",
em.getFilename(), em.getLine(), em.getPosition(),
em.getMessage()));
}
System.exit(2);
}
for (ProgramStatement ps : (ArrayList<ProgramStatement>)program.getMachineList())
System.out.println(String.format("%08x %08x", ps.getAddress(), ps.getBinaryStatement()));
}
}
To compile this program you need a Java 8+ JDK and, of course, pass the MARS' JAR in the classpath (MARS is, of course, not module ready):
javac -jar MARS4_5.jar MarsCompiler.java
Of course, this is just a basic example, it's up to you to shape it in a tool fulfilling your purpose (please note I don't give support).
Particularly, beware of multifile projects. I explicitly limited this program to a single file only.
Example
To see the machine code of this file (call it testm.s
):
.text
li $v0, 11
la $a0, 'a'
syscall
li $v0, 10
syscall
use
java -cp MARS4_5.jar MarsCompiler testm.s
to produce this in output:
00400000 2402000b
00400004 24040061
00400008 0000000c
0040000c 2402000a
00400010 0000000c