一个随机生成mips汇编指令和其对应机器码的python程序

alkaid

使用指南

支持生成的指令为:add, sub, ori, lw, sw, beq, lui, nop

所有指令的涉及到的5位寄存器编号、16位立即数均为随机生成

除了:

sw固定为sw offset($0)offset只会从0x00000000开始顺序生成,每次 +4

lw固定为lw offset($0),并且只会从已经存储过数据的内存中读取,若没有存储过,会生成nop

beq只会跳转到当前指令后的1-10条指令 (因为跳到前面大概率死循环...)

程序会自动在mips汇编文件每一条指令前加入lable<i>:标识符

例如:

1
2
3
4
lable1:
nop
lable2:
add $1, $2, $3

下载地址:

文件名:mips ans hexCode generator.py
有效期限:2023-11-28 17:46
(无需存档)

源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 使用方法:运行完之后会自动在当前目录生成test.mips和test.txt文件,对应mips汇编和16进制机器码,导入运行即可
# ps. lw只会在已经存入过的内存范围内读取,sw会从0开始按顺序存入
# ppss. 为防止死循环或者过快结束,beq只会在当前指令的后10条指令之间跳转
from random import randint
from random import choice
instruct_R = {
"add": "100000",
"sub": "100010"
}
R = ["add", "sub"]
instruct_I = {
"ori": "001101",
"lw": "100011",
"sw": "101011",
"beq": "000100",
"lui": "001111"
}
I = ["ori", "lw", "sw", "beq", "lui"]
instructCounter = 0
memoryAddr = -1
instructNum = 300

def generate_R():
op = "000000"
rs = randint(0, 31)
rt = randint(0, 31)
rd = randint(0, 31)
shamt = "00000"
instruct = choice(R)
func = instruct_R[instruct]
mips = instruct + " $" + str(rd) + ", $" + str(rs) + ", $" + str(rt)
binCode = '0b' + op + bin(rs)[2:6].zfill(5) + bin(rt)[2:6].zfill(5) + bin(rd)[2:6].zfill(5) + shamt + func
hexCode = hex(int(binCode, 2))
return mips, binCode, hexCode
def generate_I():
global memoryAddr
instruct = choice(I)
op = instruct_I[instruct]
rs = randint(0, 31)
rt = randint(0, 31)
imm = randint(0, 65535)
# imm
if(instruct == "lw"):
if(memoryAddr == -1):
return "nop", "0b00000000000000000000000000000000", "0x00000000"
else:
imm = randint(0, memoryAddr) * 4
elif(instruct == "sw"):
memoryAddr = memoryAddr + 1
imm = memoryAddr * 4
elif(instruct == "beq"):
imm = randint(instructCounter + 1, min(instructCounter + 10, instructNum - 1))
# mips
if(instruct == "lui"):
rs = 0
mips = instruct + " $" + str(rt) + ", " + str(imm)
elif(instruct == "sw" or instruct == "lw"):
mips = instruct + " $" + str(rt) + ' ' + str(imm) + "($0)"
elif(instruct == "beq"):
mips = instruct + " $" + str(rt) + ", $" + str(rs) + ", " + "lable" + str(imm)
else:
mips = instruct + " $" + str(rt) + ", $" + str(rs) + ", " + str(imm)
binCode = '0b' + op + bin(rs)[2:6].zfill(5) + bin(rt)[2:6].zfill(5) + bin(imm)[2:17].zfill(16)
hexCode = hex(int(binCode, 2))
return mips, binCode, hexCode

if __name__ == "__main__":
mipsFile = open("test.mips", "w")
hexFile = open("test.txt", "w")
hexFile.write("v2.0 raw\n")
for i in range(1, instructNum):
code = "", "", ""
instructCounter = instructCounter + 1
if randint(0, 1) == 0:
code = generate_I()
else:
code = generate_R()
mipsFile.write("lable" + str(instructCounter) + ':\n')
mipsFile.write(code[0])
mipsFile.write("\n")
hexFile.write(code[2])
hexFile.write("\n")
print("lable" + str(instructCounter) + ':')
print(code)


ForeverYolo(助教) 回复 alkaid
助教认证

同学你好,设计的非常好,但在这里说几点:

1.可以通过设计一些"巧妙"的结构让跳转往前跳转不会出错,诸如在测试数据开头设置处理跳转区,让向前的跳转都跳转到这里来。

2.同学似乎没有考虑原地跳的情况,这反而是最容易出错的点。

3.强度需要进一步提升,以计算指令为例,计算指令的正负值,边界值,溢出值均需要测试。

继续加油!

0%