微机原理实验报告西安交通大学

更新时间:2024-05-08 09:22:01 阅读量: 综合文库 文档下载

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

西安交通大学

电子信息与工程学院自动化科学与技术系

微机原理与接口技术实验报告

实验名称 : 微机原理与接口技术

实验者姓名: XX 实验者学号: 21105040XX

所在班级: 自动化1X

报告完成日期: 2014年 1月12日

实验一

数据传送、算术运算、循环程序结构

1、实验目的

a) 熟悉8086汇编语言源程序的框架结构,并掌握汇编语言程序的编写、汇

编、连接、执行的过程,并利用Turbo Debugger调试汇编程序。 b) 熟悉8086指令系统的数据传送指令,掌握寻址方式。

c) 熟悉8086指令系统的算术运算指令。掌握循环结构汇编语言程序的编制。 2、实验内容

教材P121,第14、15题。教材P195,第6题。教材P196,第12题。 3、具体实验

第一题(P121,第14题)

设有两个8个字节长的BCD码数据BCD1及BCD2。BCD1数以1000H为首地址在内存中顺序存放;BCD2数以2000H为首地址在内存中顺序存放。要求相加后结果顺序存放在以2000H为首地址的内存区中(设结果BCD数仍不超过8个字节长)。

a) 实验原理 考虑两个8个字节长的BCD码相加,首先根据地址要求将数据放在对应的地址单元中,然后做加法,BCD码相加要用到调整指令,结果才为正确的BCD数

b) 程序框图

c) 程序源代码

DATAS SEGMENT ORG 1000H

BCD1 DB 01H,02H,03H,04H,05H,06H,07H,88H;起始地址为1000H ORG 2000H

BCD2 DB 11H,12H,13H,14H,15H,16H,17H,18H;起始地址为2000H DATAS ENDS

CODES SEGMENT

ASSUME CS:CODES,DS:DATAS START:

MOV AX,DATAS MOV DS,AX MOV BX,0

MOV CX,8 ;设置循环次数8次 CLC ;清进位CF标志 AGAIN:MOV AL,[BX+1000H]

ADC [BX+2000H],AL;结果放在2000H开始的单元内 DAA INC BX

LOOP AGAIN;没完成则转AGAIN循环 MOV AH,4CH INT 21H CODES ENDS END START

运行: BCD1 DB 11H,12H,13H,14H,15H,16H,17H,18H

BCD2 DB 21H,22H,23H,24H,25H,26H,27H,28H

结果如下:DS:2000H为首地址的连续八个字节单元中

第二题(P121,第15题)

设从2000H为首地址的内存中,存放着10个带符号的字节数据,试编写“找出其中最大的数,并存入2000H单元中“的程序。

a) 实验原理

首先把十个带符号数放在要求的的存储单元中,然后再进行比较,有符号数的比较用JL,JC,JNG,等指令,首先设计一个最小带符号数80H作为比较初值,用2000H单元中的数分别与其它进行比较,若大于则把该单元的数存入2000H单元,否则不予处理。

对于该题,我采用的是字符串指令,由于是隐含寻址,把2000H中的数作为字符串源操作数,其它进行一次循环则依次放入AL中,注意的是当CX为10时,DL=80H。

b) 程序框图

c) 程序源代码 DATA SEGMENT

ORG 2000H;数据存放在2000H开始的单元

BCD DB 10H,28H,49H,69H,0A1H,0C3H,96H,29H,45H,02H DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX

MOV SI,2000H;地址指针指向单元首地址 MOV CX,10

MOV DL,80H;设置最小符号数 L1: LODSB

CMP AL,DL;比较带符号数 JNG L2 ;(DL)大则跳转L2

MOV DL,AL;DL指向内容小则交换 L2: LOOP L1

MOV DS:[2000H],DL;最大数存放在2000H单元 MOV AH,4CH INT 21H CODE ENDS END START

运行:BCD DB 10H,28H,49H,69H,0A1H,0C3H,96H,29H,45H,02H 结果为69H

第三题(P195,第6题)

