微机原理软件实验报告

更新时间:2024-04-21 17:10:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

信息与通信工程学院

微机原理软件实验报告

级:

姓 名:

学 号:

日 期: 2011年12月 微机原理软件实验·报告

实验一 DEBUG 的使用 .................................. 1

一、实验目的............................................................................................................ 1 二、实验内容............................................................................................................ 1 三、预习思考............................................................................................................ 3 四、实验过程............................................................................................................ 4 五、实验总结............................................................................................................ 9

实验二 分支、循环程序设计 ............................. 10

一、实验目的.......................................................................................................... 10 二、实验内容.......................................................................................................... 10 三、预习思考.......................................................................................................... 10 四、实验过程.......................................................................................................... 10 (一)、流程图 ....................................................................................................... 11 (二)、源代码 ....................................................................................................... 11 (三)、实验分析 ................................................................................................... 11 五、实验总结.......................................................................................................... 14

实验三 代码转换程序设计 ............................... 15

一、实验目的.......................................................................................................... 15 二、实验内容.......................................................................................................... 15 三、预习思考.......................................................................................................... 15 四、实验过程.......................................................................................................... 16 (一)流程图 ........................................................................................................... 16 (二)模块层次图 ................................................................................................... 16

第I页

微机原理软件实验·报告

(三)源代码 ........................................................................................................... 17 (四)实验分析 ....................................................................................................... 21 五、实验总结.......................................................................................................... 22

实验四 子程序设计 ..................................... 23

一、实验目的.......................................................................................................... 23 二、实验内容.......................................................................................................... 23 三、预习思考.......................................................................................................... 23 四、实验过程.......................................................................................................... 24 (一)流程图 ........................................................................................................... 24 (二)模块层次图 ................................................................................................... 25 (三)源代码 ........................................................................................................... 25 (四)实验分析 ....................................................................................................... 34 五、实验总结.......................................................................................................... 35

实验五 中断程序设计 ................................... 37

一、实验目的.......................................................................................................... 37 二、实验内容.......................................................................................................... 37 三、预习思考.......................................................................................................... 37 四、实验过程.......................................................................................................... 38 (一)流程图 ........................................................................................................... 38 (二)源代码 ........................................................................................................... 39 (三)实验分析 ....................................................................................................... 45 五、实验总结.......................................................................................................... 46

第II页

微机原理软件实验·报告

实验一 DEBUG 的使用

一、实验目的

1. 掌握汇编程序的编辑、编译、连接和执行的全过程; 2. 学习和掌握用DEBUG调试程序的方法。

二、实验内容

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

DAT SEGMENT A DB 20 B DB 15 Y DB 3 DUP(0) Z DB 0,0 DAT ENDS

STA SEGMENT STACK

DW 50 DUP(?)

STA ENDS COD SEGMENT

ASSUME CS:COD,DS:DAT STAR PROC FAR

PUSH DS XOR AX,AX PUSH AX MOV AX,DAT MOV DS,AX MOV AX,STA MOV SS,AX MOV AL,A MOV Z,AL

第1页

MOV Z+1,AL CALL SUB1 MOV AL,B MOV Z,AL MOV Z+1,AL CALL SUB1 MOV AL,A MOV Z,AL MOV AL,B MOV Z+1,AL CALL SUB1

微机原理软件实验·报告

ADD WORD PTR Y,AX ADC BYTE PTR[Y+2],0 RET

STAR ENDP SUB1 PROC

MOV AL,Z MOV AH,Z+1 MUL AH

ADD WORD PTR Y,AX ADC BYTE PTR[Y+2],0 RET

SUB1 ENDP COD ENDS

END STAR

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

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

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

地址。

2) 用 U 命令对目标代码反汇编,观察反汇编后的结果。注意发现源程序

的起始位置,并记录这个起始地址。

第2页

微机原理软件实验·报告

3) 用 T 命令作单步跟踪调试。比较每条指令执行后的结果和原来的理解

是否 一致,得出程序运行的结果:它们是写在什么单元,具体内容是什么;并判断结果是否正确。在子程序 SUB1 的入口处设一断点,用 G 命令执行程序。 在断点处观察堆栈的内容,比较堆栈的内容和程序返回地址是否一致。

4) 用 E 命令修改单元 A,B 的内容,重新执行程序,并记录结果。 5) 用 M 命令和 A 命令对程序进行修改:将主程序中最后两条指令

(ADD 和ADC) 修改为一条 CALL SUB1 指令,重新执行程序。 6) 退出 DEBUG。

4. 重新使用编辑软件,把源程序最后一句中的 STAR 去掉。再次生成可执行文件,并用 DEBUG 调入内存。当使用 U 命令时,显示的结果与前一次(未加 STAR) 的结果有何不同?

三、预习思考

1. 熟悉常用的 DEBUG 命令。

答:常用的DEBUG命令如下图表所示。

第3页

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

微机原理软件实验·报告

答:程序完成的功能是计算两个数的完全平方和,即计算a2+b2+ab 3. 若 SS=2000H,SP=FFFFH, 向堆栈中压入 4 字节数据后,如何用 D 命令显示压入堆栈的内?

答:使用的命令是:D 2000:FFFB,即使用段基址加偏移量查看。

四、实验过程

