计算机结构与组成cpu仿真.docx

上传人:b****3 文档编号:5483027 上传时间:2022-12-17 格式:DOCX 页数:18 大小:18.45KB
下载 相关 举报
计算机结构与组成cpu仿真.docx_第1页
第1页 / 共18页
计算机结构与组成cpu仿真.docx_第2页
第2页 / 共18页
计算机结构与组成cpu仿真.docx_第3页
第3页 / 共18页
计算机结构与组成cpu仿真.docx_第4页
第4页 / 共18页
计算机结构与组成cpu仿真.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

计算机结构与组成cpu仿真.docx

《计算机结构与组成cpu仿真.docx》由会员分享,可在线阅读,更多相关《计算机结构与组成cpu仿真.docx(18页珍藏版)》请在冰豆网上搜索。

计算机结构与组成cpu仿真.docx

计算机结构与组成cpu仿真

Project1

一.问题描述:

这个工程需要编写MIPS汇编语言一个子集的指令解释器.它将实现取指、反汇编,解码,并执行MIPS机器指令。

也就是构建一个缩微的MARS。

二.问题分析:

老师已经给出了一个工程,要求我们在所给文件中添加相应的代码,使sample.dump中的机器码(也就是一串数字)可以实现反汇编,在控制台黑屏中输出汇编指令和寄存器及内存的更新情况。

而且.cpp文件中提供了两个函数disassembled和simulateInstr来分别实现上述功能。

反汇编说明:

在disassembled函数中,我要将数字指令转化为汇编语言,这首先需要对一段数字进行分割,如先取32位数字的前6位为其opcode段等,数字分割是通过左移和右移实现的,具体代码如下:

intopcode,func,rs,rt,rd,shamt,targaddress,immediate;

opcode=instr>>26;

rs=(instr<<6)>>27;

rt=(instr<<11)>>27;

rd=(instr<<16)>>27;

shamt=(instr<<21)>>27;

func=(instr<<26)>>26;

immediate=(instr<<16)>>16;

targaddress=(instr<<6)>>6;

完成数字分割后,就进入具体的指令分析阶段,此步通过if-else语句实现。

如先解析R格式语句,先选出opcode为0的32为指令数字段,再针对具体的func的值为其对上不同的汇编指令,例如opcode=0,func=33表示addu指令:

if(opcode==0)

{

if(func==33)//addu

{

strcat_s(result1,"addu$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

}

运用strcat函数实现字符串的拼接,itoa_s函数将二进制数变为其他进制数输出,结果便可在黑频上输出如下类似指令:

addu$0,$2,$2

将所有情况的不同opcode和func的值用if-else语句像上面这样表示出来,于是就可以将所有的32位指令数字段解码成汇编代码,但此时的代码只是个空壳而已,需要用下面的simulateInstr函数将不同的指令的pc改变,计算,寄存器和内存的更新表示出来。

在simulateInstr函数中同样也需要对每个32位指令数字段进行划分然后依据不同的opcode和func设置pc,进行计算以及表示寄存器和内存是否被更新。

在这里,寄存器及内存的是否更新使用数字表示,-1代表没有更新,例如addu:

if(opcode==0)

{

if(func==33)//addu

{

mips->pc=mips->pc+4;

mips->registers[rd]=mips->registers[rt]+mips->registers[rs];

if(rd==0)

rd=-1;

*changedReg=rd;

*changedMem=-1;

}

其中pc会顺序加4,内存没有改变,但addu所加的结果被存在rd寄存器中,所以rd寄存器会更新。

将所有指令的实质改变按此方法用if-else语句表示出来后,该工程也就完成了。

三.所遇问题及改进方案:

(1)在编程过程中,我开始不知道该怎么样实现数据的符号扩展,因为我对32位数据采用的是左移右移方法来实现指令分割的,这就相对于对所有字段都进行的是零扩展,这对于addi,lw,sw指令中需要进行符号扩展的立即数来说显然矛盾。

后来,在请教同学的基础上,我改进了方法,对于那些只需做零扩展的立即数,不需要做什么改变。

对与addi这类需做符号扩展的立即数,我在相应的if语句中对立即数进行判断,如果立即数小于32768(也就是2的15次方),也就是该立即数的第一位数是0,那么零扩展与符号扩展对该立即数的真实值无影响,也就不需改变什么;反之,则该立即数的第一位数是1,那么必须进行符号扩展,即将该立即数减去65536(2的16次方)即可。

例如sw:

if(opcode==43)//sw

{

strcat_s(result1,"sw$");

strcat_s(result,result1);

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",");

if(immediate<32768)

_itoa_s(immediate,temp,10);

else

_itoa_s(immediate-65536,temp,10);

strcat_s(result,temp);

strcat_s(result,"($");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,")");

}

(2)在simulateInstr函数中对于sw与lw指令,需要对内存中的值进行读取,开始时我只用rs中的地址和立即数相加得到要读或取的内存地址,但这样得不到正确的结果,在同学的提醒下我注意到该程序设计的内存首地址为0x00400000,于是将上面的数减去0x00400000即可得正确结果。

四.以下为源程序代码:

charresult[100]={0};

charresult1[100]={0};

chartemp[100]={0};

char*disassembled(unsignedintinstr,unsignedintpc){

memset(result,0,100);

memset(result1,0,100);

memset(temp,0,100);

intopcode,func,rs,rt,rd,shamt,targaddress,immediate;

opcode=instr>>26;

rs=(instr<<6)>>27;

rt=(instr<<11)>>27;

rd=(instr<<16)>>27;

shamt=(instr<<21)>>27;

func=(instr<<26)>>26;

immediate=(instr<<16)>>16;

targaddress=(instr<<6)>>6;

if(opcode==0)

{

if(func==35)//subu

{

strcat_s(result1,"subu$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

}

if(func==33)//addu

{

strcat_s(result1,"addu$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

}

 

if(func==36)//and

{

strcat_s(result1,"and$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

}

 

if(func==37)//or

{

strcat_s(result1,"or$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

}

 

if(func==42)//slt

{

strcat_s(result1,"slt$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

}

 

if(func==0)//sll

{

strcat_s(result1,"sll$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",");

_itoa_s(shamt,temp,10);

strcat_s(result,temp);

}

if(func==2)//srl

{

strcat_s(result1,"srl$");

strcat_s(result,result1);

_itoa_s(rd,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",");

_itoa_s(shamt,temp,10);

strcat_s(result,temp);

}

if(func==8)//jr

{

strcat_s(result1,"jr$");

strcat_s(result,result1);

_itoa_s(rs,temp,10);

strcat_s(result,temp);

}

}

if(opcode==9)//addiu

{

strcat_s(result1,"addiu$");

strcat_s(result,result1);

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",");

if(immediate<32768)

_itoa_s(immediate,temp,10);

else

_itoa_s(immediate-65536,temp,10);

strcat_s(result,temp);

}

if(opcode==12)//andi

{

strcat_s(result1,"andi$");

strcat_s(result,result1);

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",0x");

_itoa_s(immediate,temp,16);

strcat_s(result,temp);

}

if(opcode==13)//ori

{

strcat_s(result1,"ori$");

strcat_s(result,result1);

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",0x");

_itoa_s(immediate,temp,16);

strcat_s(result,temp);

}

if(opcode==15)//lui

{

strcat_s(result1,"lui$");

strcat_s(result,result1);

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",0x");

_itoa_s(immediate,temp,16);

strcat_s(result,temp);

}

 

if(opcode==4)//beq

{

strcat_s(result1,"beq$");

strcat_s(result,result1);

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",0x");

if(immediate>=32768)

immediate-=65536;

pc=pc+4+immediate*4;

_itoa_s(pc,temp,16);

strcat_s(result,temp);

}

 

if(opcode==5)//bne

{

strcat_s(result1,"bne$");

strcat_s(result,result1);

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,",$");

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",0x");

if(immediate>=32768)

immediate-=65536;

pc=pc+4+immediate*4;

_itoa_s(pc,temp,16);

strcat_s(result,temp);

}

if(opcode==35)//lw

{

strcat_s(result1,"lw$");

strcat_s(result,result1);

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",");

if(immediate<32768)

_itoa_s(immediate,temp,10);

else

_itoa_s(immediate-65536,temp,10);

strcat_s(result,temp);

strcat_s(result,"($");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,")");

}

