计算机系统要素:第六章 Part2 汇编编译器(symbol)
生活随笔
收集整理的這篇文章主要介紹了
计算机系统要素:第六章 Part2 汇编编译器(symbol)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
要給匯編編譯器加入符號,首先要明確這個匯編編譯器有哪些符號:
預定義符號:SP,LCL等,這些符號預先就在SymbleTable中定義好了對應內(nèi)存的地址
變量variables:注意,變量是在第二遍讀取階段才依次從地址16開始計算的
標簽符號lables:你會在機器碼中見到(LOOP)@LOOP 這樣的循環(huán)代碼,這些就是標簽代碼,之所以要分兩遍讀取,就是因為(LOOP)這樣的標簽有可能出現(xiàn)在@LOOP之前,如果只讀取一遍的話無法解決這個問題,因此第一遍讀取的目的就是把所有標簽的地址給確定。而標簽的地址,按照書上的說法,是由(XXX)之前總的指令數(shù)決定的。
本書作者已經(jīng)幫我們把問題最簡化了,只要分別考慮這三類符號如何表示就能夠在nonsymbol編譯器的基礎(chǔ)上完成這一部分的內(nèi)容。
Parser和Code模塊與nonsymbol編譯器相同,不再列出。
SymbolTable.py
這個模塊有些多此一舉,因為很多函數(shù)在python中都有內(nèi)置函數(shù)可以直接使用,但是為了遵守API規(guī)范,還是把這些函數(shù)都列出來了。
#!/usr/bin/python def Constructor():symboldict={'SP' : 0,'LCL' : 1,'ARG' : 2,'THIS' : 3,'THAT' : 4,\'R0' : 0,'R1' : 1,'R2' : 2,'R3' : 3,'R4' : 4,'R5' : 5,'R6' : 6,'R7' : 7,\'R8' : 8,'R9' : 9,'R10' : 10,'R11' : 11,'R12' : 12,'R13' : 13,'R14' : 14,\'R15' : 15,'SCREEN' : 16384,'KBD' : 24576}return symboldictdef addEntry(symbol,address,symboldict):symboldict[symbol]=addressreturn symboldictdef contains(symbol,symboldict):return symboldict.has_key(symbol)def GetAddress(symbol,symboldict):return symboldict[symbol]
Assembler.py
#!/usr/bin/python import sys import Parser import Code import SymbolTablefilename=sys.argv[1] #The first Loop, aiming to decide the lables' addresses symboldict=SymbolTable.Constructor() rfile = open(filename,'r') i=0 #i is the sum of the construction numbers above lables linepre=rfile.readline() flag=Parser.hasMoreCommands(linepre) while flag:#clean the line which starts with // or blank lineswhile linepre == '\n' or linepre.startswith('//'):linepre=rfile.readline()if linepre.find('(')>=0:symbol=linepre.strip('()\n')if not SymbolTable.contains(symbol,symboldict):symboldict=SymbolTable.addEntry(symbol,i,symboldict)else: i+=1linepre=Parser.advance(rfile,linepre)flag=Parser.hasMoreCommands(linepre)rfile.close()#The second Loop j=0 #j records the total number of previous variables rfile = open(filename,'r') wfile = open('prog.hack','w') #main loop line=rfile.readline() flag=Parser.hasMoreCommands(line) while flag:while line == '\n' or line.startswith('//'):line=rfile.readline()ctype=Parser.commandType(line)#compare command typeif ctype is 'A_COMMAND':AS=Parser.symbol(line)if not AS.isdigit():if not SymbolTable.contains(AS,symboldict):symboldict=SymbolTable.addEntry(AS,j+16,symboldict)j+=1binAS=bin(SymbolTable.GetAddress(AS,symboldict))[2:]else:binAS=bin(int(AS))[2:]AString=binAS.zfill(15)wfile.write('0'+AString+'\n')#L_COMMAND should be deletedelif ctype is 'C_COMMAND':DestString=Code.dest(line)CompString=Code.comp(line)JumpString=Code.jump(line)wfile.write('111'+CompString+DestString+JumpString+'\n')line=Parser.advance(rfile,line)flag=Parser.hasMoreCommands(line)rfile.close() wfile.close()注意點:
1,兩次循環(huán)的問題
2,A指令中數(shù)字變量和字幕變量的分情況處理
總結(jié)
以上是生活随笔為你收集整理的计算机系统要素:第六章 Part2 汇编编译器(symbol)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言上机总结报告,C语言程序设计上机实
- 下一篇: vs2017+ivf+abaqus