以下由实验截图展现具体的实验过程,截图进行了详细标注,便于阅读。

编译

上图为编译、链接形成可执行文件的过程。

(1)下图展现了进行反编译然后使用D命令查看数据段中A、B值的过程。 AB段地址:142EH

A:偏移地址0000H 物理地址142E0H, B:偏移地址0001H 物理地址142E1H

第4页

微机原理软件实验·报告

(2)下图为用u命令进行反汇编的结果,CS段地址1436H,起始偏移地址0000H

(3)下图是用T命令作单步跟踪调试,并在SUB1出设置一断点,可以看到程序执行到CALL 0003F时跳到了子程序进行执行,并将断点地址压入堆栈中,各寄存器的值均有显示。

CALL SUB1语句地址

第5页

微机原理软件实验·报告

CALL语句的下一个语句的地址

(4)下图使用E命令对数据段数据A和B进行了修改,分别由20和15改为了4和8,修改后重新运行用D命令进行了查看。

修改之前 修改之后

修改之后运行结果

(6)用 M 命令和 A 命令对程序进行修改: 将主程序中最后两条指令 (ADD 和 ADC) 修改为一条 CALL SUB1 指令,重新执行程序.下图是原程序

第6页

微机原理软件实验·报告

下图将sub1的代码转移到0055h的位置,防止修改后两句命令时影响sub1子程序

下图是用A命令修改call子程序的命令及后两句命令

第7页

微机原理软件实验·报告

下图为重新运行结果,与预测结果相符

(6)重新使用编辑软件,把源程序最后一句中的 STAR 去掉。再次生成可执行文件,再次DEBUG时。当使用 U 命令时,结果如下图所示。可以看到,没有END STAR语句,编译器将不知道代码段的入口地址是多少,导致从数据段开始译码,后续译码全部紊乱。END STAR的作用是指示编译器程序结束,同时告诉编译器程序执行时代码段的入口地址。

(7)下图为退出debug的结果

第8页

微机原理软件实验·报告

五、实验总结

此次实验是微机原理软件实验的第一次实验。由于平时只是注重理论的学习,没有多少实际编程和调试经验,上机操作还不熟练。以后需要加强实践。

这次实验我学会了汇编程序的基本调试方法,也体会到汇编的调试和C/C++或者Java调试的差异。汇编的调试需要深入堆栈和内存区,关心每一寄存器和每一个指令。这也体现汇编是底层语言的特点。

在这次实验中,我学会了各种调试命令,这对以后编程有着重要的意义,对于程序中的逻辑错误知道怎么去找问题。

第9页

微机原理软件实验·报告

实验二 分支、循环程序设计

一、实验目的

1. 开始独立进行汇编语言程序设计; 2. 掌握基本分支,循环程序设计; 3. 掌握最简单的 DOS 功能调用。

二、实验内容

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

2. 编写一个程序统计数据区中正数,负数和零的个数。 3. 将统计结果在屏幕上显示。

4. (扩展题)统计出正奇数、正偶数,负奇数、负偶数以及零的个数。

三、预习思考

1. 十进制数 0 ~ 9 所对应的 ASCII 码是什么? 如何将十进制数 0 ~ 9 在屏幕上显示出来?

答:0~9分别对应ASCII码的30H~39H。欲将十进制数0~9显示在屏幕上,只需要用二进制数0~9分别加上30H即可。

2. 如何检验一个数为正,为负或为零? 你能举出多少种不同的方法? 答:方法有多种,只要能通过指令影响标志寄存器,就可以通过标志寄存器来判断出正负和零,现举出两种。一是直接用CMP命令和0比较,然后用JZ等命令进行判断;二是和0相比是否相等,然后用该数(假设为8位)和10000000相与,取出符号位判断,可区分正负。

四、实验过程

第10页

(一)、流程图

微机原理软件实验·报告

(二)、源代码

;1.安排一个数据区,内存有若干个正数,负数和零.每类数的个数都不超过 9. ;2.编写一个程序统计数据区中正数,负数和零的个数. ;3.将统计结果在屏幕上显示. DATA SEGMENT

NUM DB -3,0,5,6,4,-6;要比较的数据 COUNT EQU $-NUM NUM_A DB 0 NUM_E DB 0 NUM_B DB 0

;存放数据的长度

;存放大于0的个数 ;存放等于0的个数 ;存放小于0的个数

STRING DB 0DH,0AH,'$'

STRING1 DB 'NEGATIVE',3AH,20H,'$' STRING2 DB 'EQUAL',3AH,20H,'$' STRING3 DB 'POSITIVE',3AH,20H,'$'

DATA ENDS

第11页

STACK SEGMENT STACK 'STACK'

DB 100 DUP(?)

微机原理软件实验·报告

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STACK

STARTPROC

MOV AX,DATA MOV DS,AX MOV CX,COUNT MOV DX,0 MOV AX,0

MOV BX,OFFSET NUM

LOOP1:AND BYTE PTR[BX],0FFH

JZ EA_IN JNS A_IN INC AL JMP NEXT

EA_IN:INC DL

JMP NEXT

A_IN:INC DH NEXT:INC BX

LOOP LOOP1

MOV NUM_B,AL MOV NUM_E,DL MOV NUM_A,DH

