数字逻辑大作业:MIPS汇编器设计

题目

使用Python语言,实现一个MIPS的汇编器,将你常用到的汇编指令翻译为机器指令。

输入:汇编语言程序文件
输出:二进制或十六进制文件,采用Xilinx Vivado的COE文件格式

例如,对类似下面的汇编语言程序,能够顺利翻译为机器指令:

# 这是注释
addi $t1, $0, 100   #这也是注释,空行应该能够顺利跳过

addi $t2, $0, 200
add  $t3, $t1, $t2  # #符号后面的是注释
addi $t4, $0, 400
and  $t5, $t1, $t4
sub  $t2, $t3, $t4

要求支持以下指令

跳转分支类指令:bltz、j、jal、beq、blez
立即数类指令:addi、slti、andi、ori、xori、lui
Load/Store类指令:lb、lh、lw、sb、sh、sw
R类型指令:sll、srl、sra、jr、jalr、add、sub、and、or、xor、nor、slt
伪指令:
  nop(空操作,等效于addi $0, $0, 0)
  li $x, abcd(将一个32位立即数abcd加载到目标寄存器x,请使用lui等指令序列实现,请注意立即数是补码形式)
  mv $a, $b(将寄存器b内容复制到寄存器a中,等效于addi $a, $b, 0)
  not $a, $b(将寄存器b内容取反后复制到寄存器a中,等效于xori $a, $b, -1)
  neg $a, $b(将寄存器b内容取负后复制到寄存器a中,等效于sub $a, $0, $b)

输出的文件,采用COE文件格式。例如:

; This .COE file specifies the contents for a block memory of depth=16, and width=32.
memory_initialization_radix=16;
memory_initialization_vector=
12345678,
00ABCDEF,
AABBCCDD,
7788EEAA,
45678ABC,
12378221,
901AC912,
0034ABCD,
89898989,
56565656,
99112233,
16161616,
ABC888DD,
ED00ABCD,
78787777,
99090909;

解决方案

# Read and format the file
def justify_over(a, len):
    if len > a:
        return False
    else:
        return True

path = "mips.asm"
formatted = []
addr = {}
k = 0
PC = 0x00000000
PC = int(PC)
cnt = 0
Rtype = ['sll', 'srl', 'sra', 'jr', 'jalr', 'add', 'sub', 'and', 'or', 'xor', 'nor', 'slt', 'sllv', 'srlv', 'srav',
         'mult', 'mfhi', 'mflo', 'mthi', 'mtlo']
Itype = ['addi', 'slti', 'andi', 'ori', 'xori', 'lui']
Jtype = ['bltz', 'bgez', 'j', 'jal', 'beq', 'bne', 'blez', 'bgtz']
L_Stype = ['lb', 'lh', 'lw', 'sb', 'sh', 'sw']
Dtype = ['nop', 'li', 'mv', 'not', 'clear']
with open(path, "r", encoding="utf-8") as file:
    lines = file.readlines()
    for i in range(len(lines)):
        formatted.append([])
        line = lines[i]
        # delete the annotation and empty line
        if len(line) == 1:
            continue
        if '#' in line:
            line = line[:line.index('#')]
        if len(line) == 0:
            continue
        # delete the '\n'
        if '\n' in line:
            line = line[:-1]
        # format the mnemonic and operand
        mne = line.split()[0]
        formatted[i].append(mne)
        line = line[len(mne) + 1:]
        line = line.lstrip()
        if len(line) == 0:
            continue
        line_list = line.split(',')
        for j in range(len(line_list)):
            line_list[j] = line_list[j].strip()
        formatted[i] += line_list
k = 0
for i in range(len(formatted)):
    if len(formatted[i]) == 0:
        continue
    k += 1
    if len(formatted[i]) == 1 and formatted[i][0] not in Rtype and formatted[i][0] not in Itype and formatted[i][
        0] not in L_Stype and formatted[i][0] not in Jtype and formatted[i][0] not in Dtype:
        addr[(formatted[i][0])[:-1]] = int(PC + 4 * (k - 1)) - len(addr)