试编制一程序,用乘法指令实现32位二进制数与16位二进制数相乘。 a) 实验原理

首先把被乘数第八位和高八位分别与乘数相乘,高八位乘得结果左移16位与第八位乘得结果相加即为结果。

b) 程序框图

c) 程序源代码 DATA SEGMENT

DATAX DW 1000H,1000H DATAY DW 2000H DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START: MOV AX,DATA

MOV DS,AX

MOV BX,1000H ;将把结果存到1000H开始的单元中 MOV SI,OFFSET DATAX MOV DI,DATAY

MOV AX,[SI]

MUL DI ;把低16位相乘,结果存到AX,DX中

MOV [BX],AX ;把结果中低16位存到BX对应的存储单元 MOV [BX+2],DX ;把结果中高16位存到BX+2对应的存储单元

MOV AX,[SI+2] ;计算被乘数高16位相乘的结果 MUL DI

ADD [BX+2],AX ;把两次相乘结果对应(把第二次的结果 ;向左移16位)相加,最后结果存在了[BX] 到[BX+5] ADD [BX+4],DX MOV AH,4CH INT 21H CODE ENDS END START

运行:结果在DS:1000中

第四题(P196,第12题)

设有两个等字长,字节型字符串,试编写一汇编程序,比较它们是否完全相等,若相等则将字符Y送入AL中,否则将字符N送入字符中。

a) 程序框图

b) 程序源代码 DATA SEGMENT

STRX DB 'CZX0','$' STRY DB 'CZX1','$' DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV ES,AX CLD

LEA DI,STRY;取字符串1首地址 LEA SI,STRX;取字符串2首地址 CALL L1

MOV DL,AL ;显示结果 MOV AH,02H INT 21H

MOV AH,4CH INT 21H L1 PROC

MOV CX,10

REPZ CMPSB STRX,STRY ;比较两个字符串 JNZ RA ;不相等则跳转到RA MOV AL,'Y' ;相等则将Y送AL

JMP RB

RA: MOV AL,'N' ;不相等则将Y送AL RB:RET ;比较结束返回程序 L1 ENDP CODE ENDS END START

运行:当字符串为STRX DB 'CZX0','$' STRY DB 'CZX1','$'

当字符串为STRX DB 'CZX0','$' STRY DB 'CZX0','$'

4、实验中遇到的问题:

在刚开始接触实验时感觉非常困难,无从下手,后来经过仔细认真阅读书上的经典程序之后,基本能够写出关键程序片段,再借助辅导书完善了实验程序内容,基本顺利地完成了实验。

本次实验让我熟悉了汇编语言的实现步骤和常用的指令系统,同时也学会了利用DEBUG调试汇编程序。

实验二 汇编语言程序设计

1、实验目的

a) 练习编写较复杂汇编语言程序时程序框图的绘制。 b) 子程序定义与调用,参数传递的方法。

c) 了解宏指令的定义与调用,并与子程序定义与调用进行比较。 d) 掌握利用软件中断实现DOS系统调用的方法。 2、具体实验

第一题:

教材4章,第8题,设n=10。即试编制程序,找出前十个质数。 提示:编写一个判断某数是否质数的子程序,主程序调用该子程序,对顺序递增的自然数进行是否质数的判断,若是则存放在质数缓冲区中,直到找到10个质数,程序结束。

判断一个数N是否是质数的一种算法是:将N顺序与2~N-1的数相除,若每次除法的余数均不等于0,则该数是质数。

注意:8086的除法支持双字除以字,字除以字节,本题中可以选择字除以字节。

正确结果为:02,03,05,07,0B,0D,11,13,17,1D(十六进制数)

a) 实验原理

找出前十个质数,质数只能被1和其自身整除,但考虑到如果从2开始一个一个的除的算法效率太低,很多已经是合数的作为除数是浪费的,故该算法用每一个数除以已经判断出来的质数(均小于该数),如果不能整除则说明该数是质数,能整除说明该数不是质数,继续进行下一个判断。

b) 程序框图