MOV AH,09H

MOV DX,OFFSET STRING1 INT 21H

MOV AH,02H

第12页

MOV AX,4C00H INT 21H MOV AH,09H

MOV DX,OFFSET STRING INT 21H MOV AH,09H

MOV DX,OFFSET STRING3 INT 21H MOV AH,02H MOV DL,NUM_A ADD DL,30H INT 21H MOV AH,09H

MOV DX,OFFSET STRING2 INT 21H MOV AH,02H MOV DL,NUM_E ADD DL,30H INT 21H; MOV AH,09H

MOV DX,OFFSET STRING INT 21H MOV DL,NUM_B ADD DL,30H INT 21H; MOV AH,09H

MOV DX,OFFSET STRING INT 21H

微机原理软件实验·报告

START ENDP CODE ENDS

第13页

END START

微机原理软件实验·报告

(三)、实验分析

数据区待统计的数据为:

-3,0,5,6,4,-6

实验结果如下图所示。

本实验较为简单,意在练习基本的分支、循环结构。关键的点在于和0FFH相与,区分正负和零。使得程序更加流畅和简洁,思路也更清晰。

五、实验总结

实验中设计好的计算思路是很重要的,汇编的代码由各种跳转和逻辑结构组成,需要考虑代码间的逻辑关系,否则容易出错。语法错误是很显而易见的,但逻辑错误却不容易发现。

当有大量判断和循环存在时,需要考虑清楚程序跳转的条件和方向,这点和高级语言有较大差异,汇编本质上没有循环和分支,都是通过将IP赋予代码区地址进行跳转实现的,程序员需要自主控制如何跳转,向何处跳转,这点和C/C++中饱受诟病的goto语句处理有些类似。

考虑到实验练习的重点在分支循环结构,此次写代码时暂时没有使用子程序或宏,导致输出部分代码有些过长。

第14页

微机原理软件实验·报告

实验三 代码转换程序设计

一、实验目的

1. 掌握几种最基本的代码转换方法; 2. 运用子程序进行程序设计。

二、实验内容

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

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

3. 对输入要有检错措施,以防止非法字符输入,并有适当的提示。 4. 将整个程序分解为若干模块,分别用子程序实现。在报告中要给出模块层次图。

三、预习思考

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

答:输入的字符0~9是ASCII码表示的,对应于30H~39H,通过减去30H,可以转换为相应的计算机数。

2. 如何将选出的最小值(二进制或十进制)变为 ASCII 码再进行显示? 答:如果采用输入时把ASCII码转换为数字,然后比较数字的大小再输出,那么输出时还需要把数字再次转换为ASCII码。这是不明智的。可以直接读入并存储数字的ASCII码,容易比较其大小,然后直接输出ASCII码即可。

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

答:采用二进制或者十进制都需要进行ASCII码到数字的转换和其反向转换,换用新的思路可以大大简化编程负担。即直接使用数字对应的ASCII比较,分别比较十位和个位,最后直接输出字符即可。

第15页

微机原理软件实验·报告

四、实验过程

(一)流程图

(二)模块层次图

第16页

(三)源代码

DATA SEGMENT

NUM DB 31 DB 0

DB 31 DUP(?) MINT DB ? MING DB ?

微机原理软件实验·报告

;NUMC DB 0,1,2,3,4,5,6,7,8,9 OKF DB 0

ERRS DB 'ERROR TYPE',0DH,0AH,'$' TIP

DB

'TYPE

IN

INTEGER,SPACE

TO

SEPRATE',0DH,0AH,'$'

OUTPUT

DB 'THE MIN IS ','$'

HH DB 0AH,'$'

DATA ENDS

;10

STACK SEGMENT STACK 'STACK'

DB 100 DUP(?)

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STACK

STARTPROC

MOV AX,DATA MOV DS,AX MOV ES,AX

MOV OKF,1

;用户输入提示

;20

AG: LEA DX,TIP

LEA DX,NUM MOV AH,09H INT 21H

;输入字符

第17页

MOV AH,02H MOV DL,MINT CALL LF

LEA DX,OUTPUT MOV AH,09H INT 21H

LEA BX,NUM INC BX MOV AL,[BX] MOV AH,0 MOV CL,3 DIV CL MOV CL,AL MOV CH,0 INC BX

LEA DX,HH MOV AH,09H INT 21H

;换行

MOV AH,0AH INT 21H

微机原理软件实验·报告

;30

;确定输入数的个数,保存到CX中

;40

CALL CHECK CMP OKF,0 JZ

MOV AL,[BX] MOV MINT,AL MOV AL,[BX+1] MOV MING,AL ADD BX,3

;将第二个数的偏移地址存入BX中

;将第一个数存入最小值中

AG

;调用查找最小值函数

第18页

EXIT:MOV AX,4C00H

INT 21H

INT 21H MOV DL,MING INT 21H

微机原理软件实验·报告

START ENDP ;检查是否输入出错

;是数字+数字+空格则判断正确,其余情况判断错误 CHECK PROC

PUSH BX PUSH CX

CNUM:PUSH CX

MOV CX,2

CFS: MOV AL,[BX]

CMP AL,30H JB ERR CMP AL,39H JBE NPL

ERR: MOV OKF,0

