MIPS体系结构的asm转换成为bin:Matlab实现
0赞MIPS体系结构的asm转换成为bin:Matlab实现(使用文档)
——两忘而化其道(fei199311)
编写此程序的初衷在于,需要对自己设计的MIPS体系的软核处理器进行测试,但是因为实现的指令只是原有指令集的一个子集,所以无法使用现有的交叉编译环境,只能编写一个简单的ASM转BIN的程序,减少一些测试指令产生的工作量。
首先声明,此程序无法完全兼容MIPS体系结构的汇编语言,所以写出的汇编需要严格遵守下面叙述的各种要求,否则将会转换失败;若想完全兼容,请自行修改代码。
Matlab程序所实现的功能是:将MIPS汇编语言源程序文件(mips_asm2bin.mips)转换成十六进制格式文件(mips.bin)。
MIPS汇编语言源程序必须满足以下要求:
1.汇编语言从源程序文件第一行开始;
2.每一条汇编以英文分号“;”结尾;
3.整个程序写完后,在最后一条汇编语言的下一行输入英文字符“end”表示结束;
4.本程序只完成了20条汇编指令(详见附录1)的汇编功能;
5.操作数必须使用10进制格式,并且有标准的长度,长度不足时在前面补“0”,标准如下:
操作数类型 |
操作数标准长度(十进制) |
寄存器(r0~r31) |
2 |
立即数imm |
5 |
偏移地址offset |
5 |
J型指令地址 |
8 |
6.要转换的汇编语言源文件必须严格命名为:mips_asm2bin.mips。
附录1:
本程序完成的指令类型和输入规则:
指令格式 |
指令含义 |
add/sub/and/or/xor rd rs rt; |
rd <= rs op rt |
sll/srl/sra rd rt sa; |
rd <= rt shift sa |
lui rt imm; |
rt <= imm << 16 |
addi rt rs imm; |
rt <= rs + imm(符号扩展) |
andi/ori/xori rt rs imm; |
rt <= rs op imm |
lw rt rs offset; |
rt <= memory[rs + offset] |
sw rt rs offset; |
memory[rs + offset] <= rt |
beq rs rt offset; |
if(rs == rt) PC<=PC+4+offset<<2; |
bne rs rt offset |
if(rs != rt) PC<=PC+4+offset<<2; |
j addr; |
PC<={PC[31:28],addr,2’b0} |
jal addr; |
PC<={PC[31:28],addr,2’b0} r31<=PC+8 |
jr rs; |
PC<=rs |
注:“<=”表示赋值;“op”表示相应操作;“shift”表示移位操作。
附录2:转换例子:
mips_asm2bin.mips
lui 01 00000;
ori 04 01 00080;
addi 05 00 00004;
jal 00000024;
sw 02 04 00000;
lw 09 04 00000;
sub 08 09 04;
addi 05 00 00003;
addi 05 05 65535;
ori 08 05 65535;
xori 08 08 21845;
addi 09 00 65535;
andi 10 09 65535;
or 06 10 09;
xor 08 10 09;
and 07 10 06;
beq 05 00 00001;
j 00000008;
addi 05 00 65535;
sll 08 05 15;
sll 08 08 16;
sra 08 08 16;
srl 08 08 15;
j 00000007;
addi 04 04 00004;
add 08 08 09;
addi 05 05 65535;
bne 05 00 65531;
sll 02 08 00;
jr 31;
end
转换之后:
mips.bin
3C010000
34240050
20050004
0C000018
AC820000
8C890000
01244022
20050003
20A5FFFF
34A8FFFF
39085555
2009FFFF
312AFFFF
01493025
01494026
01463824
10A00001
08000008
2005FFFF
000543C0
00084400
00084403
000843C2
08000007
20840004
01094020
20A5FFFF
14A0FFFB
00081000
03E00008
附录3:程序源代码
1.str2mips_func_bin.m
function[op, func] = str2mpis_func_bin(str)
ifstrcmp(str,'add')% R type
op = 0;
func = 32;
elseifstrcmp(str,'sub')
op = 0;
func = 34;
elseifstrcmp(str,'and')
op = 0;
func = 36;
elseifstrcmp(str,'or')
op = 0;
func = 37;
elseifstrcmp(str,'xor')
op = 0;
func = 38;
elseifstrcmp(str,'sll')
op = 0;
func = 0;
elseifstrcmp(str,'srl')
op = 0;
func = 2;
elseifstrcmp(str,'sra')
op = 0;
func = 3;
elseifstrcmp(str,'jr')
op = 0;
func = 8;
elseifstrcmp(str,'addi')% I type
op = 8;
func = 0;
elseifstrcmp(str,'andi')
op = 12;
func = 0;
elseifstrcmp(str,'ori')
op = 13;
func = 0;
elseifstrcmp(str,'xori')
op = 14;
func = 0;
elseifstrcmp(str,'lw')
op = 35;
func = 0;
elseifstrcmp(str,'sw')
op = 43;
func = 0;
elseifstrcmp(str,'beq')
op = 4;
func = 0;
elseifstrcmp(str,'bne')
op = 5;
func = 0;
elseifstrcmp(str,'lui')
op = 15;
func = 0;
elseifstrcmp(str,'j')% J type
op = 2;
func = 0;
elseifstrcmp(str,'jal')
op = 3;
func = 0;
end
end
2.MIPS_asm2bin.m
% mips体系结构cpu
% mips汇编语言(mips_asm2bin.mips)转换成为二进制(mips.bin)
str = fileread('mips_asm2bin.mips');
str_length = length(str);%字符个数num
s = fopen('mips.bin','wb');% opens the output file
char_num = 1;%记录汇编语言的语句数
ifstrcmp(str(str_length-2:str_length),'end')
display('good!');
fori = 1:str_length
ifstrcmp(str(i),';')
asm_num = i;
asm_length = asm_num - char_num;
asm_str = str(char_num:asm_num);
forj = 1:asm_length% opcode & function
asm_str(j);
ifstrcmp(asm_str(j),' ')
temp = j+1;
[op,func] = str2mips_func_bin(asm_str(1:j-1));
break;
end
end
ifop == 0% R type
if(func == 0) || (func == 2) || (func == 3)% sll srl sra
rd = str2num(asm_str(temp:temp + 1));
rt = str2num(asm_str(temp + 3:temp + 4));
sa = str2num(asm_str(temp + 6:temp + 7));
bin_code = op*2^26 + rt*2^16 + rd*2^11 + sa*2^6 + func;
dec2hex(bin_code)
elseiffunc == 8
rs = str2num(asm_str(temp:temp + 1));
bin_code = op*2^26 + rs*2^21 + func;
dec2hex(bin_code)
else
rd = str2num(asm_str(temp:temp + 1));
rs = str2num(asm_str(temp + 3:temp + 4));
rt = str2num(asm_str(temp + 6:temp + 7));
sa = 0;
bin_code = op*2^26 + rs*2^21 + rt*2^16 + rd*2^11 + sa*2^6 + func;
dec2hex(bin_code)
end
elseifop == 2 || op == 3% J type
addr = str2num(asm_str(temp:temp + 7));
bin_code = op*2^26 + addr;
dec2hex(bin_code)
else% I type
ifop == 15% lui
rt = str2num(asm_str(temp:temp + 1));
imm = str2num(asm_str(temp + 3:temp + 7));
bin_code = op*2^26 + rt*2^16 + imm;
dec2hex(bin_code)
elseifop == 4 || op == 5% beq bne
rs = str2num(asm_str(temp:temp + 1));
rt = str2num(asm_str(temp + 3:temp + 4));
imm = str2num(asm_str(temp + 6:temp + 10));
bin_code = op*2^26 + rs*2^21 + rt*2^16 + imm;
dec2hex(bin_code)
else
rt = str2num(asm_str(temp:temp + 1));
rs = str2num(asm_str(temp + 3:temp + 4));
imm = str2num(asm_str(temp + 6:temp + 10));
bin_code = op*2^26 + rs*2^21 + rt*2^16 + imm;
dec2hex(bin_code)
end
end
% file output
iflength(dec2hex(bin_code)) == 8
output_bin = dec2hex(bin_code);
elseiflength(dec2hex(bin_code)) == 7
output_bin = strcat('0', dec2hex(bin_code));
elseiflength(dec2hex(bin_code)) == 6
output_bin = strcat('00', dec2hex(bin_code));
elseiflength(dec2hex(bin_code)) == 5
output_bin = strcat('000', dec2hex(bin_code));
elseiflength(dec2hex(bin_code)) == 4
output_bin = strcat('0000', dec2hex(bin_code));
elseiflength(dec2hex(bin_code)) == 3
output_bin = strcat('00000', dec2hex(bin_code));
elseiflength(dec2hex(bin_code)) == 2
output_bin = strcat('000000', dec2hex(bin_code));
else
output_bin = strcat('0000000', dec2hex(bin_code));
end
fprintf(s,'%c',output_bin);
fprintf(s,'\n');
char_num = i+3;
end
end
else
display('请加入结束符:end');
end
fclose(s);
参考文献:
李亚民.计算机原理与设计——Verilog HDL版.北京:清华大学出版社. 2011.