3
votes

I have written a MIPS assembly program with Mars simulator and I want to save every instruction address and machine code in a file, I know that Mars simulator does this work in "Execute" section, How can I get a copy of these in a file? And if it is not possible, are there any websites that do the same thing and provide machine code?

I mean I want to have a copy of the following part:

enter image description here

1
clang -target mips -c foo.s will assemble MIPS code. (Normal clang installs typically build in support for multiple target architectures). You can get the binary machine code out of the .o with objcopy to a flat binary. But note that .align has a slightly different meaning for GNU assemblers than for traditional MIPS assemblers like SGI (which MARS is compatible with), and clang doesn't do as many extended pseudo-instructions. - Peter Cordes
Another possibility: add a few instructions to your MARS program to use a file-write system call to write memory contents to a binary file. (Like between two labels to get the .text section) - Peter Cordes

1 Answers

1
votes

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