摘要:第章虛擬機(jī)項(xiàng)目實(shí)現(xiàn)為防閑逛至此的看官不知所云是一個(gè)在線課程,目標(biāo)是指導(dǎo)學(xué)生從邏輯門開始從頭到尾完成一整套計(jì)算機(jī)系統(tǒng)。好像擼串一樣的爽快芯片硬件編譯原理操作系統(tǒng)應(yīng)用程序這里提供的是第八章的作業(yè),以供半路摔進(jìn)坑里的同學(xué)們扶一下。。。
[From Nand to Tetris] 第8章 虛擬機(jī)項(xiàng)目 python 實(shí)現(xiàn)
為防閑逛至此的看官不知所云: From Nand to Tetris 是一個(gè)在線課程,目標(biāo)是指導(dǎo)學(xué)生從 Nand 邏輯門開始從頭到尾完成一整套計(jì)算機(jī)系統(tǒng)。
好像擼串一樣的爽快:------芯片--硬件---編譯原理---操作系統(tǒng)---應(yīng)用程序------>
這里提供的是第八章的作業(yè),以供半路摔進(jìn)坑里的同學(xué)們扶一下。。。
人家老師確實(shí)是不希望擴(kuò)散答案,不過(guò)我做的過(guò)程中遇到很多坑,搞半天后發(fā)現(xiàn)全是些腦殘?jiān)颍瑢?shí)在是浪費(fèi)時(shí)間,希望卡殼的同學(xué)們能以增進(jìn)效率為目的適當(dāng)參考答案。畢竟學(xué)習(xí)這種東西,有沒有學(xué)到手只有自己知道。。。
注釋不多,因?yàn)榇a相當(dāng) self-explanatory ,就是書上那些,沒自由發(fā)揮什么。
如果你是閑逛進(jìn)來(lái),而且對(duì)這塊內(nèi)容有興趣的話,強(qiáng)烈建議點(diǎn)開上面的課程鏈接試試,我是真心非常喜歡這門課,請(qǐng)收下我的安利。。。
另外還有第六章的作業(yè)答案:第6章 匯編器項(xiàng)目 python 實(shí)現(xiàn)
# _*_ coding: utf-8 _*_ import sys import os import glob class C_TYPE: """Command Type""" C_ARITHMETIC, C_PUSH, C_POP, C_LABEL, C_GOTO, C_IF, C_FUNCTION, C_RETURN, C_CALL = range(9) class Parser: def __init__(self, fname): self.finput = open(fname, "rU") self.current = None self.commandPart = [] self.cType = -1 def __exit__(self, exc_type, exc_val, exc_tb): self.finput.close() def has_more_commands(self): self.current = self.finput.readline() while self.current == " " or self.current[:2] == "http://": self.current = self.finput.readline() return self.current != "" def advance(self): self.commandPart = self.current.strip().split(" ")[:3] if self.commandPart[0] == "add" or self.commandPart[0] == "sub" or self.commandPart[0] == "neg" or self.commandPart[0] == "eq" or self.commandPart[0] == "gt" or self.commandPart[0] == "lt" or self.commandPart[0] == "and" or self.commandPart[0] == "or" or self.commandPart[0] == "not": self.cType = C_TYPE.C_ARITHMETIC elif self.commandPart[0] == "push": self.cType = C_TYPE.C_PUSH elif self.commandPart[0] == "pop": self.cType = C_TYPE.C_POP elif self.commandPart[0] == "label": self.cType = C_TYPE.C_LABEL elif self.commandPart[0] == "goto": self.cType = C_TYPE.C_GOTO elif self.commandPart[0] == "if-goto": self.cType = C_TYPE.C_IF elif self.commandPart[0] == "function": self.cType = C_TYPE.C_FUNCTION elif self.commandPart[0] == "call": self.cType = C_TYPE.C_CALL elif self.commandPart[0] == "return": self.cType = C_TYPE.C_RETURN def command_type(self): return self.cType def arg1(self): if self.command_type() == C_TYPE.C_ARITHMETIC: return self.commandPart[0] return self.commandPart[1] def arg2(self): return self.commandPart[2] class CodeWriter: def __init__(self, fname): self.foutput = open(fname, "w") self.uniqueFlag = 0 # 用于構(gòu)造唯一的標(biāo)簽,每次使用后加1 self.currentFile = "" # 當(dāng)前處理的文件的名字 self.currentFunc = "" # 當(dāng)前處理的函數(shù)的名字 def set_file_name(self, fname): self.currentFile = fname def write_arithmetic(self, command): if command == "add": self.foutput.write("@SP M=M-1 A=M D=M @SP M=M-1 A=M M=M+D @SP M=M+1 ") elif command == "sub": self.foutput.write("@SP M=M-1 A=M D=M @SP M=M-1 A=M M=M-D @SP M=M+1 ") elif command == "neg": self.foutput.write("@SP M=M-1 A=M M=-M @SP M=M+1 ") elif command == "eq": self.foutput.write("@SP M=M-1 A=M D=M @SP M=M-1 A=M D=M-D @RET_TRUE"+str(self.uniqueFlag)+" " "D;JEQ D=0 @END"+str(self.uniqueFlag)+" 0;JMP (RET_TRUE"+str(self.uniqueFlag)+") " "D=-1 (END"+str(self.uniqueFlag)+") @SP A=M M=D @SP M=M+1 ") self.uniqueFlag += 1 elif command == "gt": self.foutput.write("@SP M=M-1 A=M D=M @SP M=M-1 A=M D=M-D @RET_TRUE"+str(self.uniqueFlag)+" " "D;JGT D=0 @END"+str(self.uniqueFlag)+" 0;JMP (RET_TRUE"+str(self.uniqueFlag)+") " "D=-1 (END"+str(self.uniqueFlag)+") @SP A=M M=D @SP M=M+1 ") self.uniqueFlag += 1 elif command == "lt": self.foutput.write("@SP M=M-1 A=M D=M @SP M=M-1 A=M D=M-D @RET_TRUE"+str(self.uniqueFlag)+" " "D;JLT D=0 @END"+str(self.uniqueFlag)+" 0;JMP (RET_TRUE"+str(self.uniqueFlag)+") " "D=-1 (END"+str(self.uniqueFlag)+") @SP A=M M=D @SP M=M+1 ") self.uniqueFlag += 1 elif command == "and": self.foutput.write("@SP M=M-1 A=M D=M @SP M=M-1 A=M M=M&D @SP M=M+1 ") elif command == "or": self.foutput.write("@SP M=M-1 A=M D=M @SP M=M-1 A=M M=M|D @SP M=M+1 ") elif command == "not": self.foutput.write("@SP M=M-1 A=M M=!M @SP M=M+1 ") def write_push_pop(self, command, segment, index): if command == C_TYPE.C_PUSH: if segment == "constant": self.foutput.write("@"+index+" D=A @SP A=M M=D @SP M=M+1 ") elif segment == "local": self.foutput.write("@LCL D=M @"+index+" A=A+D D=M @SP A=M M=D @SP M=M+1 ") elif segment == "argument": self.foutput.write("@ARG D=M @"+index+" A=A+D D=M @SP A=M M=D @SP M=M+1 ") elif segment == "this": self.foutput.write("@THIS D=M @"+index+" A=A+D D=M @SP A=M M=D @SP M=M+1 ") elif segment == "that": self.foutput.write("@THAT D=M @"+index+" A=A+D D=M @SP A=M M=D @SP M=M+1 ") elif segment == "pointer": self.foutput.write("@"+str(int(index)+3)+" D=M @SP A=M M=D @SP M=M+1 ") elif segment == "temp": self.foutput.write("@"+str(int(index)+5)+" D=M @SP A=M M=D @SP M=M+1 ") elif segment == "static": self.foutput.write("@"+self.currentFile+"."+index+" D=M @SP A=M M=D @SP M=M+1 ") elif command == C_TYPE.C_POP: if segment == "local": self.foutput.write("@LCL D=M @"+index+" D=A+D @R13 M=D @SP M=M-1 A=M D=M @R13 A=M M=D ") elif segment == "argument": self.foutput.write("@ARG D=M @"+index+" D=A+D @R13 M=D @SP M=M-1 A=M D=M @R13 A=M M=D ") elif segment == "this": self.foutput.write("@THIS D=M @"+index+" D=A+D @R13 M=D @SP M=M-1 A=M D=M @R13 A=M M=D ") elif segment == "that": self.foutput.write("@THAT D=M @"+index+" D=A+D @R13 M=D @SP M=M-1 A=M D=M @R13 A=M M=D ") elif segment == "pointer": self.foutput.write("@SP M=M-1 A=M D=M @"+str(int(index)+3)+" M=D ") elif segment == "temp": self.foutput.write("@SP M=M-1 A=M D=M @"+str(int(index)+5)+" M=D ") elif segment == "static": self.foutput.write("@SP M=M-1 A=M D=M @"+self.currentFile+"."+index+" M=D ") def write_label(self, label): self.foutput.write("("+self.currentFunc+"$"+label+") ") # 構(gòu)造 (funcName$label) 格式的標(biāo)記,網(wǎng)站上沒提,但書里有 def write_init(self): self.foutput.write("@256 D=A @SP M=D ") self.write_call("Sys.init", 0) def write_goto(self, label): self.foutput.write("@"+self.currentFunc+"$"+label+" 0;JMP ") def write_if(self, label): self.foutput.write("@SP M=M-1 A=M D=M @"+self.currentFunc+"$"+label+" D;JNE ") def write_call(self, function_name, num_args): self.foutput.write("@RETURN_ADDRESS"+str(self.uniqueFlag)+" D=A @SP A=M M=D @SP M=M+1 " "@LCL D=M @SP A=M M=D @SP M=M+1 " "@ARG D=M @SP A=M M=D @SP M=M+1 " "@THIS D=M @SP A=M M=D @SP M=M+1 " "@THAT D=M @SP A=M M=D @SP M=M+1 " "@SP D=M @"+str(int(num_args)+5)+" D=D-A @ARG M=D " "@SP D=M @LCL M=D " "@"+function_name+" 0;JMP " "(RETURN_ADDRESS"+str(self.uniqueFlag)+") ") self.uniqueFlag += 1 def write_return(self): self.foutput.write("@LCL D=M @R13 M=D " "@5 A=D-A D=M @R14 M=D " "@SP M=M-1 A=M D=M @ARG A=M M=D " "@ARG D=M+1 @SP M=D " "@R13 A=M-1 D=M @THAT M=D " "@R13 A=M-1 A=A-1 D=M @THIS M=D " # 蠢萌蠢萌的減n次1,比下一句還省一條指令。。。 "@R13 D=M @3 A=D-A D=M @ARG M=D " "@R13 D=M @4 A=D-A D=M @LCL M=D " "@R14 A=M 0;JMP ") def write_function(self, function_name, num_locals): self.currentFunc = function_name commandsInitLocals = "" for i in range(int(num_locals)): commandsInitLocals += "@LCL D=M @"+str(i)+" A=A+D M=0 " self.foutput.write("("+function_name+") "+commandsInitLocals) def close(self): self.foutput.close() def process_vm_file(fpath): """ 處理一個(gè) .vm 文件 fpath: 待處理 .vm 文件的絕對(duì)路徑 """ parser = Parser(fpath) writer.set_file_name(os.path.basename(fpath.strip(".vm"))) while parser.has_more_commands(): parser.advance() if parser.command_type() == C_TYPE.C_PUSH or parser.command_type() == C_TYPE.C_POP: writer.write_push_pop(parser.command_type(), parser.arg1(), parser.arg2()) elif parser.command_type() == C_TYPE.C_ARITHMETIC: writer.write_arithmetic(parser.arg1()) elif parser.command_type() == C_TYPE.C_LABEL: writer.write_label(parser.arg1()) elif parser.command_type() == C_TYPE.C_GOTO: writer.write_goto(parser.arg1()) elif parser.command_type() == C_TYPE.C_IF: writer.write_if(parser.arg1()) elif parser.command_type() == C_TYPE.C_CALL: writer.write_call(parser.arg1(), parser.arg2()) elif parser.command_type() == C_TYPE.C_FUNCTION: writer.write_function(parser.arg1(), parser.arg2()) elif parser.command_type() == C_TYPE.C_RETURN: writer.write_return() # main program if os.path.isfile(sys.argv[1]) and sys.argv[1].endswith(".vm"): # 參數(shù)為 .vm 文件,只翻譯一個(gè)文件 writer = CodeWriter(os.path.splitext(sys.argv[1])[0]+".asm") writer.write_init() process_vm_file(sys.argv[1]) elif os.path.isdir(sys.argv[1]): # 參數(shù)為文件夾,將文件夾中所有文件翻譯為 hack 匯編 writer = CodeWriter(sys.argv[1]+"/"+os.path.basename(sys.argv[1])+".asm") writer.write_init() for f in glob.glob(sys.argv[1] + "/*.vm"): process_vm_file(f)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/45396.html
摘要:今天折騰一上午,終于完成了上這個(gè)課程的最后一個(gè)匯編器項(xiàng)目。這套課程真是沒白跟,收獲良多,現(xiàn)在已經(jīng)等不及想看下一期的軟件部分了,哈哈。 今天折騰一上午,終于 完成了 Coursera 上 From Nand to Tetris / Part I 這個(gè)課程的最后一個(gè)匯編器項(xiàng)目。這套課程真是沒白跟,收獲良多,現(xiàn)在已經(jīng)等不及想看下一期的軟件部分了,哈哈。 下面是我的 python 實(shí)現(xiàn),存?zhèn)€...
摘要:作用是將標(biāo)準(zhǔn)輸入中的所有大寫字母轉(zhuǎn)換為響應(yīng)的小寫字母。的移植過(guò)的源代碼是在源代碼目錄下編譯的,所以源代碼目錄等于目標(biāo)文件目錄,所以條件不滿足,將執(zhí)行分支的代碼。 ????????一個(gè)嵌入式產(chǎn)品的開發(fā)階段,需要不斷地把bootloader下載到存儲(chǔ)器中,如果存儲(chǔ)器使用nand flash,但是...
摘要:自己定義的抽象基類要繼承。抽象基類可以包含具體方法。這里想表達(dá)的觀點(diǎn)是我們可以偷懶,直接從抽象基類中繼承不是那么理想的具體方法。 抽象基類 抽象基類的常見用途: 實(shí)現(xiàn)接口時(shí)作為超類使用。 然后,說(shuō)明抽象基類如何檢查具體子類是否符合接口定義,以及如何使用注冊(cè)機(jī)制聲明一個(gè)類實(shí)現(xiàn)了某個(gè)接口,而不進(jìn)行子類化操作。 如何讓抽象基類自動(dòng)識(shí)別任何符合接口的類——不進(jìn)行子類化或注冊(cè)。 接口在動(dòng)態(tài)類...
摘要:虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)分為以下幾個(gè)部分。程序計(jì)數(shù)器也是在虛擬機(jī)規(guī)范中唯一沒有規(guī)定任何異常情況的區(qū)域。在方法運(yùn)行期間不會(huì)改變局部變量表的大小。長(zhǎng)度在位和位的虛擬機(jī)中,分別為官方稱它為。 Java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū) 詳解 2.1 概述 本文參考的是周志明的 《深入理解Java虛擬機(jī)》第二章 ,為了整理思路,簡(jiǎn)單記錄一下,方便后期查閱。 2.2 運(yùn)行時(shí)數(shù)據(jù)區(qū)域 Java虛擬機(jī)在Java程序運(yùn)行時(shí)...
摘要:貢獻(xiàn)者飛龍版本最近總是有人問我,把這些資料看完一遍要用多長(zhǎng)時(shí)間,如果你一本書一本書看的話,的確要用很長(zhǎng)時(shí)間。為了方便大家,我就把每本書的章節(jié)拆開,再按照知識(shí)點(diǎn)合并,手動(dòng)整理了這個(gè)知識(shí)樹。 Special Sponsors showImg(https://segmentfault.com/img/remote/1460000018907426?w=1760&h=200); 貢獻(xiàn)者:飛龍版...
閱讀 3223·2021-09-09 11:39
閱讀 1228·2021-09-09 09:33
閱讀 1127·2019-08-30 15:43
閱讀 546·2019-08-29 14:08
閱讀 1733·2019-08-26 13:49
閱讀 2376·2019-08-26 10:09
閱讀 1545·2019-08-23 17:13
閱讀 2283·2019-08-23 12:57