计算机组成原理课内实验报告一Word文档下载推荐.docx

上传人:b****4 文档编号:17950239 上传时间:2022-12-12 格式:DOCX 页数:12 大小:111.46KB
下载 相关 举报
计算机组成原理课内实验报告一Word文档下载推荐.docx_第1页
第1页 / 共12页
计算机组成原理课内实验报告一Word文档下载推荐.docx_第2页
第2页 / 共12页
计算机组成原理课内实验报告一Word文档下载推荐.docx_第3页
第3页 / 共12页
计算机组成原理课内实验报告一Word文档下载推荐.docx_第4页
第4页 / 共12页
计算机组成原理课内实验报告一Word文档下载推荐.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

计算机组成原理课内实验报告一Word文档下载推荐.docx

《计算机组成原理课内实验报告一Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《计算机组成原理课内实验报告一Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。

计算机组成原理课内实验报告一Word文档下载推荐.docx

汇编代码给出的方式是,每一句源程序语句后紧随相应的汇编代码。

第一列的数字表示的是当前汇编指令在内存中的地址,第二列表示的是当前汇编指令的机器码,第三列对应于当前汇编指令。

可以看出,每一句高级语言的实现,都可以分解成一句或多句汇编指令来执行,从汇编指令中我们可以看到寄存器、内存单元的变化,整个过程更透明。

五、实验步骤

●在VisualStudio下建立工程文件

⏹选择Win32ConsoleApplication;

输入工程名称;

⏹选择建立空工程;

⏹添加新源文件

●编写简单的C语言程序;

⏹设置断点;

⏹调试,打开汇编以及与其对应的机器代码;

✓按F5进入Debug模式;

✓按Alt+8进入汇编查看模式;

✓右键选中CodeBytes,查看查看机器代码;

●学习、查看C语言源代码、汇编代码及其相对应的机器代码;

六、设计思路与源代码

三个问题要求的程序都比较简单,不做过多解释。

基本的思路就是首先设计并写出源程序,然后经过设断点,调试,反汇编等步骤获取他相应的汇编程序代码。

并对汇编代码进行分析,同时对程序的执行结果做出判断和评价。

●问题一源代码:

●问题二源代码:

●问题三源代码:

七、实验结果以及相关分析

●问题一:

程序的汇编代码如下所示,各条语句后的解释是对汇编代码的逐条分析:

#include<

stdio.h>

intmax(inta,intb)

{;

以下过程为进入max函数前的准备工作。

000D13D0pushebp

把原来ebp的值压入堆栈保护起来。

000D13D1movebp,esp

把栈顶的值放在ebp中保存,此后ebp一般不变,此时ebp就是“当前函数堆栈”的基址,以便访问堆栈中的信息以及从当前函数栈顶返回到栈底。

000D13D3subesp,0C0h

保留变量空间长度。

把esp往下移动一个范围,等于划出一片空间用来存局部变量。

000D13D9pushebx

000D13DApushesi

000D13DBpushedi

把寄存器中原来的值压入堆栈保护起来。

000D13DCleaedi,[ebp-0C0h]

本来是要movedi,ebp-0c0h,但是mov不支持该操作;

所以对ebp-0c0h取内容,而lea把内容的地址,也就是ebp-0c0h加载到edi中。

目的是把保存局部变量的区域(从ebp-0c0h开始的区域)初始化成全;

部0cccccccch。

000D13E2movecx,30h

000D13E7moveax,0CCCCCCCCh

000D13ECrepstosdwordptres:

[edi]

初始化用于该函数的栈空间为0XCCCCCCCCh即从堆栈里所有的值均为0xCCCCCCCC。

if(a>

b)

000D13EEmoveax,dwordptr[a]

把a的值扩展成双字放入eax寄存器。

000D13F1cmpeax,dwordptr[b]

把eax寄存器中的值即a与b比较。

000D13F4jlemax+2Dh(0D13FDh)

如果a比b大则跳到地址为0D13FDh的语句。

returna;

000D13F6moveax,dwordptr[a]

把a的值扩展成双字大小存入eax寄存器。

000D13F9jmpmax+30h(0D1400h)

跳到地址为0D1400h的语句结束执行。

else

000D13FBjmpmax+30h(0D1400h)

returnb;

000D13FDmoveax,dwordptr[b]

把b的值扩展为双字大小存入eax寄存器。

}

000D1400popedi

000D1401popesi

000D1402popebx

000D1403movesp,ebp

000D1405popebp

000D1406ret

以上部分将压入堆栈保存起来的值重新弹出恢复程序执行前的状态。

voidmain()