NPL: INC BX

CSP: MOV AL,[BX]

CMP AL,20H JNZ ERR LOOP CFS MOV AH,09H

MOV DX,OFFSET ERRS INT 21H POP CX JMP RE

第19页

NEXT:INC BX

POP CX LOOP CNUM MOV OKF,1

微机原理软件实验·报告

RE: POP CX

POP BX RET

CHECK ENDP

;查找最小值

;入口参数BX,出口参数MINT,MING LF

PROC PUSH CX DEC CX

LFC: MOV AL,[BX] 比较

EXCH:MOV AL,[BX]

NLF: ADD BX,3

POP CX RET LOOP LFC MOV MINT,AL MOV AL,[BX+1] MOV MING,AL MOV AL,[BX+1] CMP AL,MING JAE NLF

;十位数与最小数的十位数相等,比较个位数

CMP AL,MINT JB JA

EXCH NLF

;十位数比最小数的十位数小,交换

;十位数比最小数的十位数大,进入下一个数的

第20页

LF

ENDP

微机原理软件实验·报告

CODE ENDS

END START

(四)实验分析

下图是实验输出结果截图。实验中以空格为分隔符,空格的个数不限制,以回车为输入结束标志符。对输入的数字进行了位数和范围的严格限制,即必须是两位数字,如果数字小于10,需要补齐零。

实验中对输入错误执行严格的检查,出错则重新输入。判断输入错误的核心思路为:以空格为分割,以回车结束,要求必须是两位数,也即,一位数字后不能有空格,两位数字后必须有空格,以上三种情况囊括了所有可能的格式错误,不满足任何一个条件即出错。满足格式输入后,再判断字符的是否0~9,不是则出错。每项错误均已错误列表的形式给出,打印出错误提示。

总结实验中的关键设计思路如下:

1、严格的输入格式检查,严格的输入字符有效性检查。

2、以数组方式进行存储,每两个BYTE存储一个输入的两位数,存储格式为字符ASCII码。不进行字符ASCII码到数字的转换。

3、比较数字大小时,采用分别比较高位ASCII码和低位ASCII码的方式,从而不用在输入时将字符存储为数字,输出时也不用再进行逆转换。程序效率大为提高。

第21页

微机原理软件实验·报告

4、为使得程序结构清晰,减小代码耦合度,采用了多子程序的设计方式。把实验任务分为三步:读取输入、找出最小、输出打印,分别以子程序方式实现,主调函数依次调用完成实验任务。

五、实验总结

实验中比较大小的方式有多种,如何采用更加简洁有效的方式是值得思考的问题。考虑到ASCII也是可以比较的,且十位数和个位数是可以分别比较的这一情况,我采用了巧妙的方式进行处理。这说明,在实际的编程中,需要根据具体情况调整一般方法,使得方法更加简洁可行且有效。

第22页

微机原理软件实验·报告

实验四 子程序设计

一、实验目的

1. 进一步掌握子程序设计方法; 2. 进一步掌握基本的 DOS 功能调用。

二、实验内容

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

2. 统计检查每个学生的名次。 3. 将统计结果在屏幕上显示。

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

三、预习思考

1. 如何确定一个学生在这门科目中的名次?

答:有两种基本思路,一是抽取每个学生的成绩和其他所有学生的成绩进行比较,然后统计比其分数高的学生,得出该学生的名次;二是把学生成绩存入连续内存区域,即数组方式,取得每个学生的成绩偏移量,即成绩指针。然后比较指针所指的成绩的大小,根据比较结果移动指针完成排序。具体排序时可以采用诸多的方式,比如冒泡法,快速排序法等等,均是可行的。本实验采用第二种方式,用冒泡法予以具体实现。

2. 输入结束后,采用什么方法进行比较以得到学生的名次最为简单? 答:如上问所述,采用冒泡排序法可获得较好的时间和空间性能。冒泡法平均时间性能O(N2)。相比于直接比较,性能有所改善。但相对于快速排序、归并排序等优化的算法的时间复杂度O(N*log2N)还不够好。但后两者使用汇编实现代码的复杂度和编程要求要高。考虑到

第23页

微机原理软件实验·报告

学生人数比较少,使用冒泡法是比较简洁的,时间性能是可以接受的。

3. 准备好模块层次图。

答:见下文“实验过程”中所示。 4. 给出输出显示的形式。

答:输出以列表形式给出。学号、分数、名次各一列。具体形式参见实验分析部分的输出截图。

四、实验过程

(一)流程图

第24页

(二)模块层次图

微机原理软件实验·报告

(三)源代码

DATA SEGMENT

RSCORE

DB 40 DUP(0)

;存

储分数排名

SCORE DB 0

DB 100 DUP(?) ASCORE

DB 40 DUP(0)

;存

DB 100

储调整后的分数值 ;10

SCOUNT

DB 1

;十进制转

OKF DB 0

;输入数据有效位

REF DB 09H

BCD参考数

第25页

TEN DB 0

微机原理软件实验·报告

ERRS DB 'ERROR TYPE',0DH,0AH,'$' ;出

错提示符

TIP DB 'TYPE ININTEGER,SPACE TOSEPRATE',0DH,0AH,'$'

;输入提示符 ;换行字符串

