微原软件实验.docx

上传人:b****5 文档编号:11783430 上传时间:2023-04-01 格式:DOCX 页数:40 大小:503.55KB
下载 相关 举报
微原软件实验.docx_第1页
第1页 / 共40页
微原软件实验.docx_第2页
第2页 / 共40页
微原软件实验.docx_第3页
第3页 / 共40页
微原软件实验.docx_第4页
第4页 / 共40页
微原软件实验.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

微原软件实验.docx

《微原软件实验.docx》由会员分享,可在线阅读,更多相关《微原软件实验.docx(40页珍藏版)》请在冰豆网上搜索。

微原软件实验.docx

微原软件实验

微机原理软件实验报告

实验一:

DEBUG的使用

一、实验目的:

1、掌握汇编程序的编辑,编译,连接和执行的全过程;

2、学习和掌握用DEBUG调试程序的方法。

二、实验过程:

(本部分包括实验任务和内容,程序流程,源程序,运行结果等)

1、用编辑软件,输入以下汇编语言源程序:

DATSEGMENT

ADB20;(自定)

BDB15;(自定)

YDB3DUP(0)

ZDB0,0

DATENDS

STASEGMENTSTACK

DW50DUP(?

STAENDS

CODSEGMENT

ASSUMECS:

COD,DS:

DAT

STARPROCFAR

PUSHDS

XORAX,AX

PUSHAX

MOVAX,DAT

MOVDS,AX

MOVAX,STA

MOVSS,AX

MOVAL,A

MOVZ,AL

MOVZ+1,AL

CALLSUB1

MOVAL,B

MOVZ,AL

MOVZ+1,AL

CALLSUB1

MOVAL,A

MOVZ,AL

MOVAL,B

MOVZ+1,AL

CALLSUB1

ADDWORDPTRY,AX

ADCBYTEPTR[Y+2],0

RET

STARENDP

SUB1PROC

MOVAL,Z

MOVAH,Z+1

MULAH

ADDWORDPTRY,AX

ADCBYTEPTR[Y+2],0

RET

SUB1ENDP

CODENDS

ENDSTAR

用windows自带的记事本就行。

输入之后保存为扩展名为asm的文件即可。

2、通过编译,连接形成可执行文件。

3、用DEBUG将可执行文件调入,并进行调试。

用D命令观察数据区在内存中的具体内容,记录单元A和B的具体地址。

A的地址是1414:

0000,B的地址是1414:

0001。

(2)用U命令对目标代码反汇编,观察反汇编后的结果。

注意发现源程序的起始位置,并记录这个起始地址。

源程序的起始位置是141C:

0000。

(3)用T命令作单步跟踪调试比较每条指令执行后的结果和原来的理解是否一致得出程序运行的结果:

它们是写在什么单元,具体内容是什么;并判断结果是否正确。

逐步执行,得到最后结果,符合预期结果

(4)在子程序SUB1的入口处设一断点,用G命令执行程序。

在断点处观察堆栈的内容,比较堆栈的内容和程序返回地址是否一致。

可见sub1的入口地址是141C:

0017。

下一条指令的偏移地址是001A。

(5)用E命令修改单元A,B的内容,重新执行程序,并记录结果.

这里把A的值为0AH,把B的值改为了09H

修改后为:

(6)用M命令和A命令对程序进行修改:

将主程序中最后两条指令(ADD和

ADC)修改为一条CALLSUB1指令,重新执行程序。

首先找到那两条,然后修改

修改后:

再全速运行g即可。

(7)退出DEBUG.

用Q命令即可。

4.重新使用编辑软件,把源程序最后一句中的STAR去掉。

再次生成可执行文件,并用DEBUG调入内存当使用U命令时,显示的结果与前一次(未用STAR)的结果有何不同?

程序找不到入口地址,接着上次U的结果继续运行。

三、回答预习题:

1、熟悉常用的DEBUG命令。

其中常用debug命令:

u地址反汇编

dxx:

偏移地址xx:

csdssses查看内存单元的内容

t=开始地址[结束地址]跟踪执行

p跳过子程序单步运行

g=开始地址[断点地址]执行到断点处

g全速运行

r查看寄存器内容

rxxxx:

寄存器名称,修改寄存器内容

exx:

偏移地址xx:

csdssses修改内存单元的内容

a偏移地址汇编,录入程序或可修改语句

mxx:

块的开始地址块的结束地址xx:

新的块开始地址

其中xx:

csdssses块搬移又相当于复制命令

q退出debug

命令行方式全屏回到窗口方式用Atl+Enter键

2、阅读并分析程序的功能。

这个程序实现的功能是计算Y=

,并将结果放入Y和Y+1两字节中,而进位信息放入Y+2中。

如:

A=20,B=15,则Y=

=1125=04C9H,这样内存中的内容为Y:

C9,Y+1:

04,Y+2:

00

3、若SS=2000H,SP=FFFFH,向堆栈中压入4字节数据后,如何用D命令显示压入堆栈的内容?

用D2000:

FFFC来查看堆栈的内容。

四、实验总结和心得体会

这是第一次实验,对后面的程序有很大的影响。

1、汇编程序的编辑,编译,连接和执行的全过程,对这种语言有了很大的理解;

2、加深了对书本上知识的理解与掌握,对8086CPU有了更加深刻的认识,学会了一件事情,那就是知识只有去应用才是最能掌握,这是最重要的。

3、学会用DEBUG了,知道了DEBUG的重要性,会用反汇编来理解程序的执行过程,以及这时CPU内部寄存器的状态变化,汇编语言与机器语言的对应关系,会对自己的程序查错,检错,改错了,这是很重要的,以后的程序就可以自食其力了。

实验二:

分支,循环程序设计

一、实验目的:

1、开始独立进行汇编语言程序设计。

2、掌握基本分支,循环程序设计。

3、掌握最简单的DOS功能调用。

二、实验任务及内容:

1、安排一个数据区,内存有若干个正数,负数和零.每类数的个数都不超过9。

2、编写一个程序统计数据区中正数,负数和零的个数。

3、将统计结果在屏幕上显示。

4、选作统计出正奇数,正偶数,负奇数,负偶数以及零的个数。

三、画出程序流程图:

四、源程序(带注释):

;数据段的定义

datasegment

numdb-1,-2,-3,-4,0,1,2,3,4,5,0,6,7,8,0,9,0,-5;定义源数组各个元素

countequ$-num;源数组所占的字节数

msg1db'Positivenumis:

',0ah,0dh

n_positivedb'0';正数的个数

msg11db0ah,'Evenpositivenumis:

',0ah,0dh

ne_positivedb'0';正偶数的个数

msg12db0ah,'Oddpositivenumis:

',0ah,0dh

no_positivedb'0';正奇数的个数

msg2db0ah,'Negativenumis:

',0ah,0dh

n_negativedb'0';负数的个数

msg21db0ah,'Evennegativenumis:

',0ah,0dh

ne_negativedb'0';负偶数的个数

msg22db0ah,'Oddnegativenumis:

',0ah,0dh

no_negativedb'0';负奇数的个数

msg3db0ah,'Zeronumis:

',0ah,0dh

n_zerodb'0','$';0的个数

dataends

;堆栈段

stacksegmentstack'stack'

db100dup(?

stackends

;代码段

codesegment

assumecs:

code,ds:

data,es:

data,ss:

stack

start:

movax,data

movds,ax;设置段地址

movcx,count;cx中为下面的循环的次数

movdx,0;设定初值,dh为正数的个数,dl为负数的个数

movah,0;ah中为0的个数

leabx,num;数组起始地址赋给bx

again:

cmpbyteptr[bx],0;比较

jgeplus_zero;大于等于0时转plus_zero

incn_negative;统计小于0的个数

testbyteptr[bx],01h;检测最低为是否为1,为1则转移

jnzodd_n

incne_negative

jmpnext

plus_zero:

jzzero;等于0时转zero

incn_positive;统计大于0的个数

testbyteptr[bx],01h;检测最低为是否为1,为1则转移

jnzodd_p

incne_positive

jmpnext

zero:

incn_zero;统计等于0的个数

jmpnext

odd_n:

incno_negative

jmpnext

odd_p:

incno_positive

jmpnext

next:

incbx;地址加1,指向下一个数

loopagain;循环

display:

movdx,offsetmsg1

movah,09h

int21h;由ASCII可知,数字与其对应的ASCII

movah,4ch;返回dos系统

int21h

codeends

endstart

五、程序运行结果:

六、回答预习题:

1、十进制数0--9所对应的ASCII码是什么?

如何将十进制数0--9在屏幕上显示出来?

十进制数字0—9对应的ASCII码为30H—39H;由于在计算机中,显示的字符是用ASCII码来表示的,所以要想把数字显示在屏幕上,就要实现一个数字到ASCII码的转换,这可用数字的ASCII码=(十进制数字+30H)来实现。

2、如何检验一个数为正、为负或为零?

你能举出多少种不同的方法?

方法一、与0比较。

大于0为正,小于0为负,等于0为0。

本实验我用的是这种方法。

方法二、与0异或之后并检查最高位。

首先将数与0异或,结果为0则数为0,否则就检验最高位,为0就是正数,为1就是负数。

七、实验总结和心得体会:

这次的题其实是比较简单的,但也能学到很多的东西,只要自己认真去做,总会有意想不到的收获。

1、算法方面。

将ASCII码与十进制数之间的转换,检验一个数为正负零,判断奇偶等这些都是可以在本实验中看到的。

2、汇编语言方面。

掌握了基本分支语句,循环程序的设计与实现;DOS功能的调用,将结果显示在屏幕上。

3、程序设计方面。

体会到精简程序的重要性与可实现性,刚开始的程序有2K大小,原因在于显示与计数时有很多的冗余,结果后来想到可用宏来精简,最简单的是利用字符串是以’$’做结尾的,将’$’放在数据段的最末即可一次输出,此法妙不可言。

4、技巧方面。

上面也有提到一些,另外还有加注释,编程风格,输出功能等方面。

实验三:

代码转换程序设计

一、实验目的:

1、掌握几种最基本的代码转换方法;

2、运用子程序进行程序设计。

二、实验任务及内容:

1、从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来。

2、两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明。

3、对输入要有检错措施,以防止非法字符输入,并有适当的提示。

4、将整个程序分解为若干模块,分别用子程序实现。

在报告中要给出模块层次图。

 

三、画出程序流程图:

四、源程序(带注释):

;数据段的定义

datasegment

msg1db'Pleaseputinyournums:

',0ah,0dh,'$'

msg2db0ah,'Theminnumberis:

',0ah,0dh,'$'

msg3db0ah,'Error!

!

Pleaseputinagain:

',0ah,0dh,'$'

mindb0;最小数

tendb0;十位

unitdb0;个位

countdb0;数的个数

numdb50dup(0);存放待比较的数

dataends

;堆栈段

stacksegmentstack'stack'

db100dup(?

stackends

;代码段

codesegment

assumecs:

code,ds:

data,es:

data,ss:

stack

start:

movax,data

movds,ax;设置段地址

callputin;输入数字

callfind_min;寻找最小值

calldisplay;显示最小值

exit:

movah,4ch;返回DOS

int21h

putinprocnear;输入函数

movdx,offsetmsg1;显示msg1

movah,09h

int21h

init:

movbx,0;初始化

leasi,num

movcx,0;计数的个数

put:

movah,1

int21h;输入单个字符

jmpcheck;检查是否合法

legal:

incbl;用bl来标志输入了一个数字还是两个

incbh;用bh防止输入3位数

cmpbh,3

jaeerror

testbl,01h;bl=1表明输入的时十位

jnzis_ten

testbl,02h;bl=2是个位

jnzis_unit

is_ten:

subal,30h

movten,al;存入十位

jmpput

is_unit:

subal,30h

movunit,al;存入个位

movdh,10;计算这个两位数

moval,ten

muldh

addal,unit;是ten*10+unit最大为99,直接是在al中

mov[si],al

incsi

inccx

movbl,0

jmpput

check:

;检错子程序

cmpal,20h;是空格吗?

jebe_put;是则合法,继续输入

cmpal,0dh;是回车吗?

jebe_putback;是则返回寻找最小值

cmpal,30h;是数字吗?

jberror

cmpal,39h

jaerror

jmplegal

be_put:

movbh,0

testbl,01h;防止输入一位数

jnzerror

jmpput

error:

movdx,offsetmsg3;显示msg3,可以考虑清屏

movah,09h

int21h

jmpinit;重新初始化

be_putback:

testbl,01h

jnzerror

jmpputback

putback:

movcount,cl

ret

putinendp

find_minprocnear;找最小值函数

leasi,num

moval,[si]

again:

cmpal,[si]

jcnext

moval,[si]

next:

incsi

loopagain

find:

movmin,al

ret

find_minendp

displayprocnear;显示最小值

movdx,offsetmsg2;显示msg2

movah,09h

int21h

moval,min

movbl,01h

mulbl

aam;这样AH中是十位数,AL为个位数

movten,ah

movunit,al

movdl,ten

adddl,30h

movah,02h

int21h;显示十位数

movdl,unit

adddl,30h

movah,02h

int21h;显示个位数

ret

displayendp

codeends

endstart

五、程序运行结果:

六、回答预习题:

1、如何将输入的两个字符(0--9)变为十进制或二进制数?

定义一个内存缓冲区,用于存放十进制数=a*10+b,而其中的a,b为字符的ASCII码减去30H即可。

2、如何将选出的最小值(二进制或十进制)变为ASCII码再进行显示?

首先设十进制数为min,则十位数为min/10,个位数为min%10,这样就得到两个数,最后分别加上30H即可得其ASCII码,显示。

3、你觉得采用二进制运算还是十进制运算更适合于这个实验?

应该是十进制更适合于这个实验。

七、实验总结和心得体会:

1、掌握了几种代码转换的方法,熟悉了运用子程序进行程序设计的程序设计方法。

2、加深了一些常用的算法。

求最小值算法;模块设计的思想;二进制与十进制的转换;十进制与ASCII码的转换等。

3、理论运用于实际的能力有所提高。

在实践中进一步掌握,加深了理解,使我们认识到了理论联系实际的重要性。

实验四:

子程序设计

一、实验目的:

1、进一步掌握子程序设计方法;

2、进一步掌握基本的DOS功能调用.

二、实验任务及内容:

1、从键盘上输入某班学生的某科目成绩.输入按学生的学号由小到大的顺序输入.

2、统计检查每个学生的名次。

3、将统计结果在屏幕上显示。

4、为便于观察,输入学生数目不宜太多,以不超过一屏为宜.输出应便于阅读尽可能考虑美观。

5、输入要有检错手段。

三、画出程序流程图:

四、源程序(带注释):

;数据段的定义

datasegment

msg1db'Pleaseputinthescoresbyrollnumbers(0-100):

',0ah,0dh,'$'

msg2db0ah,'Therankinglistisasfollows:

',0ah,0dh,'$'

msg21db'RankRoll_numScore',0ah,0dh,'$'

msg3db0ah,'Error!

!

Pleaseputinagain:

',0ah,0dh,'$'

tendb0;十位

unitdb0;个位

countdb0;数的个数

scoredb50dup(0);存放待比较的数

roll_numdb50dup(0);存放的是学号

rankdb50dup(0);存放名次

dataends

;堆栈段

stacksegmentstack'stack'

db100dup(?

stackends

;下面是宏定义(必须放在最前?

),注释须以";;"开始

coutmacrox;;输出十进制数字0-99

moval,ds:

[x]

movbl,01h

mulbl

aam;;这样AH中是十位数,AL为个位数

movten,ah

movunit,al

movdl,ten

adddl,30h

movah,02h

int21h;;显示十位数

movdl,unit

adddl,30h

movah,02h

int21h;;显示个位数

endm

showmacroy;;显示字符串

leadx,y

movah,9

int21h

endm

spacemacroz;;控制空格数

localspace_lp

pushcx

movcx,z

space_lp:

movah,02h

movdl,''

int21h

loopspace_lp

popcx

endm

;代码段

codesegment

assumecs:

code,ds:

data,es:

data,ss:

stack

start:

movax,data

movds,ax;设置段地址

callputin;输入数字

calldescend_sort;成绩按降序排列

calldisplay;显示名次,学号和成绩

exit:

movah,4ch;返回DOS

int21h

putinprocnear;输入函数

showmsg1;显示msg1

init:

movbx,0;初始化

leasi,score

leadi,roll_num

movcx,0;计数的个数

put:

movah,1

int21h;输入单个字符

jmpcheck;检查是否合法

legal:

incbl;用bl来标志输入了一个数字还是两个

incbh;用bh防止输入3位数

cmpbh,03h

jebe_3error

testbl,01h;bl=1表明输入的时十位

jnzis_ten

testbl,02h;bl=2是个位

jnzis_unit

is_ten:

subal,30h

movten,al;存入十位

jmpput

is_unit:

subal,30h

movunit,al;存入个位

movdh,10;计算这个两位数

moval,ten

muldh

addal,unit;是ten*10+unit最大为99,直接是在al中

save:

mov[si],al

incsi

inccl

mov[di],cl;存入学号

incdi

movbl,0

jmpput

check:

;检错子程序

cmpal,20h;是空格吗?

jebe_put;是则合法,继续输入

cmpal,0dh;是回车吗?

jebe_putback;是则返回寻找最小值

cmpal,30h;是数字吗?

jberror

cmpal,39h

jaerror

jmplegal

be_put:

movbh,0

testbl,01h;防止输入一位数

jnzbe_1

jmpput

be_1:

moval,ten;是1位数

jmpsave

be_3error:

cmpten,1;百位数是不是1

jnzerror

cmpunit,0

jnzerror

cmpal,30h;al中是不是0

jnzerror

moval,100

decsi

deccl

decdi

jmpsave;把100存入成绩

error:

showmsg3;显示msg3,可以考虑清屏

jmpinit;重新初始化

be_putback:

cmpbl,0

jeerror

testbl,01h

j

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

当前位置:首页 > 工程科技 > 能源化工

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

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