{

000D1420pushebp

000D1421movebp,esp

000D1423subesp,0C0h

000D1429pushebx

000D142Apushesi

000D142Bpushedi

000D142Cleaedi,[ebp-0C0h]

000D1432movecx,30h

000D1437moveax,0CCCCCCCCh

000D143Crepstosdwordptres:

进入函数调用前的准备工作,同上,不做重复解释。

max(10,20);

000D143Epush14h;

将操作数20压入堆栈

000D1440push0Ah;

将操作数10压入堆栈

000D1442callmax(0D1118h);

调用max函数

000D1447addesp,8;

并将堆栈指针上移8

000D144Axoreax,eax

000D144Cpopedi

000D144Dpopesi

000D144Epopebx

000D144Faddesp,0C0h

000D1455cmpebp,esp

000D1457call__RTC_CheckEsp(0D113Bh)

000D145Cmovesp,ebp

000D145Epopebp

000D145Fret

以上部分将压入堆栈保存起来的值重新弹出恢复程序执行前的状态,并且返回值。

●问题二:

0040102055pushebp

004010218BECmovebp,esp

0040102383EC40subesp,40h

0040102653pushebx

0040102756pushesi

0040102857pushedi

004010298D7DC0leaedi,[ebp-40h]

0040102CB910000000movecx,10h

00401031B8CCCCCCCCmoveax,0CCCCCCCCh

00401036F3ABrepstosdwordptr[edi]

函数调用前的准备工作,同问题一,不做重复解释。

printf("

HelloWorld!

"

);

00401038686C2F4200pushoffsetstring"

(00422f6c)

将”HelloWorld”字符串的偏移地址压入堆栈,且其地址为00422f6c。

0040103DE87EC60000callprintf(0040d6c0)

调用printf函数。

0040104283C404addesp,4

恢复了调用printf前的堆栈状态。

004010455Fpopedi

004010465Epopesi

004010475Bpopebx

0040104883C440addesp,40h

0040104B3BECcmpebp,esp

0040104DE85E000000call__chkesp(004010b0)

004010528BE5movesp,ebp

004010545Dpopebp

00401055C3ret

●问题三:

执行结果如图所示:

该程序的汇编代码如下所示,各条语句后的解释是对汇编代码的逐条分析:

main()

0040101055pushebp

004010118BECmovebp,esp

0040101383EC48subesp,48h

0040101653pushebx

0040101756pushesi

0040101857pushedi

004010198D7DB8leaedi,[ebp-48h]

0040101CB912000000movecx,12h

00401021B8CCCCCCCCmoveax,0CCCCCCCCh

00401026F3ABrepstosdwordptr[edi]

进入函数调用前的准备工作,同问题一,不做重复解释。

inta;

floatb;

a*=a/=(a=7)-(b=4.5);

00401028DB45FCfilddwordptr[ebp-4]

将[ebp-4]单元的整数值压栈,即st(0)。

0040102BC745FC07000000movdwordptr[ebp-4],7

将整数7赋值到[ebp-4]单元。

00401032DB45FCfilddwordptr[ebp-4]

将[ebp-4]单元的整数值压入栈,即st

(1)。

00401035C745F800009040movdwordptr[ebp-8],40900000h

将浮点数4.5赋值到[ebp-8]单元(由于是浮点数,该数是32位形式)

0040103CD865F8fsubdwordptr[ebp-8]

st(0)-[ebp-8]差值,结果放在st(0)。

0040103FDEF9fdivpst

(1),st

st(0)/st(i),并把结果放在st(i),并执行一次出栈操作。

00401041E8C2010000call__ftol(00401208)

浮点转换整数指令,入口参数通过st传入,出口结果在eax,且弹出st

004010468945FCmovdwordptr[ebp-4],eax

004010498B45FCmoveax,dwordptr[ebp-4]

0040104C0FAF45FCimuleax,dwordptr[ebp-4]

a=a*a结果放到eax

004010508945FCmovdwordptr[ebp-4],eax

将结果存入内存单元。

a=%d,b=%f\n"

a,b);

00401053D945F8flddwordptr[ebp-8]

将[ebp-8]单元的值即b入栈

0040105683EC08subesp,8

将栈顶指针向下移动8,栈顶下移到b。

00401059DD1C24fstpqwordptr[esp]

将堆栈栈顶的数据传送到目标操作数中,并弹出栈顶

0040105C8B4DFCmovecx,dwordptr[ebp-4]

0040105F51pushecx

ecx中存储a

00401060681C604200pushoffsetstring"

(0042601c);

打印的参数设定压入堆栈

00401065E836000000callprintf(004010a0)

调用printf函数

0040106A83C410addesp,10h

0040106D5Fpopedi

0040106E5Epopesi

0040106F5Bpopebx

0040107083C448addesp,48h

004010733BECcmpebp,esp

00401075E856010000call__chkesp(004011d0)

0040107A8BE5movesp,ebp

0040107C5Dpopebp

0040107DC3ret

问题分析以及解决:

预期的结果是a=7.84,b=4.5。

在程序初始化时,eax被初始化为0CCCCCCCCh,转化为补码是-343597384,所以计算发生错误,与预期不相符合。

处理方法可以直接用汇编语言重写,也可以在C语言代码中,给a,b预定义的时候对其赋值并分配内存空间。

八、实验小结

由于硬件等许多因素,程序并非完全如预期执行。

硬件软件等许多因素都相互影响相互制约。

通过查看汇编代码,能对底层有一个更清晰的认识。

另外实验过程中接触了不少自己并不是很了解的知识,通过各种途径的查询和询问,解决了问题。

我们很难对各种知识都有一个全面而深刻的理解,然而具备解决问题的能力是很重要的一个方面。

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

当前位置:首页 > 人文社科 > 文化宗教

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

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