HH DB 0DH,0AH,'$' STRNUM NO

EQU $-HH

DB 'NO.','$'

;号数字符串 ;冒号+空格字符串 ;显示统计数据

SPOUTDB 3AH,' ','$'

STA DB 'STATIC',3AH,'$'

DATA ENDS ;27

STACK SEGMENT STACK 'STACK'

DB 100 DUP(?)

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STACK

;打印字符串的宏 PRINT MACRO PARA

PUSH AX PUSH DX MOV AH,09H

MOV DX,OFFSET PARA INT 21H POP DX POP AX

ENDM

STARTPROC

MOV AX,DATA MOV DS,AX MOV ES,AX

第26页

微机原理软件实验·报告

LEA DI,ASCORE ;ASCORE存放调整后的分数数组 LEA SI,RSCORE ;RSCORE存放排序后的分数数组 CLD

AG: MOV OKF,1

MOV NUMC,1 MOV SCOUNT,1 MOV CL,7 MOV CH,0 LEA BX,COUNT

CLE: MOV BYTE PTR[BX],0 ;60

PRINTHH

;换行

INC BX LOOP CLE PRINTTIP

;提示用户输入

LEA DX,SCORE ;输入字符 MOV AH,0AH INT 21H

;确定输入字符的个数,保存到CL中

LEA BX,SCORE ;BX指向SCORE首单元 INC BX

;BX指向字符数单元

;CL存字符数目

MOV CL,[BX] MOV CH,0 INC BX

;BX指向第一个字符单元 ;判断是否输入出错 ;如果出错重新输入

CALL CHECK CMP OKF,0 JZ

AG

;调整分数及排序

MOV CL,COUNT ;CL存学生数目 MOV CH,0

MOV AL,[BX]

LOOP1:

SUB AL,30H

MOV AH,[BX+1] ;查找出这个数是一位数两个数还是三位数 CMP AH,20H

第27页

JZ

LOC1

;一位数,跳转到LOC1

微机原理软件实验·报告

MOV AH,[BX+2] CMP AH,20H JZ

LOC2

;两位数,跳转到LOC2

;MOV AH,[BX+3] ;CMP AH,20H ;JZ LOC3

;三位数,跳转到LOC3

LOC3:MOV AX,100

;三位数,只有100,存入AL,BX移到下一个成绩处

ADD BX,4 JMP LOCA

;两个数的分数,BX加1,指向个位数 ;十位数乘10放到DL里,再加上个位数

LOC2:INC BX

MOV AH,0 MOV DL,10 MUL DL MOV DL,AL MOV AL,[BX] SUB AX,30H ADD AL,DL

;个位数放到AL

LOC1:MOV AH,0

ADD BX,2;100

;存串操作,将转换后的分数存到ASCORE里

;调用排序函数

LOCA:STOSB

CALL LSCORE LOOP LOOP1

;显示排名

LEA DI,ASCORE LEA BX,SCORE ADD BX,2 MOV CL,COUNT MOV CH,0

SHOW:PUSH CX

;显示号数 CALL SHOWNO

第28页

MOV AH,02H MOV DL,'R' INT 21H MOV DL,3AH INT 21H ;查找名次 CALL LOSCORE ;显示名次

MOV AH,02H MOV DL,'S' INT 21H MOV DL,3AH INT 21H CALL SHOWSC

微机原理软件实验·报告

MOV AH,02H MOV DL,CH INT 21H MOV DL,CL INT 21H ;输出格式调整 MOV AH,02H MOV DL,09H INT 21H

MOV AL,NUMC MOV AH,0 MOV CL,3 DIV CL CMP AH,0 JNZ NEXTST

MOV AH,09H

;换行

;满三个换行

;输出制表符

MOV DX,OFFSET HH

第29页

INT 21H ;查找下一个学生

INC DI

微机原理软件实验·报告

NEXTST:

INC NUMC POP CX LOOP SHOW

EXIT:MOV AX,4C00H

INT 21H

START ENDP

;查错子程序:对输入的数据进行查错,

;含有非数字或非空格字符或者连续出现两个空格则报错 ;入口参数:BX,COUNT,出口参数:OKF(1有效) CHECK

PROC

PUSH BX PUSH CX

;保护现场

CN: MOV AL,[BX]

CMP AL,30H JB CSP CMP AL,39H

;判断是否大于30H,小于30H就判断是不是空格

;大于30H判断是否大于39H,大于则报错,小于则跳;到下一字节进行判断

JBE NEXTB

;判断是否是空格,是空格学生数加1

CSP: CMP AL,20H

JZ

NUMI

ERR: MOV OKF,0

MOV AH,09H

MOV DX,OFFSET ERRS INT 21H JMP RE

NUMI:INC COUNT

CMP BYTE PTR[BX+1],20H JZ

ERR INC BX

NEXTB:

第30页

LOOP CN MOV OKF,1

微机原理软件实验·报告

RE: POP CX

POP BX RET

CHECK ENDP

;排序子程序:对COUNT个数字进行排序 ;入口参数:COUNT,SI LSCORE

PROC

PUSH CX PUSH BX PUSH SI MOV CL,COUNT MOV CH,0

;AL与当前SI的值进行比较,如果比SI大, ;移动SI并插入,否则直接插到末尾

