硬件设计测试中,MIPS汇编指令翻译成二进制编码的Python实现

最近在做计算机体系结构与组成原理的实验,需要写MIPS指令系统的CPU。在测试时,人工将需要测试的指令翻译成二进制的编码实在有些繁琐,而且极易出错,正好最近在学习python,就写了一个实用的脚本,来完成这个工作。

 

由于我们实现的CPU暂时只实现了16条指令,分别是:

 

add rd,rs,rt 

addu rd,rs,rt 

addi rt,rs,imm 

addiu rt,rs,imm 

sub rd,rs,rt 

subu rd,rs,rt 

nor rd,rs,rt 

xori rt,rs,imm 

clo rd, rs

clz rs,rs

slt rd,rs,rt 

sltu rd,rs,rt 

slti rt,rs,imm 

 

sltiu rt,rs imm 

blez rs,imm 

j target 

 

因此这个脚本只涉及了这些指令的内容,以后再扩展吧。

 

 

下面说一下实现思路:

1、从一个文件中读取MIPS的汇编指令;

2、通过字符串处理,然后将其各个部分进行匹配;

3、将生成的二进制编码写到一个文件中。

 

 

需要注意的是,指令应该向上边的示例一样,在操作符和操作数之间应该有个空格,操作数之间以逗号和若干(最好0)个空格分隔,每行写一条指令,指令前最好没有空字符。由于这个脚本主要是自己用,鲁棒性不是很好,见谅。

 

下面直接上代码:

import os def readfile(filename): """read and store test file""" try: fobj = open(filename, 'r') except IOError, e: print "*** file open error:", e else: lines = [] for eachLine in fobj: lines.append(eachLine) fobj.close() return lines def writefile(filename, l): """write the file with the binary""" ls = os.linesep fobj = open(filename, 'w') fobj.writelines(['%s%s' % (x, ls) for x in l]) fobj.close() print 'DONE!' def splitOandD(inst): """split the op and data""" sinst = [] for x in inst: z = x.rstrip() y = z.split(' ', 1) sinst.append(y); return sinst def numtobin(num, count): """tran a num to binary""" s = (bin(num))[2:] ss = ((count - len(s)) * '0') + s return ss def regtobin(reg): """make a regs to binary""" regs = reg.lstrip() regnum = regs[1:] if((int)(regnum) <= 31 and (int)(regnum) >= 0): regb = numtobin((int)(regnum), 5) return regb else: print "***no regs: ", regs return regb def handle(ins): """handle the strings to regular binary code""" op = (str)(ins[0]) data = (str)(ins[1]) sdata = data.lstrip() dl = sdata.split(',') if op == "add": opcode = "000000" rd = regtobin(dl[0]) rs = regtobin(dl[1]) rt = regtobin(dl[2]) func = "100000" incode = opcode+rs+rt+rd+"00000"+func elif op == "addu": opcode = "000000" rd = regtobin(dl[0]) rs = regtobin(dl[1]) rt = regtobin(dl[2]) func = "100001" incode = opcode+rs+rt+rd+"00000"+func elif op == "addi": opcode = "001000" rt = regtobin(dl[0]) rs = regtobin(dl[1]) imm = numtobin((int)(dl[2]), 16) incode = opcode + rs + rt + imm elif op == "addiu": opcode = "001001" rt = regtobin(dl[0]) rs = regtobin(dl[1]) imm = numtobin((int)(dl[2]), 16) incode = opcode + rs + rt + imm elif op == "sub": opcode = "000000" rd = regtobin(dl[0]) rs = regtobin(dl[1]) rt = regtobin(dl[2]) func = "100010" incode = opcode+rs+rt+rd+"00000"+func elif op == "subu": opcode = "000000" rd = regtobin(dl[0]) rs = regtobin(dl[1]) rt = regtobin(dl[2]) func = "100011" incode = opcode+rs+rt+rd+"00000"+func elif op == "nor": opcode = "000000" rd = regtobin(dl[0]) rs = regtobin(dl[1]) rt = regtobin(dl[2]) func = "100111" incode = opcode+rs+rt+rd+"00000"+func elif op == "xori": opcode = "001110" rt = regtobin(dl[0]) rs = regtobin(dl[1]) imm = numtobin((int)(dl[2]), 16) incode = opcode + rs + rt + imm elif op == "clo": opcode = "011100" rd = regtobin(dl[0]) rs = regtobin(dl[1]) func = "100001" incode = opcode + rs + "00000" + rd + "00000" + func elif op == "clz": opcode = "011100" rd = regtobin(dl[0]) rs = regtobin(dl[1]) func = "100000" incode = opcode + rs + "00000" + rd + "00000" + func elif op == "slt": opcode = "000000" rd = regtobin(dl[0]) rs = regtobin(dl[1]) rt = regtobin(dl[2]) func = "101010" incode = opcode+rs+rt+rd+"00000"+func elif op == "sltu": opcode = "000000" rd = regtobin(dl[0]) rs = regtobin(dl[1]) rt = regtobin(dl[2]) func = "101011" incode = opcode+rs+rt+rd+"00000"+func elif op == "slti": opcode = "001010" rt = regtobin(dl[0]) rs = regtobin(dl[1]) imm = numtobin((int)(dl[2]), 16) incode = opcode + rs + rt + imm elif op == "sltiu": opcode = "001011" rt = regtobin(dl[0]) rs = regtobin(dl[1]) imm = numtobin((int)(dl[2]), 16) incode = opcode + rs + rt + imm elif op == "blez": opcode = "000110" rs = regtobin(dl[0]) imm = numtobin((int)(dl[1]), 16) incode = opcode + rs + "00000" + imm elif op == "j": opcode = "000010" imm = numtobin((int)(dl[0]), 26) incode = opcode + imm else: print "***Not Define: ", op return incode def main(): l = readfile("i.txt") s = splitOandD(l) b = [] print s for m in s: if m != ['']: print m b.append(handle(m)) writefile("o.txt", b) if __name__ == "__main__": main() 

 

Reference:

《Mips instruction Reference》

http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html

你可能感兴趣的:(python,汇编,测试,脚本,File,reference)