register = {
    '$0': 0,
    '$at': 1,
    '$v0': 2,
    '$v1': 3,
    '$a0': 4,
    '$a1': 5,
    '$a2': 6,
    '$a3': 7,
    '$t0': 8,
    '$t1': 9,
    '$t2': 10,
    '$t3': 11,
    '$t4': 12,
    '$t5': 13,
    '$t6': 14,
    '$t7': 15,
    '$s0': 16,
    '$s1': 17,
    '$s2': 18,
    '$s3': 19,
    '$s4': 20,
    '$s5': 21,
    '$s6': 22,
    '$s7': 23,
    '$t8': 24,
    '$t9': 25,
    '$k0': 26,
    '$k1': 27,
    '$gp': 28,
    '$sp': 29,
    '$fp': 30,
    '$ra': 31
}

codeToWrite = []
k = 0
for i in range(len(formatted)):
    if len(formatted[i]) == 0:
        continue
    try:
        # R type:sll、srl、sra、jr、jalr、add、sub、and、or、xor、nor、slt、sllv、srlv、srav、mult、mfhi、mflo、mthi、mtlo
        k += 1
        if formatted[i][0] in Rtype:
            op = '000000'
            rs = '00000'
            rt = '00000'
            rd = '00000'
            shamt = '00000'
            funct = '000000'
            match formatted[i][0]:
                case 'sll':
                    formatted[i][3] = int(formatted[i][3])
                    if formatted[i][3] >= 32:
                        print("Error\n line %d: invalid immediate" % (i + 1))
                        continue
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    shamt = bin(formatted[i][3])[2:].zfill(5)
                case 'srl':
                    formatted[i][3] = int(formatted[i][3])
                    if formatted[i][3] >= 32:
                        print("Error\n line %d: invalid immediate" % (i + 1))
                        continue
                    funct = '000010'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    shamt = bin(formatted[i][3])[2:].zfill(5)
                case 'sra':
                    formatted[i][3] = int(formatted[i][3])
                    if formatted[i][3] >= 32:
                        print("Error\n line %d: invalid immediate" % (i + 1))
                        continue
                    funct = '000011'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    shamt = bin(formatted[i][3])[2:].zfill(5)
                case 'jr':
                    funct = '001000'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                case 'jalr':
                    funct = '001001'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                case 'add':
                    funct = '100000'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'sub':
                    funct = '100010'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'and':
                    funct = '100100'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'or':
                    funct = '100101'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'xor':
                    funct = '100110'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'nor':
                    funct = '100111'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'slt':
                    funct = '101010'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'sllv':
                    funct = '000100'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    rs = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'srlv':
                    funct = '000110'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    rs = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'srav':
                    funct = '000111'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    rs = bin(register[formatted[i][3]])[2:].zfill(5)
                case 'mult':
                    funct = '011000'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                case 'mfhi':
                    funct = '010000'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                case 'mflo':
                    funct = '010010'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                case 'mthi':
                    funct = '010001'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                case 'mtlo':
                    funct = '010011'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
            code = (hex(int(op + rs + rt + rd + shamt + funct, 2))[2:]).zfill(8).upper()
        elif formatted[i][0] in Itype:
            rs = '00000'
            rt = '00000'
            match formatted[i][0]:
                case 'addi':
                    op = '001000'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    if formatted[i][3].startswith('0x'):
                        if int(formatted[i][3], 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3], 16))[2:].zfill(16)
                    else:
                        if int(formatted[i][3]) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3]))[2:].zfill(16)
                case 'slti':
                    op = '001010'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    if formatted[i][3].startswith('0x'):
                        if int(formatted[i][3], 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3], 16))[2:].zfill(16)
                    else:
                        if int(formatted[i][3]) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3]))[2:].zfill(16)
                case 'andi':
                    op = '001100'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    if formatted[i][3].startswith('0x'):
                        if int(formatted[i][3], 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3], 16))[2:].zfill(16)
                    else:
                        if int(formatted[i][3]) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3]))[2:].zfill(16)
                case 'ori':
                    op = '001101'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    if formatted[i][3].startswith('0x'):
                        if int(formatted[i][3], 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3], 16))[2:].zfill(16)
                    else:
                        if int(formatted[i][3]) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3]))[2:].zfill(16)
                case 'xori':
                    op = '001110'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    if formatted[i][3].startswith('0x'):
                        if int(formatted[i][3], 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3], 16))[2:].zfill(16)
                    else:
                        if int(formatted[i][3]) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(formatted[i][3]))[2:].zfill(16)
                case 'lui':
                    op = '001111'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)

                    if formatted[i][2].startswith('0x'):

                        imm = bin(int(formatted[i][2][:6], 16))[2:].zfill(16)

                    else:
                        if int(formatted[i][2]) >= 65536:
                            imm = bin(int(hex(int(formatted[i][2]))[:6], 16))[2:].zfill(16)
                        else:
                            imm = bin(int(formatted[i][2]))[2:].zfill(16)
            code = (hex(int(op + rs + rt + imm, 2))[2:]).zfill(8).upper()
        elif formatted[i][0] in Jtype:
            match formatted[i][0]:
                case 'bltz':
                    op = '000001'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = '00000'
                    label = formatted[i][2]
                    if label in addr:  ##BTA
                        n = 0
                        temp = PC + 4 * (k - 1)
                        for element in addr:
                            if addr[element] < temp:
                                n += 1
                        temp = temp - n
                        x = int((addr[label] - temp) / 4) - 1
                        if (x > 0):
                            ad = bin(x)[2:].zfill(16)
                        else:
                            ad = bin(x)[3:].zfill(16)
                            ad = ad.replace('1', '2').replace('0', '1').replace('2', '0')
                            ad = bin(int(ad, 2) + 1).replace('0b', '')
                        code = (hex(int(op + rs + rt + ad, 2))[2:]).zfill(8).upper()
                    else:
                        print("Error\n line %d: invalid label" % (i + 1))
                        continue
                case 'j':
                    op = '000010'
                    label = formatted[i][1]
                    if label in addr:  ##JTA
                        temp = addr[label]
                        test = bin(temp)[2:].zfill(32)[4:-2]
                        code = ((hex(int(op + test, 2)))[2:]).zfill(8).upper()
                    else:
                        print("Error\n line %d: invalid label" % (i + 1))
                        continue
                case 'bgez':
                    op = '000001'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = '00001'
                    label = formatted[i][2]
                    if label in addr:  ##BTA
                        n = 0
                        temp = PC + 4 * (k - 1)
                        for element in addr:
                            if addr[element] < temp:
                                n += 1
                        temp = temp - n
                        x = int((addr[label] - temp) / 4) - 1
                        if (x > 0):
                            ad = bin(x)[2:].zfill(16)
                        else:
                            ad = bin(x)[3:].zfill(16)
                            ad = ad.replace('1', '2').replace('0', '1').replace('2', '0')
                            ad = bin(int(ad, 2) + 1).replace('0b', '')
                        code = (hex(int(op + rs + rt + ad, 2))[2:]).zfill(8).upper()
                    else:
                        print("Error\n line %d: invalid label" % (i + 1))
                        continue
                case 'jal':
                    op = '000011'
                    label = formatted[i][1]
                    if label in addr:
                        temp = addr[label]
                        test = bin(temp)[2:].zfill(32)[4:-2]
                        code = ((hex(int(op + test, 2)))[2:]).zfill(8).upper()
                    else:
                        print("Error\n line %d: invalid label" % (i + 1))
                        continue
                case 'beq':
                    op = '000100'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    label = formatted[i][3]
                    if label in addr:  ##BTA
                        n = 0
                        temp = PC + 4 * (k - 1)
                        for element in addr:
                            if addr[element] < temp:
                                n += 1
                        temp = temp - n
                        x = int((addr[label] - temp) / 4) - 1
                        if (x > 0):
                            ad = bin(x)[2:].zfill(16)
                        else:
                            ad = bin(x)[3:].zfill(16)
                            ad = ad.replace('1', '2').replace('0', '1').replace('2', '0')
                            ad = bin(int(ad, 2) + 1).replace('0b', '')
                        code = (hex(int(op + rs + rt + ad, 2))[2:]).zfill(8).upper()
                    else:
                        print("Error\n line %d: invalid label" % (i + 1))
                        continue
                case 'bne':
                    op = '000101'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register[formatted[i][2]])[2:].zfill(5)
                    label = formatted[i][3]
                    if label in addr:  ##BTA
                        n = 0
                        temp = PC + 4 * (k - 1)
                        for element in addr:
                            if addr[element] < temp:
                                n += 1
                        temp = temp - n
                        x = int((addr[label] - temp) / 4) - 1
                        if (x > 0):
                            ad = bin(x)[2:].zfill(16)
                        else:
                            ad = bin(x)[3:].zfill(16)
                            ad = ad.replace('1', '2').replace('0', '1').replace('2', '0')
                            ad = bin(int(ad, 2) + 1).replace('0b', '')
                        code = (hex(int(op + rs + rt + ad, 2))[2:]).zfill(8).upper()
                case 'blez':
                    op = '000110'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = '00000'
                    label = formatted[i][2]
                    if label in addr:  ##BTA
                        n = 0
                        temp = PC + 4 * (k - 1)
                        for element in addr:
                            if addr[element] < temp:
                                n += 1
                        temp = temp - n
                        x = int((addr[label] - temp) / 4) - 1
                        if (x > 0):
                            ad = bin(x)[2:].zfill(16)
                        else:
                            ad = bin(x)[3:].zfill(16)
                            ad = ad.replace('1', '2').replace('0', '1').replace('2', '0')
                            ad = bin(int(ad, 2) + 1).replace('0b', '')
                        code = (hex(int(op + rs + rt + ad, 2))[2:]).zfill(8).upper()
                    else:
                        print("Error\n line %d: invalid label" % (i + 1))
                        continue
                case 'bgtz':
                    op = '000111'
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = '00000'
                    label = formatted[i][2]
                    if label in addr:  ##BTA
                        n = 0
                        temp = PC + 4 * (k - 1)
                        for element in addr:
                            if addr[element] < temp:
                                n += 1
                        temp = temp - n
                        x = int((addr[label] - temp) / 4) - 1
                        if (x > 0):
                            ad = bin(x)[2:].zfill(16)
                        else:
                            ad = bin(x)[3:].zfill(16)
                            ad = ad.replace('1', '2').replace('0', '1').replace('2', '0')
                            ad = bin(int(ad, 2) + 1).replace('0b', '')
                        code = (hex(int(op + rs + rt + ad, 2))[2:]).zfill(8).upper()
                    else:
                        print("Error\n line %d: invalid label" % (i + 1))
                        continue
        elif formatted[i][0] in L_Stype:
            match formatted[i][0]:
                case 'lw':
                    op = '100011'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    x = formatted[i][2].index('(')
                    y = formatted[i][2].index(')')
                    imm = formatted[i][2][:x]
                    rs = formatted[i][2][x + 1:y]
                    rs = bin(register[rs])[2:].zfill(5)
                    if imm.startswith('0x'):
                        if int(imm, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm, 16))[2:].zfill(16)
                    else:
                        if int(imm) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm))[2:].zfill(16)
                case 'sw':
                    op = '101011'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    x = formatted[i][2].index('(')
                    y = formatted[i][2].index(')')
                    imm = formatted[i][2][:x]
                    rs = formatted[i][2][x + 1:y]
                    rs = bin(register[rs])[2:].zfill(5)
                    if imm.startswith('0x'):
                        if int(imm, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm, 16))[2:].zfill(16)
                    else:
                        if int(imm) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm))[2:].zfill(16)
                case 'lb':
                    op = '100000'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    x = formatted[i][2].index('(')
                    y = formatted[i][2].index(')')
                    imm = formatted[i][2][:x]
                    rs = formatted[i][2][x + 1:y]
                    rs = bin(register[rs])[2:].zfill(5)
                    if imm.startswith('0x'):
                        if int(imm, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm, 16))[2:].zfill(16)
                    else:
                        if int(imm) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm))[2:].zfill(16)
                case 'sb':
                    op = '101000'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    x = formatted[i][2].index('(')
                    y = formatted[i][2].index(')')
                    imm = formatted[i][2][:x]
                    rs = formatted[i][2][x + 1:y]
                    rs = bin(register[rs])[2:].zfill(5)
                    if imm.startswith('0x'):
                        if int(imm, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm, 16))[2:].zfill(16)
                    else:
                        if int(imm) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm))[2:].zfill(16)
                case 'lh':
                    op = '100001'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    x = formatted[i][2].index('(')
                    y = formatted[i][2].index(')')
                    imm = formatted[i][2][:x]
                    rs = formatted[i][2][x + 1:y]
                    rs = bin(register[rs])[2:].zfill(5)
                    if imm.startswith('0x'):
                        if int(imm, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm, 16))[2:].zfill(16)
                    else:
                        if int(imm) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm))[2:].zfill(16)
                case 'sh':
                    op = '101001'
                    rt = bin(register[formatted[i][1]])[2:].zfill(5)
                    x = formatted[i][2].index('(')
                    y = formatted[i][2].index(')')
                    imm = formatted[i][2][:x]
                    rs = formatted[i][2][x + 1:y]
                    rs = bin(register[rs])[2:].zfill(5)
                    if imm.startswith('0x'):
                        if int(imm, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm, 16))[2:].zfill(16)
                    else:
                        if int(imm) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(imm))[2:].zfill(16)
            code = (hex(int(op + rs + rt + imm, 2))[2:]).zfill(8).upper()
        elif formatted[i][0] in Dtype:
            match formatted[i][0]:
                case 'nop':
                    op = '000000'
                    rs = '00000'
                    rt = '00000'
                    rd = '00000'
                    shamt = '00000'
                    funct = '000000'
                    rd = bin(register['$0'])[2:].zfill(5)
                    rt = bin(register['$0'])[2:].zfill(5)
                    shamt = bin(0)[2:].zfill(5)  ##sll $0,$0,0
                    code = (hex(int(op + rs + rt + rd + shamt + funct, 2))[2:]).zfill(8).upper()
                case 'li':
                    rs = '00000'
                    if formatted[i][0].stareswith('0x'):
                        up = formatted[i][2][2:6]
                        down = formatted[i][2][6:]
                        op = '001111'
                        rt = bin(register[formatted[i][1]])[2:].zfill(5)
                        if int(up, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(up, 16))[2:].zfill(16)
                        code = (hex(int(op + rs + rt + imm, 2))[2:]).zfill(8).upper()
                        print(code)
                        k += 1
                        op = '001101'
                        rt = bin(register[formatted[i][1]])[2:].zfill(5)
                        rs = rt
                        if int(down, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(down, 16))[2:].zfill(16)
                    else:
                        x = hex(formatted[i][2]).zfill(10)
                        up = x[2:6]
                        down = x[6:]
                        op = '001111'
                        rt = bin(register[formatted[i][1]])[2:].zfill(5)
                        if int(up, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(up, 16))[2:].zfill(16)
                        code = (hex(int(op + rs + rt + imm, 2))[2:]).zfill(8).upper()
                        print(code)
                        k += 1
                        op = '001101'
                        rt = bin(register[formatted[i][1]])[2:].zfill(5)
                        rs = rt
                        if int(down, 16) >= 65536:
                            print("Error\n line %d: invalid immediate" % (i + 1))
                            continue
                        imm = bin(int(down, 16))[2:].zfill(16)
                    code = (hex(int(op + rs + rt + imm, 2))[2:]).zfill(8).upper()
                case 'mv':
                    op = '000000'
                    rs = '00000'
                    rt = '00000'
                    rd = '00000'
                    shamt = '00000'
                    funct = '100000'
                    rd = bin(register[formatted[i][2]])[2:].zfill(5)
                    rs = bin(register[formatted[i][1]])[2:].zfill(5)
                    rt = bin(register['$0'])[2:].zfill(5)
                    code = (hex(int(op + rs + rt + rd + shamt + funct, 2))[2:]).zfill(8).upper()
                case 'clear':
                    op = '000000'
                    rs = '00000'
                    rt = '00000'
                    rd = '00000'
                    shamt = '00000'
                    funct = '100000'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register['$0'])[2:].zfill(5)
                    rt = bin(register['$0'])[2:].zfill(5)
                    code = (hex(int(op + rs + rt + rd + shamt + funct, 2))[2:]).zfill(8).upper()
                case 'not':
                    op = '000000'
                    rs = '00000'
                    rt = '00000'
                    rd = '00000'
                    shamt = '00000'
                    funct = '100111'
                    rd = bin(register[formatted[i][1]])[2:].zfill(5)
                    rs = bin(register[formatted[i][2]])[2:].zfill(5)
                    rt = bin(register['$0'])[2:].zfill(5)
                    code = (hex(int(op + rs + rt + rd + shamt + funct, 2))[2:]).zfill(8).upper()
        elif formatted[i][0][:-1] in addr:
            continue
        else:
            print("Error\n line %d: invalid mnemonic" % (i + 1))
            continue
        codeToWrite.append(code)
        cnt += 1
    except:
        print("Error\n line %d: invalid operand" % (i + 1))
        continue

outfile = open('output.coe', 'w')
outfile.write(
    "; This .COE file specifies the contents for a block memory of depth=%d, and width=32.\nmemory_initialization_radix=16;\nmemory_initialization_vector=\n" % cnt)
for i in range(len(codeToWrite)):
    if i != len(codeToWrite) - 1:
        outfile.write("%s,\n" % codeToWrite[i])
    else:
        outfile.write("%s;" % codeToWrite[i])
outfile.close()
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值