LSC: CMP AL,[SI]

JAE MOVRANK ADD SI,1 LOOP LSC

MOVRANK:CALL

STODT

MOV [SI],AL POP SI POP BX POP CX RET

ENDP

LSCORE

;子程序用途:将从SI开始的字符串向下移一位 ;入口参数:转移的起始位置SI,字符串总个数COUNT STODTPROC

PUSHF PUSH AX PUSH CX

第31页

MOV CH,0 MOV AX,SI MOV DI,AX PUSH DI PUSH SI PUSHF

微机原理软件实验·报告

MOV CL,COUNT ;CL存放需要转移的字符个数:COUNT-SI-1个 SUB CX,SI DEC CX ADD DI,CX MOV AX,CX DEC AX

;SI加上需要转移的个数减1,倒数第二个单元 ;方向:递减 ;转移串,SI->DI

;DI加上需要转移的个数,指向最后一个单元

ADD SI,AX STD

REP MOVSB POPF POP SI POP DI POP CX POP AX POPF RET

STODTENDP ;显示号数 ;入口参数:NUMC SHOWNO

PROC

MOV CL,NUMC CALL BTODD

MOV DX,OFFSET NO MOV AH,09H INT 21H

第32页

MOV AH,02H CMP CH,0 JZ

SINNO

微机原理软件实验·报告

;如果号数是个位数,则十位数不显示

MOV DL,CH INT 21H

;显示号数的个位数

SINNO:MOV DL,CL

INT 21H PRINTSPOUT RET

ENDP

;显示冒号和空格

SHOWNO

;显示分数

;入口参数:BX SHOWSC

PROC

MOV AH,02H

SOUT:MOV DL,[BX]

INT 21H

CMP BYTE PTR[BX],20H;如果该字符是空格,则跳出子程序 JZ

ROUT

INC BX JMP SOUT

ROUT:INC BX

RET

ENDP

SHOWSC ;确定名次 LOSCORE

PROC

MOV CL,COUNT MOV AL,[DI]

MOV SI,OFFSET RSCORE;找名次

CMP AL,[SI] GETRANK

RANKS:

JZ

ADD SI,1 LOOP RANKS

第33页

GETRANK:NEG

CL

;求名次

微机原理软件实验·报告

ADD CL,COUNT ADD CL,1 CALL BTODD RET

ENDP

LOSCORE

;二进制转换为非组合BCD码 ;入口参数CL,出口参数CX, BTODDPROC

MOV REF,09H MOV TEN,00H

;参考值 ;十位数

;CL与参考值相比,比后者大,则参考值加10, ;十位数加1

CH存十位数,CL存个位数

COMPARE:CMP CL,REF

JBE DDOUT

BTNEXT:

ADD REF,0AH

INC TEN JMP COMPARE

;CH存十位数,CL存个位数

DDOUT:

MOV CH,TEN

ADD CL,09H SUB CL,REF

ADD CX,3030H ;CX加3030H,用于屏幕显示 RET

BTODDENDP CODE ENDS

END START

(四)实验分析

输入输出格式如下图所示。首先提示输入学生人数,然后逐个提示输入学号和分数,输入完毕之后打印出最终结果,结果输出按照表格的形式给出,三列分别为学号、分数、排名。

第34页

微机原理软件实验·报告

设计输入的学生个数上限是100人。分数从0—100分。学号可以输入任意长度的15位数字,存储为字符串格式,每个学生固定长度。分数经过转换后存储为数字,每人占用一个BYTE。名次亦存储为数字,每人占用一个BYTE。

下图演示了错误输入时的处理,根据错误类型打印出提示,并允许进行重新输入,而不用退出程序。

本程序设计的主要特点如下:

1、在程序设计思路上,采用了多子程序模块化设计,充分利用了宏和DOS功能调用等高级汇编技巧。

2、在数据结构设计上,采用数组的方式进行存储,可直接又下标(即学生的班内序号)进行直接寻址,效率较高。

3、在进行排名比较时,利用了指针技术,即对分数的偏移量进行排序,而不移动实际的分数。模拟了高级语言中的数组和指针的技术,结构和思路完整规范。排序技术选用了冒泡排序,获得一定的性能提升。

4、对用户输入进行严格的检查,对各种可能出现的错误进行了提示和处理。使得程序具有很好的完备性和健壮性。

五、实验总结

此次实验是在前几次实验的基础上完成的,综合了子程序设计、DOS调用、宏汇编等等编程方法和技术。具有很强的综合性。程序的设计按照小型程序的要求,充分考虑了健壮性和运行效率等因素,精心设计了数据结构

第35页

微机原理软件实验·报告

和算法。是可用于实际工程的代码雏形。由于完备性、健壮性、效率、界面等方方面面都考虑到,故代码长度达到了461行。这也使得调试花费了大量时间。综合实验对我的汇编编程能力的提升大有帮助。从四次实验的整个过程来看,我的进步是十分明显的。这也是令我十分欣喜的事情。

第36页

微机原理软件实验·报告

实验五 中断程序设计

一、实验目的

1. 初步掌握中断程序的设计方法;

2. 初步掌握修改 DOS 系统中断,以适应实际使用的方法。

二、实验内容