c) 程序源代码 N EQU 10

STRDISP MACRO POS MOV DX,OFFSET POS MOV AH,9H INT 21H ENDM

NUMTOSTR MACRO NUM,POS MOV AX,NUM MOV SI,OFFSET POS ADD SI,LENGTH POS-2;从最后开始(不考虑字符串结束符\存放5个字符

CALL WORDTOSTR; ENDM

DATAS SEGMENT

NUMBER DW N DUP(0) LAST DW ?

NUMNOW DW ?

STR1 DB \,0DH,0AH,\ STR3 DB \,\ STRNO DB 6 DUP(\),\

STRPRIME DB 6 DUP(\),\ HCHH DB 0DH,0AH,\DATAS ENDS

STACKS SEGMENT STACKS ENDS

CODES SEGMENT

ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:DATAS START:

MOV AX,DATAS MOV DS,AX MOV ES,AX

MOV AX,STACKS MOV SS,AX

MOV SI,OFFSET NUMBER;质数数组首地址 MOV BX,0

MOV NUMBER[SI+BX],2;第一个质数为2 MOV LAST,0;最后一个质数地址 MOV DX,2;第一个质数是2 MOV NUMNOW,1;质数计数 LOOP1:

INC DX;往后查找 MOV BX,2; MOV CX,0 LOOP2:

;判定DX中数据是否是质数

PUSH DX;保存现场,防止除法运算带来的改变 MOV AX,DX MOV DX,0

ADD SI,CX;求出作为除数的质数的相对位移

MOV BX,NUMBER[SI];从质数集里读取质数 ADC SI,CX;还原SI INC CX

INC CX;cx自加2

DIV BX;DX<-(DX:AX)/(BX)余数 CMP DX,0 POP DX

JZ LOOP1;除尽则表示该数不是质数,继续查找下一个 CMP BX,DX

JB LOOP2;如果除数小于被除数,则增大除数继续做除法 ADD LAST,2;相当于指针往后移动一个字的单位长度 MOV BX,LAST

MOV NUMBER[SI+BX],DX;将找到的质数存入数组,基址变址寻址 ADD NUMNOW,1;质数计数加1

CMP NUMNOW,N;得到N个质数则结束 JNZ LOOP1;否则继续查找

;输出结果

MOV NUMNOW,1

MOV DI,OFFSET NUMBER STRDISP STR1 DISPLAY:

NUMTOSTR NUMNOW,STRNO MOV AX,DS:[DI]

NUMTOSTR AX,STRPRIME STRDISP STRPRIME;输出质数 STRDISP HCHH INC DI INC DI

ADD NUMNOW,1 CMP NUMNOW,N JBE DISPLAY

;等待键盘输入,使程序不会立即退出 STRDISP STR3 MOV AH,08H INT 21H

MOV AH,4CH INT 21H ;子程序

;WORDTOSTR

;将AX中数字转换成5个字符的字符串,存入SI为首地址的存储单元里

WORDTOSTR PROC FAR PUSH SI MOV CX,5;设置循环次数 NEXTDIGIT:MOV DX,0 MOV BX,10 CMP AX,0 JZ BLANK DIV BX ADD DX,30H;将得到的每位数字转换为对应的ASCII码 SETCHAR:MOV [SI],DL DEC SI MOV DX,0 LOOP NEXTDIGIT POP SI CMP BYTE PTR [SI],20H JZ ZERO RET

ZERO:MOV BYTE PTR[SI],30H RET

BLANK:MOV DL,20H JMP SETCHAR WORDTOSTR ENDP CODES ENDS END START

运行结果:

第二题

编写一个汇编程序,实现N!(N>=0):

N!=N*(N-1)*(N-2)*??*1

(设N=3),跟踪IP变化,观察堆栈的变化,理解子程序递归调用中程序执行的流程,以及帧信息的组成。(注意BP的变化)

a) 程序框图

b) 程序源代码 DATA SEGMENT

RESULT DW ? SAVE_BP DW ?

SAVE_CS_IP DW 2 DUP(?) N DW 3 SAVE_N DW ?

