CPU不加功能了,但汇编器可以有。
下面写一个把汇编(助记符)翻译成机器码的小工具。Python熟些,就用它了。很简单,就是字符串替换。直接上代码。
import sys
if len(sys.argv) != 2:
print("usage: python assembler xxx.asm")
exit(0)
code_path = sys.argv[1]
print('processing %s' % code_path)
op_dict={'ldr':0,'mov':0,'add':1,'sub':2,'and':3,'or':4,'cmp':5,'beq':6,'bne':7}
for i,line in enumerate(open(code_path).readlines()):
try:
line = line.split('//')[0]
line = line.replace('bne', "bne r7 ")
line = line.replace('beq', "beq r7 ")
(op,in1,in2) = line.lower().replace(',',' ').split()
# print(op,in1,in2)
bin_op = op_dict[op]
bin_in1 = int(in1[1:])
bin_in2 = int(in2[1:])
if '#' in in2: bin_in2 += 0x0800 #1<<11: [11]表示立即数
code = (bin_op<<12) + (bin_in1<<8) + (bin_in2)
print("%d: op = 'h%04x" % (i,code))
except:
print("@@@line %d: error(s) occured."%i)
从命令行运行时传入xxx.asm即可,否则会报错,提示usage: python assembler xxx.asm。
主要代码就下面这10行:
line = line.split('//')[0]
line = line.replace('bne', "bne r7 ")
line = line.replace('beq', "beq r7 ")
(op,in1,in2) = line.lower().replace(',',' ').split()
这4行对指令做预处理,去掉注释并按空格逗号分隔成3段。这里bne/beq只有两段,稍做转换,这样所有指令可以对齐,方便使用相同的规则来处理。
bin_op = op_dict[op]
bin_in1 = int(in1[1:])
bin_in2 = int(in2[1:])
if '#' in in2: bin_in2 += 0x0800 #1<<11: [11]表示立即数
这4行是指令转码。按op分段解码,转换成二进制码。
code = (bin_op<<12) + (bin_in1<<8) + (bin_in2)
print("%d: op = 'h%04x" % (i,code))
这2行是将3个分段的二进制加起来,形成一条机器码。这里打印出来,然后复制到FPGA环境,就可以编译下载并运行新程序了。
把一节的程序拿过来试试:
ldr r0,#0
ldr r1,#1
add r0,r1
add r1,#1
cmp r1,#11
bne #2
mov r7,r7 //while(1);
输出
processing r:/code.asm
0: op = 'h0800
1: op = 'h0901
2: op = 'h1001
3: op = 'h1901
4: op = 'h590b
5: op = 'h7f02
6: op = 'h0707
可以用了。
标签:bin,自己,in2,in1,动手,line,CPU,bne,op From: https://blog.csdn.net/weixin_46766770/article/details/145084309