1. 编写一个32位二进制数除以16位二进制数的除法程序。观察当除数为 0,或超过相应寄存器范围时,程序执行的结果。 2. 修改零号中断服务程序,使它具有以下功能:

1) 判断除数是否为0,当除数为0时,显示相应的结果;

2) 当除数不为0时,采用适当的方法完成商超过16位的二进制数的

除法运算。

3. 注意必须保护原有中断服务程序的入口地址,并在程序完毕前加以恢复。 4. 选作题:

1) 用二进制将结果在屏幕上显示。 2) 从键盘输入二进制数。

三、预习思考

1. 如何保护原有中断向量表中的中断服务程序的入口地址?

答:先读取中断向量表中0号中断的地址,压入堆栈,程序结束时弹出堆栈,写回中断向量表即可。

2. 如何将你的中断服务程序入口地址置入中断向量表?

答:有两种基本方法:一是直接写入法,使用指令将中断服务程序入口地址的IP写入n×4的RAM位置,中断服务程序入口的CS写入n×4+2的位置;二是DOS功能调用,25H用来写中断向量表,35H读中断向量表。

第37页

微机原理软件实验·报告

四、实验过程

(一)流程图

第38页

(二)源代码

DATA SEGMENT

XX DD ?; 被除数32bit YY DW ?; 除数 16bit TMP DW ?

微机原理软件实验·报告

FLAG DB 0 ;是否调用了中断处理程序的标志位,即是否溢出

;一些提示信息

ERR0 DB ' ERROR! Divide by ZERO! ','$' TIP1 DB 'Quotient : ','$' TIP2 DB 'Remainder: ','$'

TIP3 DB 'Input high 16-bit of dividend:','$' TIP4 DB 'Input low 16-bit of dividend:','$' TIP5 DB 'Input 16-bit divisor:','$' CR DB 0DH,0AH,'$';回车换行 ONE DB '1','$' ZER DB '0','$' TAB DB 09H,'$'

BUFF DB 17 ;输入缓冲区,可容纳包括回车在内的17个字符

PRES DB 0

CHAR DB 17 DUP(0)

DATA ENDS

;-------------------------------------------------------- ;定义堆栈

STACK SEGMENT STACK 'STACK' DB 100 DUP(0) STACK ENDS

;-------------------------------------------------------- CODE SEGMENT

ASSUME DS:DATA,CS:CODE,ES:CODE,SS:STACK ;打印字符串的宏 PRINT MACRO PARA

PUSH AX PUSH DX MOV AH,09H

第39页

MOV DX,OFFSET PARA INT 21H POP DX POP AX

微机原理软件实验·报告

ENDM

;-------------------------------------------------------- ;主程序入口 MAIN:

MOV AX,DATA MOV DS,AX MOV AX,0 MOV ES,AX

;保存原中断向量表

MOV AX,WORD PTR ES:[0000H] PUSH AX

MOV AX,WORD PTR ES:[0002H] PUSH AX

;写入新的中断处理子程序地址

MOV WORD PTR ES:[0000H],OFFSET INT0 MOV WORD PTR ES:[0002H],SEG INT0

CALL INPUT; 获取输入 MOV DX,WORD PTR XX; 移入被除数高16位 MOV AX,WORD PTR XX+2; 移入被除数低16位 MOV BX,YY ;移入除数 DIV BX; 进行32位除法运算

CMP FLAG,0; 查看是否调用了中断处理程序,即可判断是否溢出 JNE ISOF; 溢出跳转,到扩充除法的结果输出

; 否则直接输出没有溢出的正常除法结果

PRINT TIP1 MOV BX,AX CALL DISP2 PRINT CR PRINT TIP2 MOV BX,DX

第40页

CALL DISP2 JMP EOP

微机原理软件实验·报告

;有溢出的时候需要输出32位商和16位余数

ISOF:

PRINT TIP1 MOV BX,DX CALL DISP2 MOV BX,AX CALL DISP2 PRINT CR PRINT TIP2 MOV BX,CX

CALL DISP2 EOP:

POP AX; 程序结束出口

;恢复中断向量表

MOV WORD PTR ES:[0002H],AX POP AX

MOV WORD PTR ES:[0000H],AX MOV AX,4C00H; 返回DOS INT 21H

;-------------------------------------------------------- ;新的0号中断子程序 INT0:

POP SI

ADD SI,2; 修改IP的值,指向DIV后的指令 PUSH SI

CMP BX,0; 判断除数是否为0

JE DIV0; 为零则提示除数为0,然后返回DOS MOV FLAG,1; 置标志为除数不为零溢出

;进行扩展除法运算,分别用除数除以被除数高16位和低16位 ;输出参数为DX:商高16位,AX:商低16位,CX:16位余数

PUSH AX MOV AX,DX

第41页

XOR DX,DX; 除前将DX清零 DIV BX; 高16位除法

微机原理软件实验·报告

MOV CX,AX; 保存商的高16位 POP AX; 取出被除数低16位 DIV BX; 低16位除法

XCHG CX,DX; 同时保存余数和商的低16位 JMP EXIT DIV0:

PRINT ERR0; 被零除错误打印 MOV AX,4C00H; 返回DOS INT 21H EXIT:IRET