RESULT_ADDR DW ? NFACT DB 6 DUP(?)

DATA ENDS

STACK SEGMENT

TOP LABEL WORD DW 128 DUP(0)

STACK ENDS

CODE1 SEGMENT

ASSUME CS:CODE1,DS:DATA,SS:STACK START: MOV AX,STACK MOV SS,AX

MOV SP,OFFSET TOP PUSH DS

MOV AX,DATA

FACT DONE: RETURN: FACT MOV DS,AX

MOV BX,OFFSET RESULT PUSH BX

MOV BX,N PUSH BX

CALL FAR PTR FACT MOV AH,4CH INT 21H

PROC FAR PUSH BP MOV BP,SP PUSH BX PUSH AX

MOV BX,[BP]+RESULT_ADDR MOV AX,[BP]+SAVE_N CMP AX,0 JE DONE PUSH BX DEC AX PUSH AX

CALL FAR PTR FACT

MOV BX,[BP]+RESULT_ADDR MOV AX,[BX]

MUL [BP]+SAVE_N JMP SHORT RETURN MOV AX,1 MOV [BX],AX POP AX POP BX POP BP RET 4 ENDP

CODE1 ENDS

END START

查看指令

观察IP的变化:第一次变化:0017--0020

第二、三、四次跳变相同:0037--0020

共调用了四次FACT函数 IP跳转可用如下图表示:

FACT 主程序 观察堆栈情况:

与书中P165页情况相符合

3阶阶乘堆栈示意图

第三题

编写一个通用多字节数相加的宏定义,并调用它实现多字节数的加法,注意观察汇编时宏调用被展开的情况。

a) 实验原理

多字节数的加法就是一个迭代过程。运用调用多字节相加的宏定义,可以很简单的实现加法。宏定义中运用间接寻址,用进位标志记录每字节的进位,并在下一字节的加法中加上进位标志,以达到多字节数加法的运算效果。

b) 程序框图

c) 程序源代码

N EQU 4;定义多字节的字节数 ADDMB MACRO M1,M2,M MOV SI,OFFSET M1

MOV DI,OFFSET M2;读取数字的首地址 MOV CX,M CLC L1:

MOV AL,[DI]

ADC [SI],AL;当前位的两个数相加,存在M1的地址中 INC SI

INC DI;两个数的地址均自加1,取下一个数进行运算 LOOP L1 ENDM

DATAS SEGMENT

MB1 DB N DUP(01H) MB2 DB N DUP(01H)

DATAS ENDS

CODES SEGMENT

ASSUME CS:CODES,DS:DATAS START:

MOV AX,DATAS MOV DS,AX

ADDMB MB1,MB2,N;引用宏定义计算多直接数 MOV AH,4CH INT 21H CODES ENDS END START

运行结果:

宏展开

第四题

编写程序:屏幕显示“Password:”,随后从键盘读入字符串,并比较这个字符串与程序内部设定的字符串。若二者相同则显示“Hello!”,否则显示“Sorry!”,注意:要求键盘输入字符不能直接回显在显示器上,而要用*号代替。

a) 实验原理

该程序运用了中断程序INT完成了密码程序的输入与输出,首先把首次输入的密码和第二次确认的密码分别存在PASSWORD1与PASSWORD2 中,并用A与B记录PASSWORD1与PASSWORD2的长度,之后用COMPARE判断两次输入是否相同,并用A与B中比较小的与C比较判断是否结束循环,按照对照结果选择输出。

b) 程序框图

不带回显输入字符,保存为password2 显示*号 不带回显输入字符,保存为password1 显示*号 开始 显示” Please input the password:” N 回车? Y 显示” Please confirm the password:”

N 回车?

N Y 比较两次输入长度并取较小长度 小于较小长度 Y Y 比较? N 显示”Sorry!” 显示”Hello!”

c) 程序源代码 CRLF MACRO MOV AH,02H MOV DL,0DH INT 21H

MOV AH,02H MOV DL,0AH INT 21H ENDM

DATA SEGMENT

