数字逻辑大作业: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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值