;-------------------------------------------------------- ;获取用户输入二进制序列的代码 INPUT PROC NEAR PUSH AX PRINT TIP3

CALL GETIN; 调用获取一次输入缓冲,得到16位二进制码 CALL CHANGE; 对字符进行转换,得到二进制序列 MOV AX,TMP

MOV WORD PTR XX[0],AX; 保存被除数高16位 PRINT CR PRINT TIP4 CALL GETIN CALL CHANGE MOV AX,TMP

MOV WORD PTR XX[2],AX; 保存被除数低16位 PRINT CR PRINT TIP5 CALL GETIN CALL CHANGE MOV AX,TMP

MOV YY,AX; 保存除数 PRINT CR

第42页

POP AX RET INPUT ENDP

微机原理软件实验·报告

;------------------------------------------------------- ;缓冲区0、1字符序列转换为二进制数子程序 CHANGE PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX

MOV CX,16; 总共16bit XOR BX,BX

LOPC: MOV AL,CHAR[BX]; 依次取出每个bit CMP AL,30H

JE IS0; 是零的处理 JMP IS1; 是一的处理 IS0: CLC

RCL DX,1; 把CF清零,然后循环左移,可得到二进制序列 JMP EXTCH IS1: STC

RCL DX,1 ; 把CF置一,循环左移 EXTCH: INC BX

LOOP LOPC ; 把16bit输入处理完 MOV TMP,DX ;保存转换后的二进制数 POP DX POP CX POP BX POP AX RET CHANGE ENDP

;------------------------------------------------------- ;获取一次输入字符串缓冲子程序 GETIN PROC NEAR

PUSH AX

第43页

PUSH DX PUSH DI

微机原理软件实验·报告

MOV DX,OFFSET BUFF MOV AH,0AH INT 21H POP DI POP DX POP AX RET

GETIN ENDP

;------------------------------------------------------- ;显示二进制序列的子程序,把二进制数转换为0、1字符串输出 DISP2 PROC NEAR PUSH CX MOV CX,16 HERE:

SHL BX,1; 二进制数左移到CF

JNC ISZERO; 判断CF是0还是1,分别打印之 PRINT ONE ;打印字符一 JMP ISONE ISZERO:

PRINT ZER ;打印字符零 ISONE:

LOOP HERE

PRINT TAB POP CX RET DISP2 ENDP

;------------------------------------------------------- CODE ENDS END MAIN

第44页

(三)实验分析

本程序完成了以下主要功能:

微机原理软件实验·报告

1. 读取用户键盘输入二进制数并处理。

2. 修改零号中断处理程序。保护并恢复了原中断向量表。 3. 在中断程序中处理除数为零的情况。

4. 用扩展除法处理除数不为零32位除法溢出,得出正确结果并显示。 5. 用二进制在屏幕显示输出。

实验中首先读取用户输入的0、1符号,进行转换,成为二进制数,然后分别测试了无溢出时的处理、有溢出时的处理、除数为零时的处理。如下两图为32位除以16位溢出时触发0号中断,用扩展的32位除法得到正确结果的测试截图。

下图为除数为0时的测试截图。输出错误提示,并返回DOS。

程序设计的核心思路如下:

1. 通过从键盘读取用户输入,得到32位被除数和16位除数。从字符到二进制数转换的方法是逐位移位判断,然后依据判断结果写CF标志,再用循环移位可将每次得到的二进制位移入16位寄存器保存。

第45页

微机原理软件实验·报告

2. 保护和恢复中断向量表。采用的是直接读取的方式,压入堆栈保存,退出程序时将其弹出并直接写入中断向量表。

3. 修改零号中断服务程序。采用直接修改向量表的方式实现。在修改后的中断服务程序中,对除0和非除零溢出分别进行处理。非除零溢出时采用扩展的32位除法得到正确的结果,返回32位商和16位余数。

4. 输出二进制数也是移位,根据CF标志决定输出符号0还是符号1。

五、实验总结

由于时间安排的问题,实验E,也是扩展实验,没能在验收前写完。故仅能在报告中写出。但不论怎样,编写中断程序让我收获颇多。

中断是计算机史上十分重要的发明,其思想是很优秀的。中断让CPU真正解放出来,成为了名副其实的决策者和领导者。纵观计算机设计的各种思路,不论是体系结构的层次化,还是权限的分配与优先权等等,和人类社会颇有几分相似。中断程序设计是很有意思的部分,是深入汇编或者说微机的必经之路。

本实验本身难度不大,但可以从中体悟到中断的基本的概念,适合于领会理论课的知识。为了概念的清晰,本实验并没有把过多的精力放在如何处理输入错误这类问题上,实际上前几个实验已经完美解决了输入检查和输出控制的内容,没有必要把代码写得很冗长,反而喧宾夺主。

五个实验完成下来,我的编程技术有较大的提升,对于微机有更深的理解。微机原理和接口技术,涉及到了软件和硬件两个方面,相信过段时间开始的硬件实验将也会收获很多。这还是大学第一次软硬件的综合,以前的学习总是要么电路要么高级语言,二者分离,对硬件和软件的理解总是受限在一定层次。微原这门课为我打开了一扇窗——通向软硬综合的窗口。

第46页

本文来源:https://www.bwwdw.com/article/r3xp.html

Top