PASSWORD1 DB 'chang';密码设置 PASSWORD2 DB 20 DUP(?) A DB 0;标记password1的长度 B DB 0;标记password2的长度 D DB 0;标记比较的次数

STRING1 DB 'Please input the password:',0DH,0AH,\;单引号双引号分析;最多20个字

STRING2 DB 'Please confirm the password:',0DH,0AH,'$';

STRING4 DB 'HELLO!THE PASSWORD IS RIGHT',0DH,0AH,'$'; STRING5 DB 'SORRY!THE PASSWORD IS WRONG',0DH,0AH,'$'; DATA ENDS

CODE SEGMENT

ASSUME DS:DATA,CS:CODE START:

MOV AX,DATA MOV DS,AX MOV AH,09H

LEA DX,STRING1

INT 21H;读取string1的地址,用中断显示出来 MOV CX,20

LEA SI,PASSWORD1 INPUT1:

MOV AH,08H

INT 21H;读取password1的地址,用中断读取用户输入的密码并存入 CMP AL,0DH JZ NEXT1 MOV [SI],AL INC SI INC A

MOV DL,'*' MOV AH,02H

INT 21H;用户每输入一个数字活字符,屏幕显示* LOOP INPUT1 NEXT1:

MOV AL,'$' MOV [SI],AL CRLF

MOV AH,09H

LEA DX,STRING2

INT 21H ;读取string2的地址,用中断显示出来 LEA SI,PASSWORD2 INPUT2:

MOV AH,08H

INT 21H;读取password2的地址,用中断读取用户输入的密码并存入 CMP AL,0DH JZ NEXT2 MOV [SI],AL INC SI INC B

MOV DL,'*' MOV AH,02H

INT 21H;用户每输入一个数字活字符,屏幕显示* LOOP INPUT2

NEXT2:

LEA SI,PASSWORD1 LEA DI,PASSWORD2 MOV AL,A CMP AL,B

JBE PANDUAN;比较A与B的大小 JMP COMPARE

PANDUAN:

MOV AL,A;取AB中较小的存到B中 MOV B,AL COMPARE:

MOV DL,[DI] CMP [SI],DL

JNE PASSERROR;比较,如果不相等则跳至error处 INC SI INC DI

INC D;记录比较次数 MOV AL,D

CMP AL,B;判断循环是否继续进行 JNZ COMPARE

ACCEPT:;确认密码成功 CRLF

MOV AH,09H

LEA DX,STRING4 INT 21H JMP EXIT

PASSERROR:;确认密码失败 CRLF

MOV AH,09H

LEA DX,STRING5 INT 21H JMP EXIT EXIT:;退出

MOV AH,4CH INT 21H CODE ENDS END START

运行输入:chang 时显示如下:

输入chanf时错误显示

3、实验中的问题:

第二次的实验是在上次实验的基础上,更加考验我们的编程素养,通过对问题的分析和画出解决问题的流程图,进而编写源代码。实验中多次遇到困难,特别是编译不能通过,在百度和同学的帮助下最终完成了实验。

本次实验主要考察对子程序和宏的设计以及调用的掌握程度,这与写单个程序不同,需要更多的知识来完善,让我们对子程序及宏调用的理解也更加清楚。

实验心得

通过这两次实验,让我基本上掌握的汇编语言常用的一些程序设计,以及子程序的调用和宏调用,汇编语言是接近于机器语言的一种编程语言,指令系统尤为重要但也比较繁琐,同样的功能,汇编语言的编程比较复杂难懂,但是由于最接近机器语言,可以很好地理解计算机是怎样一步一步实现程序功能的。

总之,在老师辛勤教导下,我们对汇编语言有了很深的认识和很好的掌握,谢谢老师!

参考文献

[1] 姚燕南等.微型计算机原理与接口技术.西安:西安电子科技大学.高等教育出版社出版.2008

[2]乔瑞萍、姚向华. .微型计算机原理与接口技术学习指导. 西安:西安电子科技大学.高等教育出版社出版.2009

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

Top