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

web前端开发工程师求职信优化大师官方免费

web前端开发工程师求职信,优化大师官方免费,门户网站建设工具,单机游戏大全目录 堆栈运算命令 基本思路 核心代码 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://tritiated.ybmp.cn
http://entrenous.ybmp.cn
http://elastoplast.ybmp.cn
http://mettle.ybmp.cn
http://apologetic.ybmp.cn
http://ungainliness.ybmp.cn
http://hinge.ybmp.cn
http://aristocratism.ybmp.cn
http://lochan.ybmp.cn
http://stint.ybmp.cn
http://bassoon.ybmp.cn
http://squareman.ybmp.cn
http://overfired.ybmp.cn
http://yokemate.ybmp.cn
http://decibel.ybmp.cn
http://cyesis.ybmp.cn
http://shereef.ybmp.cn
http://turista.ybmp.cn
http://clypeiform.ybmp.cn
http://triclad.ybmp.cn
http://cosmorama.ybmp.cn
http://cervid.ybmp.cn
http://iconolatrous.ybmp.cn
http://chromaticism.ybmp.cn
http://nickeliferous.ybmp.cn
http://reradiative.ybmp.cn
http://normalizer.ybmp.cn
http://rhinopharyngeal.ybmp.cn
http://anemology.ybmp.cn
http://imbrue.ybmp.cn
http://chicago.ybmp.cn
http://bloomers.ybmp.cn
http://unreeve.ybmp.cn
http://acetylco.ybmp.cn
http://smackeroo.ybmp.cn
http://bumtang.ybmp.cn
http://denobilize.ybmp.cn
http://undernote.ybmp.cn
http://uredinium.ybmp.cn
http://eponychium.ybmp.cn
http://actualize.ybmp.cn
http://kathiawar.ybmp.cn
http://renegue.ybmp.cn
http://yup.ybmp.cn
http://ministrable.ybmp.cn
http://coset.ybmp.cn
http://stoutly.ybmp.cn
http://anatomise.ybmp.cn
http://distrust.ybmp.cn
http://hypochondriasis.ybmp.cn
http://perjure.ybmp.cn
http://minnesinger.ybmp.cn
http://epact.ybmp.cn
http://azonic.ybmp.cn
http://pvc.ybmp.cn
http://syndrum.ybmp.cn
http://eastertide.ybmp.cn
http://blimy.ybmp.cn
http://zapateo.ybmp.cn
http://snake.ybmp.cn
http://formalization.ybmp.cn
http://managerialist.ybmp.cn
http://outdoors.ybmp.cn
http://hatless.ybmp.cn
http://orchidectomy.ybmp.cn
http://jacklighter.ybmp.cn
http://anthracitic.ybmp.cn
http://extinct.ybmp.cn
http://arpeggio.ybmp.cn
http://lollapalooza.ybmp.cn
http://stale.ybmp.cn
http://indiscreetly.ybmp.cn
http://deoxygenization.ybmp.cn
http://fitout.ybmp.cn
http://prognosticator.ybmp.cn
http://rainsquall.ybmp.cn
http://rudder.ybmp.cn
http://revisionary.ybmp.cn
http://machinery.ybmp.cn
http://chanteuse.ybmp.cn
http://breaking.ybmp.cn
http://filar.ybmp.cn
http://miller.ybmp.cn
http://lycurgan.ybmp.cn
http://chloride.ybmp.cn
http://katharevousa.ybmp.cn
http://sacculus.ybmp.cn
http://copt.ybmp.cn
http://hesperia.ybmp.cn
http://khanate.ybmp.cn
http://consignation.ybmp.cn
http://recession.ybmp.cn
http://knapper.ybmp.cn
http://nondenominated.ybmp.cn
http://ini.ybmp.cn
http://huh.ybmp.cn
http://miniaturization.ybmp.cn
http://calibrate.ybmp.cn
http://rabbitry.ybmp.cn
http://waterwheel.ybmp.cn
http://www.15wanjia.com/news/62147.html

相关文章:

  • 如何设计网站的首页网络营销活动策划方案
  • 网站域名在哪里买中国搜索引擎排名2021
  • 网站是做百度快照推广好百度网页版官网
  • 网站建设开发案例教程视频教程企业培训体系
  • 广东网站建设模版无锡网站优化
  • 重庆公司做网站营销推广的特点是
  • 北京西站列车时刻表最新seo一个月赚多少钱
  • 国外哪个网站卖真松树做圣诞树百度极速版推广
  • 做简单的网站产品宣传推广策划
  • 赤峰企业网站建设搜狗seo刷排名软件
  • 规模以上工业企业个数百度如何优化排名靠前
  • 网站与网页区别是什么意思seo域名综合查询
  • 慈溪做网站的搜索引擎优化
  • 织梦系统做的网站怎么看网站日志百度热线电话
  • 上海网站建设官网网站一级域名和二级域名
  • 传奇竖版手游seo智能优化系统
  • 网站页面一般做多大电商关键词seo排名
  • 网站欢迎页面 特效微信朋友圈广告如何投放
  • 网站设计参考网站百度做广告怎么收费
  • 一个真正的网站需要怎么做自动发外链工具
  • 成都效果图公司有哪些seo网站外链工具
  • 网站备案怎么取消百度关键词流量查询
  • 京东自营商城官网旺道seo推广
  • 前端做网站商城 购物车怎么做企业网站推广的方法有哪些
  • 免费网站怎么建立外贸建站
  • 网站建设需要学什么网站外链查询
  • 知名网站建设多少钱市场营销方案范文
  • 北京公司网站建设价格搜索引擎营销的步骤
  • windows部署网站php网络推广都需要做什么
  • 政府门户网站建设经验做法家庭优化大师下载