当前位置: 首页 > news >正文

衡水微信网站建设百度 个人中心首页

衡水微信网站建设,百度 个人中心首页,做棋牌网站建设哪家便宜,自助购物网站怎么做目录 堆栈运算命令 基本思路 核心代码 Parser Code Writer Main 实验结果,使用SimpleAdd、StackTest进行验证 内存访问命令 基本思路 核心代码 Parser Code Writer Main 实验结果,使用进行验证。对比生成的二进制代码文件。 用Java写一个翻…

目录

堆栈运算命令

基本思路

核心代码

Parser

Code Writer

Main

实验结果,使用SimpleAdd、StackTest进行验证

内存访问命令

基本思路

核心代码

Parser

Code Writer

Main

实验结果,使用进行验证。对比生成的二进制代码文件。


用Java写一个翻译器,将Java的字节码翻译成汇编语言 

堆栈运算命令

基本思路

主要写两个类,一个解析器类Parser负责处理输入的vm文件,解析vm指令,一个类CodeWriter负责将经过Parser解析过的vm指令翻译成汇编指令,输出asm文件。

首先编写类Parser,有六个成员函数,包含构造函数负责打开文件流并准备读取vm指令,hasMoreCommands函数判断是否还有指令,advance函数负责将vm指令处理干净,去掉空白和注释,commandType函数判断vm指令的类型,arg1和arg2函数负责返回指令的组成部分。

然后编写CodeWriter类,构造函数打开一个文件,准备写入asm指令,writeArithmetic函数写入算术逻辑运算asm指令,writerPushPop函数写入push和pop的asm指令。

然后最关键的地方来了,如何从vm指令到asm指令?

我们首先从算术逻辑运算指令来看,以二元运算为例,计算的两个数是放在栈上的,位于栈指针SP上面两个位置,而我们只有M和D两个寄存器可以用来计算,在A寄存器保存栈指针地址的情况下。

因此,对于所有二元运算,我们首先要把参与计算的两个数放在M和D寄存器上,具体操作是,栈指针SP自减,把M的值赋给D,然后再将栈指针上移。

然后再执行二元运算,这样就比较简单了。

对于一元运算比较简单,直接栈指针自减,对M进行操作即可。

而对于gt、eq和lt这样比较指令,则比较复杂,因为涉及到跳转,同样是二元运算,因此我们需要先按照上述方法先将参与计算的两个数拿出来放在M和D寄存器,然后计算M和D的差,通过比较差和0的大小来跳转。

而对于push constant x指令,将一个常数压入栈就比较简单了。

拿到常数的值后将它写入栈指针执行的内存,然后栈指针自增就行了。

核心代码

