Assembly 如何从火星模拟器获取机器代码

Assembly 如何从火星模拟器获取机器代码,assembly,mips,mars-simulator,Assembly,Mips,Mars Simulator,我已经用Mars模拟器编写了一个MIPS汇编程序,我想将每个指令地址和机器代码保存在一个文件中,我知道Mars模拟器在“执行”部分执行这项工作,如何在文件中获得这些指令的副本? 如果这是不可能的,是否有任何网站做同样的事情,并提供机器代码 我的意思是我想要一份以下部分的副本: MARS是一个Java JAR,您可以轻松地将其用作库或对其进行反向工程(尽管源代码可用)。 事实上,如果您这样做,您很容易发现它有一个命令行界面: java -jar Mars4_5.jar h 虽然有一个用于“仅汇编

我已经用Mars模拟器编写了一个MIPS汇编程序,我想将每个指令地址和机器代码保存在一个文件中,我知道Mars模拟器在“执行”部分执行这项工作,如何在文件中获得这些指令的副本? 如果这是不可能的,是否有任何网站做同样的事情,并提供机器代码

我的意思是我想要一份以下部分的副本:


MARS是一个Java JAR,您可以轻松地将其用作库或对其进行反向工程(尽管源代码可用)。
事实上,如果您这样做,您很容易发现它有一个命令行界面:

java -jar Mars4_5.jar h
虽然有一个用于“仅汇编”的
a
开关,但它不会生成输出文件-它只是一个验证阶段

但是,如上所述,幸运的是这是Java,因此我们可以简单地重用所有的MARS类:

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()));
      
  }

}
当然,这只是一个基本的例子,您可以使用工具来实现您的目标(请注意,我不提供支持)。
尤其要注意多文件项目。我明确地将这个程序限制为仅一个文件


例子 要查看此文件的机器代码(称之为
testm.s
):

使用

要在输出中生成此值,请执行以下操作:

00400000 2402000b
00400004 24040061
00400008 0000000c
0040000c 2402000a
00400010 0000000c

clang-target mips-c foo.s
将汇编mips代码。(正常的clang安装通常内置支持多个目标体系结构)。您可以使用
objcopy
.o
中的二进制机器代码转换为普通二进制。但请注意,对于GNU汇编器来说,它比传统的MIPS汇编器(如SGI(MARS与之兼容))要多,而clang并没有执行那么多扩展伪指令。另一种可能性是:向MARS程序添加一些指令,以使用文件写入系统调用将内存内容写入二进制文件。(类似于两个标签之间以获得.text部分)
.text
li $v0, 11
la $a0, 'a'
syscall
li $v0, 10
syscall
java -cp MARS4_5.jar MarsCompiler testm.s
00400000 2402000b
00400004 24040061
00400008 0000000c
0040000c 2402000a
00400010 0000000c