if(opcode==43)//sw

{

strcat_s(result1,"sw$");

strcat_s(result,result1);

_itoa_s(rt,temp,10);

strcat_s(result,temp);

strcat_s(result,",");

if(immediate<32768)

_itoa_s(immediate,temp,10);

else

_itoa_s(immediate-65536,temp,10);

strcat_s(result,temp);

strcat_s(result,"($");

_itoa_s(rs,temp,10);

strcat_s(result,temp);

strcat_s(result,")");

}

if(opcode==2)//j

{

pc=(((pc+4)>>28)<<28)+((targaddress<<6)>>4);

strcat_s(result1,"j0x");

strcat_s(result,result1);

_itoa_s(pc,temp,16);

strcat_s(result,temp);

}

if(opcode==3)//jal

{

pc=(((pc+4)>>28)<<28)+((targaddress<<6)>>4);

strcat_s(result1,"jal0x");

strcat_s(result,result1);

_itoa_s(pc,temp,16);

strcat_s(result,temp);

}

returnresult;

voidsimulateInstr(Computermips,unsignedintinstr,int*changedReg,int*changedMem)

{

/*Youreplacethiscodebytherightstuff.*/

intopcode,func,rs,rt,rd,shamt,targaddress,immediate;

opcode=instr>>26;

rs=(instr<<6)>>27;

rt=(instr<<11)>>27;

rd=(instr<<16)>>27;

shamt=(instr<<21)>>27;

func=(instr<<26)>>26;

immediate=(instr<<16)>>16;

targaddress=(instr<<6)>>6;

if(opcode==0)

{

if(func==33)//addu

{

mips->pc=mips->pc+4;

mips->registers[rd]=mips->registers[rt]+mips->registers[rs];

if(rd==0)

rd=-1;

*changedReg=rd;

*changedMem=-1;

}

if(func==35)//subu

{

mips->pc=mips->pc+4;

mips->registers[rd]=mips->registers[rs]+mips->registers[rt];

if(rd==0)

rd=-1;

*changedReg=rd;

*changedMem=-1;

}

if(func==36)//and

{

mips->pc=mips->pc+4;

mips->registers[rd]=mips->registers[rs]&mips->registers[rt];

if(rd==0)

rd=-1;

*changedReg=rd;

*changedMem=-1;

}

if(func==37)//or

{

mips->pc=mips->pc+4;

mips->registers[rd]=mips->registers[rs]|mips->registers[rt];

if(rd==0)

rd=-1;

*changedReg=rd;

*changedMem=-1;

}

 

if(func==42)//slt

{

mips->pc=mips->pc+4;

if(mips->registers[rs]registers[rt])

mips->registers[rd]=1;

else

mips->registers[rd]=0;

if(rd==0)

rd=-1;

*changedReg=rd;

*changedMem=-1;

}

if(func==0)/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1