Parser

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Objects;
import java.util.Scanner;public class Parser {private String command = null;private Scanner scanner = null;private String cmd0 = null;private String cmd1 = null;private int cmd2;public Parser(File file) throws FileNotFoundException {scanner = new Scanner(new FileReader(file));}public boolean hasMoreCommands() {boolean hasMore = false;while (scanner.hasNextLine()) {command = scanner.nextLine();if (!Objects.equals(command, "") && command.charAt(0) != '/') { //去掉空白行和注释String[] pure = command.split("/");command = pure[0];hasMore = true;break;}}return hasMore;}public void advance() {String[] cmd = command.split(" ");cmd0 = cmd[0];if (cmd.length > 1) {cmd1 = cmd[1];if (cmd.length > 2) {cmd2 = Integer.parseInt(cmd[2]);}}}public String commandType() {if (Objects.equals(cmd0, "push")) {return "C_PUSH";} else {return "C_ARITHMETIC";}}public String arg1() {if (Objects.equals(commandType(), "C_ARITHMETIC"))return cmd0;return cmd1;}public int arg2() {return cmd2;}public void close(){scanner.close();}}

Code Writer

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;public class CodeWriter {private FileWriter asm = null;private String asmCommand;private final HashMap<String, String> vmToAsm = new HashMap<>();private int jump=0;public CodeWriter(File file) throws IOException {asm = new FileWriter(file);String fetch = "@SP\nM=M-1\nA=M\nD=M\nA=A-1\n";vmToAsm.put("add", fetch + "M=M+D\n");vmToAsm.put("sub", fetch + "M=M-D\n");vmToAsm.put("and", fetch + "M=M&D\n");vmToAsm.put("or", fetch + "M=M|D\n");vmToAsm.put("gt", fetch + "D=M-D\n@TRUE\nD;JGT\n@SP\nA=M-1\nM=0\n@END\n0;JMP\n(TRUE)\n@SP\nA=M-1\nM=-1\n(END)\n");vmToAsm.put("eq", fetch + "D=M-D\n@TRUE\nD;JEQ\n@SP\nA=M-1\nM=0\n@END\n0;JMP\n(TRUE)\n@SP\nA=M-1\nM=-1\n(END)\n");vmToAsm.put("lt", fetch + "D=M-D\n@TRUE\nD;JLT\n@SP\nA=M-1\nM=0\n@END\n0;JMP\n(TRUE)\n@SP\nA=M-1\nM=-1\n(END)\n");vmToAsm.put("neg", "D=0\n@SP\nA=M-1\nM=D-M\n");vmToAsm.put("not", "@SP\nA=M-1\nM=!M\n");}public void writeArithmetic(String vmCommand) throws IOException {asmCommand=vmToAsm.get(vmCommand);if(Objects.equals(vmCommand, "gt") || Objects.equals(vmCommand, "eq") || Objects.equals(vmCommand, "lt")){asmCommand=asmCommand.replaceAll("TRUE","TRUE"+Integer.toString(jump));asmCommand=asmCommand.replaceAll("END","END"+Integer.toString(jump));jump++;}asm.write(asmCommand);}public void writePushPop(String cmd, String segment, int index) throws IOException {if (Objects.equals(cmd, "C_PUSH")) {if (Objects.equals(segment, "constant")) {asmCommand = "@" + Integer.toString(index) + "\nD=A\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";}}asm.write(asmCommand);}public void close() throws IOException {asm.close();}
}

Main

import java.io.File;
import java.io.IOException;
import java.util.Objects;public class Main {public static void main(String[] args) throws IOException {Parser parser=new Parser(new File("C:\\Users\\Yezi\\Desktop\\Java程序设计\\nand2tetris\\projects\\07\\StackArithmetic\\StackTest\\StackTest.vm"));CodeWriter codeWriter=new CodeWriter(new File("C:\\Users\\Yezi\\Desktop\\Java程序设计\\nand2tetris\\projects\\07\\StackArithmetic\\StackTest\\StackTest.asm"));while(parser.hasMoreCommands()){parser.advance();if(Objects.equals(parser.commandType(), "C_ARITHMETIC")){codeWriter.writeArithmetic(parser.arg1());}else{codeWriter.writePushPop(parser.commandType(), parser.arg1(), parser.arg2());}}codeWriter.close();parser.close();}
}

实验结果,使用SimpleAdd、StackTest进行验证

我们用CPU Emulator装载.tst文件,用运行程序得到的.out文件和所给的.cmp文件进行比较,其中SimpleAdd比较结果如下图所示,可见成功翻译

StackTest的结果如下图所示,可见第一阶段翻译成功。

内存访问命令

基本思路

首先要搞明白的是,push操作是将内存上的数值压入栈中,而pop操作是将栈中的数值弹出来到内存中。

对于constant段,我们第一阶段已经解决了。

对于local、argument、this和that字段,就是从它们相应的内存地址上读取或写入数据。

Push的话,先拿到segment+i的地址所指向的数值,然后将这个数值压入栈中,栈指针自增。

Pop的话,要复杂一些,因为我们只有A、M和D寄存器可以用,而pop我们首先要拿到segment+i的地址,所以我们要先找一个地方存下来,原本的R系列寄存器在这里已经被字段占用了,所以我们这里取地址255的内存空间暂存一下地址。

而temp字段的push和pop操作相对而言要简单许多。

此时读写的地址为5+i。

对于pointer字段,其实就是把this和that的数值压入栈或者弹栈的数值到this和that中。

当参数为0时,对this进行操作,当参数为1时,对that进行操作,在this和that的地址上进行读写数据。

而对于static字段,与前面的字段相比,不过就是换了运算的地址空间而已。

Asm代码基本和前面的操作一样,就是运算的地址变成了16开始的地址。

核心代码

Parser

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Objects;
import java.util.Scanner;public class Parser {private String command = null;private final Scanner scanner;private String cmd0 = null;private String cmd1 = null;private int cmd2;public Parser(File file) throws FileNotFoundException {scanner = new Scanner(new FileReader(file));}public boolean hasMoreCommands() {boolean hasMore = false;while (scanner.hasNextLine()) {command = scanner.nextLine();if (!Objects.equals(command, "") && command.charAt(0) != '/') { //去掉空白行和注释String[] pure = command.split("/");command = pure[0];hasMore = true;break;}}return hasMore;}public void advance() {String[] cmd = command.split(" ");cmd0 = cmd[0];if (cmd.length > 1) {cmd1 = cmd[1];if (cmd.length > 2) {cmd2 = Integer.parseInt(cmd[2]);}}}public String commandType() {if (Objects.equals(cmd0, "push")) {return "C_PUSH";} else if (Objects.equals(cmd0, "pop")) {return "C_POP";} else {return "C_ARITHMETIC";}}public String arg1() {if (Objects.equals(commandType(), "C_ARITHMETIC"))return cmd0;return cmd1;}public int arg2() {return cmd2;}public void close() {scanner.close();}}

Code Writer

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;public class CodeWriter {private final FileWriter asm;private String asmCommand;private final HashMap<String, String> vmToAsm = new HashMap<>();private int jump = 0;public CodeWriter(File file) throws IOException {asm = new FileWriter(file);String fetch = "@SP\nM=M-1\nA=M\nD=M\nA=A-1\n";vmToAsm.put("add", fetch + "M=M+D\n");vmToAsm.put("sub", fetch + "M=M-D\n");vmToAsm.put("and", fetch + "M=M&D\n");vmToAsm.put("or", fetch + "M=M|D\n");vmToAsm.put("gt", fetch + "D=M-D\n@TRUE\nD;JGT\n@SP\nA=M-1\nM=0\n@END\n0;JMP\n(TRUE)\n@SP\nA=M-1\nM=-1\n(END)\n");vmToAsm.put("eq", fetch + "D=M-D\n@TRUE\nD;JEQ\n@SP\nA=M-1\nM=0\n@END\n0;JMP\n(TRUE)\n@SP\nA=M-1\nM=-1\n(END)\n");vmToAsm.put("lt", fetch + "D=M-D\n@TRUE\nD;JLT\n@SP\nA=M-1\nM=0\n@END\n0;JMP\n(TRUE)\n@SP\nA=M-1\nM=-1\n(END)\n");vmToAsm.put("neg", "D=0\n@SP\nA=M-1\nM=D-M\n");vmToAsm.put("not", "@SP\nA=M-1\nM=!M\n");}public void writeArithmetic(String vmCommand) throws IOException {asmCommand = vmToAsm.get(vmCommand);if (Objects.equals(vmCommand, "gt") || Objects.equals(vmCommand, "eq") || Objects.equals(vmCommand, "lt")) {asmCommand = asmCommand.replaceAll("TRUE", "TRUE" + jump);asmCommand = asmCommand.replaceAll("END", "END" + jump);jump++;}asm.write(asmCommand);}public void writePushPop(String cmd, String segment, int index) throws IOException {if (Objects.equals(cmd, "C_PUSH")) {if (Objects.equals(segment, "constant")) {asmCommand = "@" + index + "\nD=A\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";} else if (Objects.equals(segment, "local")) {asmCommand = "@LCL\nD=M\n@" + index + "\nA=D+A\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";} else if (Objects.equals(segment, "argument")) {asmCommand = "@ARG\nD=M\n@" + index + "\nA=D+A\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";} else if (Objects.equals(segment, "this")) {asmCommand = "@THIS\nD=M\n@" + index + "\nA=D+A\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";} else if (Objects.equals(segment, "that")) {asmCommand = "@THAT\nD=M\n@" + index + "\nA=D+A\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";} else if (Objects.equals(segment, "temp")) {asmCommand = "@" + (5 + index) + "\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";} else if (Objects.equals(segment, "pointer")) {if (index == 0) {asmCommand = "@THIS\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";} else {asmCommand = "@THAT\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";}} else if (Objects.equals(segment, "static")) {asmCommand = "@" + (16 + index) + "\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n";}} else {if (Objects.equals(segment, "local")) {asmCommand = "@LCL\nD=M\n@" + index + "\nD=D+A\n@255\nM=D\n@SP\nM=M-1\nA=M\nD=M\n@255\nA=M\nM=D\n";} else if (Objects.equals(segment, "argument")) {asmCommand = "@ARG\nD=M\n@" + index + "\nD=D+A\n@255\nM=D\n@SP\nM=M-1\nA=M\nD=M\n@255\nA=M\nM=D\n";} else if (Objects.equals(segment, "this")) {asmCommand = "@THIS\nD=M\n@" + index + "\nD=D+A\n@255\nM=D\n@SP\nM=M-1\nA=M\nD=M\n@255\nA=M\nM=D\n";} else if (Objects.equals(segment, "that")) {asmCommand = "@THAT\nD=M\n@" + index + "\nD=D+A\n@255\nM=D\n@SP\nM=M-1\nA=M\nD=M\n@255\nA=M\nM=D\n";} else if (Objects.equals(segment, "temp")) {asmCommand = "@SP\nM=M-1\nA=M\nD=M\n@" + (5 + index) + "\nM=D\n";} else if (Objects.equals(segment, "pointer")) {if (index == 0) {asmCommand = "@SP\nM=M-1\nA=M\nD=M\n@THIS\nM=D\n";} else {asmCommand = "@SP\nM=M-1\nA=M\nD=M\n@THAT\nM=D\n";}} else if (Objects.equals(segment, "static")) {asmCommand = "@SP\nM=M-1\nA=M\nD=M\n@" + (16 + index) + "\nM=D\n";}}asm.write(asmCommand);}public void close() throws IOException {asm.close();}
}

Main

main函数没变

实验结果,使用进行验证。对比生成的二进制代码文件。

我们用CPU Emulator装载.tst文件,用运行程序得到的.out文件和所给的.cmp文件进行比较,其中BasicTest的比较结果如下图所示,可见成功翻译。

PointerTest的比较结果如下图所示,可见成功翻译

StaticTest的结果如下图所示,可见第二阶段翻译成功。

http://www.ritt.cn/news/23330.html

相关文章:

  • 电信的网做的网站移动网打不开该找电信还是移动营销软文300字范文
  • 宁波专业网站搭建地址百度推广需要什么条件
  • 护栏板销售网站怎么做如何注册域名及网站
  • 做物流的网站都有什么作用英语seo
  • 百度关键词优化外包天津seo关键词排名优化
  • 深圳专业做网站排名公司成都新站软件快速排名
  • php网站开发工程师招聘会it行业培训机构一般多少钱
  • 张掖专业做网站的公司抖音seo什么意思
  • 南充做网站 www.xinbay.com注册网站查询
  • 宣传网站有哪些淘宝关键词搜索工具
  • 网站免费网站app优化设计三年级上册答案语文
  • 郑州做网站hnmaorui电商培训机构有哪些?哪家比较好
  • 重庆网站设计工作室优化公司组织架构
  • 中力建设网站郑州网站推广排名公司
  • 做网站的服务器多少钱网站流量统计系统
  • wordpress 插件 加速seo招聘网
  • 专业建站教程网络舆情监测
  • 哈尔滨网站建设推广营销策划方案案例
  • 云南做网站费用怎么开通百度推广账号
  • 看24小时b站直播环球军事新闻最新消息
  • 网站制作_做网站_耐思智慧自己做网站网页归档
  • 做挂件的网站一个完整的营销策划案范文
  • 天台城乡规划建设局网站互联网广告投放
  • 杭州电子网站建设方案seo关键词大搜
  • 做国外网站需要多少钱如何开展网络营销
  • 门户网站开发视频教学windows优化工具
  • 新网店怎么免费推广国内做seo最好的公司
  • 企业做网站费用网络营销八大工具
  • 网站建设宣传文案百度售后服务电话
  • 品牌型网站开发网络营销案例分析题及答案