微机软件实验习题与答案(完整版)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
微机原理软件实验
实验1 两个多位十进制数相加的实验
实验内容:将两个多位十进制数相加,要求加数和被加数均以ASCII码形式各自顺序存放以DATA1和DATA2为首的5个内存单元中(低位在前),结果送回DATA1处。
完整代码如下:
DATAS SEGMENT
;此处输入数据段代码
STRING1 DB'input the first number:','$'
STRING2 DB 13,10,'input the second number:','$'
STRING3 DB 13,10,'the output is:','$'
DATA1 DB 6 DUP(00H),'$'
DATA2 DB 6 DUP(00H),'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
LEA SI,DATA1
LEA DI,DATA2
L0:
LEA DX,STRING1;打印字符串STRING1
MOV AH,09
INT 21H
INPUT1: ;输入第一个数
MOV AH,01;输入字符至AL中
INT 21H
CMP AL,'/'
JE L1
MOV [SI],AL
INC SI
JMP INPUT1
L1:
LEA DX,STRING2;打印字符串STRING2
MOV AH,09
INT 21H
INPUT2: ;输入第二个数
MOV AH,01;输入字符至AL
INT 21H
CMP AL,'/'
JE L2
MOV [DI],AL
INC DI
JMP INPUT2
L2:
MOV SI,0
CLC;清空进位标志位CF
MOV CX,6
PLUSE: ;相加
;SUB DATA1[SI],30H
;SUB DATA2[SI],30H
;这里不能使用这两条指令,因为如果DATA1[5]=00H,00H-30H需要借位相减,使CF=1
MOV AL,DATA1[SI]
ADC AL,DATA2[SI]
AAA;加法调整指令,可使两个ASCII数直接相加
MOV DATA1[SI],AL;和赋给DATA1[SI]
INC SI
LOOP PLUSE
L3:
LEA DX,STRING3;打印字符串STRING3
MOV AH,09
INT 21H
MOV CX,6
MOV SI,6
SHOW:
DEC SI
CMP DATA1[SI],00H
JE SHOW
SHOW2:
MOV DL,DATA1[SI]
ADD DL,30H
MOV AH,02
INT 21H
CMP SI,0
JE L4
DEC SI
JMP SHOW2
L4: MOV AH,4CH
INT 21H
CODES ENDS
END START
运行结果如下:输入为低位在前,即输入1234和99999相加实际上是4321和99999相加(即:4321+99999=104320)
实验2 两个数相乘的实验(无符号数相乘)实验内容:实现十进制数的乘法。
要求被乘数和乘数均以ASCII码形式各自顺序存放在内存中,乘积在屏幕上显示出来。
完整代码如下:DATAS SEGMENT
;此处输入数据段代码
STRING1 DB'the output is:','$'
DATA1 DB 31H,32H,33H
DATA2 DB 35H,36H
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
MOV DL,10
MOV AL,DATA1[0];AL=31H
SUB AL,30H ;AL=01H
MUL DL;乘10 ;AL=10
ADD AL,DATA1[1];AL=10 +32H
SUB AL,30H ;AL=10 +32H-30H=12
MUL DL ;AL=120
ADD AL,DATA1[2];AL=120+33H
SUB AL,30H ;AL=120+33H-30H=123
MOV BL,AL ;BL=AL
;
MOV AL,DATA2[0];AL=35H
SUB AL,30H ;AL=5
MUL DL;乘10 ;AL=50
ADD AL,DATA2[1];AL=50+36H
SUB AL,30H ;AL=50+36H-30H=56
MUL BL ;AX=123x56=6888
SUB DX,DX;DX清零
MOV BX,1000
DIV BX;(DX,AX)/1000,商6在AX中,余数888在DX中PUSH DX
MOV DL,AL
ADD DL,30H
MOV AH,02 ;打印最高位6
INT 21H
POP DX
MOV AX,DX;888赋给AX
DIV BL;AX/100,商放在AL中,余数88放在AH中
MOV DL,AL
MOV CL,AH ;!!!这里千万不能把AH直接赋给AL,因为经过INT 21H 指令后AL,AH会改变
ADD DL,30H
MOV AH,02;打印第二位
INT 21H
MOV BL,10
MOV AL,CL
SUB AH,AH;清空AH
DIV BL;AX/10,商放在AL中,余数8放在AH中
MOV DL,AL
MOV CL,AH
ADD DL,30H
MOV AH,02;打印第三位
INT 21H
ADD DL,30H
MOV AH,02;打印第四位
INT 21H
CODES ENDS
END START
运行结果为:
实验3 字符串匹配实验
实验内容:编写程序实现两个字符串比较。
如果相同,则屏幕显示“match”,否则屏幕显示”nomatch”,完整代码如下:
DATAS SEGMENT
;此处输入数据段代码
PRINT1 DB'input the first string:','$'
PRINT2 DB 13,10,'input the second string:','$'
PRINT3 DB'match','$'
PRINT4 DB'nomatch','$'
PRINT5 DB 13,10,'output: ','$'
STRING1 DB 30 DUP(00H),13,10,'$'
STRING2 DB 30 DUP(00H),13,10,'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:DATAS START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
LEA DX,PRINT1;打印字符串PRINT1
MOV AH,09
INT 21H
LEA SI,STRING1;STRING1地址赋给SI
LEA DI,STRING2;STRING2地址赋给DI
INPUT1:
MOV AH,01;输入字符至AL
INT 21H
CMP AL,'/';输入字符串以‘/’结束,转L0 JE L0
MOV [SI],AL
INC SI
JMP INPUT1
L0:
LEA DX,PRINT2;打印字符串PRINT2
MOV AH,09
INT 21H
INPUT2:
MOV AH,01; 输入字符至AL
INT 21H
CMP AL,'/'
JE L1
MOV [DI],AL
INC DI
JMP INPUT2
L1: MOV CX,30 ;CX=30代表比较30次
MOV SI,00H
COMPARE:;字符串一个一个比较
MOV AL,STRING1[SI];取STRING1存储单位中的第SI个字符赋给AL CMP AL,STRING2[SI];AL与STRING2存储单位中的第SI个字符比较 JNE NOMATCH
INC SI
LOOP COMPARE
JMP MATCH
NOMATCH:;打印output:nomatch
LEA DX,PRINT5
MOV AH,09
INT 21H
LEA DX,PRINT4
MOV AH,09
INT 21H
JMP L2
MATCH:;打印output:match
LEA DX,PRINT5
MOV AH,09
INT 21H
LEA DX,PRINT3
MOV AH,09
INT 21H
L2: MOV AH,4CH
INT 21H
CODES ENDS
END START 运行结果:
实验4 从键盘输入数据并显示的实验实验内容:将键盘输入的2位十六进制数转换为等值的二进制数,并在屏幕上显示。
列如:键入f2,则显示.完整代码如下:
DATAS SEGMENT
;此处输入数据段代码
STRING1 DB'please input a string:','$'
STRING2 DB 13,10,'the output is:','$'
STRING3 DB 13,10,'input error',13,10,'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
L0: LEA DX,STRING1;打印字符串STRING1 MOV AH,09
INT 21H
MOV AH,01;输入第一个字符至AL中
INT 21H
CMP AL,'0'
JB ERROR1
CMP AL,'9'
JBE ENTER1
CMP AL,'A'
JB ERROR1
CMP AL,'F'
JBE ENTER1
CMP AL,'a'
JB ERROR1
CMP AL,'f'
JBE ENTER1
ERROR1:
LEA DX,STRING3;打印字符串STRING3
MOV AH,09
INT 21H
JMP L0
ENTER1:
CALL ASC2BCD;把ASCII码转化成十进制数BCD码MOV CL,4
ROL AL,CL
MOV BL,AL;把高四位放到BL寄存器中
;输入第二个字符
MOV AH,01;输入第二个字符至AL中
INT 21H
CMP AL,'0'
JB ERROR1
CMP AL,'9'
JBE ENTER2
CMP AL,'A'
JB ERROR1
CMP AL,'F'
JBE ENTER2
CMP AL,'a'
JB ERROR1
CMP AL,'f'
JBE ENTER2
ENTER2:
CALL ASC2BCD;把ASCII码转化成十进制数BCD码ADD BL,AL
LEA DX,STRING2;打印字符串STRING2
MOV AH,09
INT 21H
MOV CX,9
CLC;清空标志位
SHOW: ;显示BL中的二进制数
DEC CX
CMP CX,0
JE NEXT ;输出完八位之后返回DOS
ROL BL,1 ;循环左移一位,若溢出为1,则CF=1 JC M1
JMP M2
M1: MOV DL,'1';若CF=1,转至M1打印‘1’MOV AH,02
INT 21H
JMP SHOW
M2: MOV DL,'0';若CF=0,转至M1打印‘0’MOV AH,02
INT 21H
JMP SHOW
NEXT:
MOV AH,4CH
INT 21H
ASC2BCD PROC
CMP AL,'9'
JBE L1 ;若AL≤9,转L1
SUB AL,07H ;若输入的数为A~F,或者a~f,则减7,A接在39H后面,A~F=3AH~3FH,a~f=5AH~5FH
L1: SUB AL,30H ;减30H
AND AL,0FH ;滤除高位,保留低位,因为a~f恰好比A~F大20H,这样a~f就和A~F的数值一样了
RET
ASC2BCD ENDP
CODES ENDS
END START
输出结果为:(若输出不在0~9,A~F,a~f内,则重新输入)
实验5 字符和数据计算的实验
实验内容:先在屏幕上显示“input string,”,输入字符串; 再显示“result=”。
如为0~9的数字,则计数器加1,如为非数字,则直接显示,但不计数。
完整代码如下:
DATAS SEGMENT
;此处输入数据段代码
STRING1 DB'input string:','$'
STRING2 DB 13,10,'result=','$'
STRING3 DB 13,10,'zifu:','$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
LEA DX,STRING1;打印字符串1
MOV AH,09
INT 21H
MOV CX,0
MOV BX,0
INPUT:
MOV AH,01;输入字符至AL
INT 21H
CMP AL,'/';输入/后转L0
JE L0
CMP AL,'0';下溢出转RUZHAN
JB RUZHAN
CMP AL,'9';上溢出转RUZHAN
JA RUZHAN
INC CL ;若为数字则计数器+1
JMP INPUT
RUZHAN:;非数字字符入栈
PUSH AX
ADD BL,1 ;BL代表入栈的字符个数,方便待会输出 JMP INPUT
L0:
LEA DX,STRING3;打印字符串3
MOV AH,09
INT 21H
CHUZHAN:
POP AX
MOV DX,AX
MOV AH,02
INT 21H
SUB BL,1
CMP BL,0 ;入了多少个栈,出多少栈 JNE CHUZHAN
OUTPUT:;输出数字的个数
LEA DX,STRING2;打印字符串2
MOV AH,09
INT 21H
MOV DL,CL
ADD DL,30H
MOV AH,02
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START
输出结果为:(这里非数字字符输出顺序与输入顺序相反)
实验6 改变年月日的实验
实验内容:先在屏幕上显示“what is the date(mm/dd/yy)“从键盘输入的月日年能把计算机的系统日期改为你键入的值。
完整代码如下:
DATAS SEGMENT
S1 DB 0AH,0DH,"what is the date(mm/dd/yy):",'$'
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV DX,OFFSET S1
MOV AH,09H;打印字符串"what is the date(mm/dd/yy):" INT 21H
MOV DX,0H;DX=CH=0
MOV CH,0
;MOV SI,0AH
KAISHI:
MOV CL,0;用来压缩移位
SHURU:
MOV AH,01H;输入字符存入AL中
INT 21H
MOV AH,0AH;10赋给AH
CMP AL,0DH;AL=13则结束,设置日期
JE GENGGAI
CMP AL,'/';计算来判断是年,月,日
JE ZIZENG
CMP CH,0;等于0则转月
JE YUE
CMP CH,1;等于1则转日
JE RI
CMP CH,2;等于2则转年
JE NIAN
ZIZENG:INC CH
JMP SHURU;无条件转移至SHURU YUE:
ADD DH,AL
CMP CL,0
JNZ KAISHI
INC CL
MOV AL,DH
MUL AH
MOV DH,AL
JMP SHURU;无条件转移至SHURU RI:
CMP CL,0
JNZ KAISHI
INC CL
MOV AL,DL
MUL AH
MOV DL,AL
JMP SHURU;无条件转移至SHURU NIAN:
CMP CL,0
JNZ XIABU
ADD BL,AL
MOV CL,03H;3赋给CL
JMP SHURU;无条件转移至SHURU XIABU:
MOV AH,0;清空AH
MOV SI,BX;SI=BX
SHL BX,CL;BX左移三位,乘以8
SHL SI,1;SI左移一位,乘以2
ADD BX,SI;两个相加,即乘以10
ADD BX,AX;BX加上新输入的数字
JMP SHURU
GENGGAI:
MOV CX,BX
MOV AH,2BH;设置日期
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START
输出结果为:(设置2008年12月3日,注意如果要设置好系统,否则可能计算机的日期改变不了)
实验7 将小写字母转换为大写字母的实验
实验内容:接收键入字符(以Ctrl-c为结束),将小写字母变为大写字母,并在屏幕上显示。
完整代码如下:
DATAS SEGMENT
;此处输入数据段代码
STRING1 DB 13,10,'please input a string:','$'
STRING2 DB 13,10,' the output string is:','$'
DATA DB 100 DUP(00H),'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
M: LEA SI,DATA
LEA DX,STRING1;打印字符串1
MOV AH,09
INT 21H
INPUT:
MOV AH,01;输入字符C
INT 21H
CMP AL,03H
JE OUTPUT
CMP AL,'a'
JB M
CMP AL,'z'
JA M
SUB AL,20H ;减20H变小写
MOV [SI],AL
INC SI
JMP INPUT
OUTPUT:
LEA DX,STRING2;打印字符串2
MOV AH,09
INT 21H
LEA SI,DATA
L1:
MOV DL,[SI]
CMP DL,00H
JE ENDING
MOV AH,02
INT 21H
INC SI
JMP L1
ENDING:
MOV AH,4CH
INT 21H
CODES ENDS
END START
运行结果为:(如果输入的不在a~f中,则重新输入)
实验8 排序实验(0~9)
实验内容:从首地址为1000H开始存放10个数,将这些数按降序排列.
完整代码如下:
DATAS SEGMENT
;此处输入数据段代码
STRING1 DB'please input 10 numbers:','$'
STRING2 DB 13,10,' the sorted numbers are:','$' ORG 1000H
DATA DB 10 DUP(00H),'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
LEA DX,STRING1;输入提示语'plese input 10 numbers:' MOV AH,09
INT 21H
MOV CX,10
LEA SI,DATA
INPUT:
MOV AH,01;输入字符至AL
INT 21H
MOV [SI],AL;把AL赋给偏移地址为SI指向的单元
INC SI
LOOP INPUT
MOV BL,0
L0: MOV CX,9
LEA SI,DATA
L1: ;比较第SI个数和第SI+1个数的大小
MOV AL,[SI]
INC SI
CMP AL,[SI]
JB CHANGE ;若小于则转CHANGE
L2: LOOP L1 ;小循环(CX自动减1),若CX=0则结束
L3: INC BL
CMP BL,10
JB L0 ;若大循环有10次了,则转OUTPUT
JMP OUTPUT
CHANGE:;交换两个数
XCHG AL,[SI];交换,
MOV [SI-1],AL;赋给SI-1
JMP L2
OUTPUT:
LEA DX,STRING2;输入提示语' the sorted numbers are:' MOV AH,09
INT 21H
MOV CX,10
LEA SI,DATA
L4:;循环输出
MOV DL,[SI]
MOV AH,02
INT 21H
INC SI
LOOP L4
MOV AH,4CH
INT 21H
CODES ENDS
END START
输出结果为:
实验8 排序实验(多位数排序)
实验内容:从首地址为1000H开始存放10个数,将这些数按降序排列.
完整代码如下:
DATA SEGMENT;CHANGE函数DI,SI为入口函数,交换SI,DI的值,SI,DI值已经大变
BUFFER DB 100
DB
DB 100 DUP()
DB"$"
ORG 1000H
N EQU 10
STOREDATA DB 110 DUP(30H) ;每个数最大为10位
TEMP1 DB 12 DUP(24H) ;中间变量
TEMP2 DB 12 DUP(24H) ;中间变量
TEMP3 DB 12 DUP(24H) ;中间变量
DATA ENDS
STACK SEGMENT PARA STACK
DW 60H DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME DS:DATA,CS:CODE,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
;MOV AX,STACK
;MOV SS,AX ;可以有可以无,因为其已经默认为SS了
MOV DX,OFFSET BUFFER
MOV AH,0AH
INT 21H
CALL TURNLINE
LEA SI,BUFFER
LEA DI,STOREDATA
CALL BUFFERTOSTORE
CALL TURNLINE
LEA SI,STOREDATA
CALL COMPARE
GO: MOV SI,OFFSET STOREDATA
MOV CL,110
PRINT:MOV DL,[SI]
JNE PRINT1
CMP AL,1
JE PRINT1 ;打印该有的0 INC SI
LOOP PRINT
PRINT1:
CMP DL,2CH
JE PRINT0
JIXU: MOV AH,02H
INT 21H
CMP DL,2CH
JNE GOON5
MOV AL,0
JMP GOON6
PRINT0:CMP AL,0
JNE JIXU
MOV DL,30H
MOV AH,02H
MOV DL,2CH
JMP JIXU
GOON5:MOV AL,1
GOON6:INC SI
LOOP PRINT
MOV AH,01H
INT 21H
MOV AH,4CH
INT 21H
COMPARE PROC ;以SI为入口传递MOV BX,SI
; LEA DI,TEMP2
;GETLAST:
; CALL TEMPSAVE
; INC DL
; CMP DL,N
; JE GOON1
; LEA DI,TEMP2
; JMP GETLAST ;TEMP2始终指向当前最后一个数;GOON1:
MOV CL,N
COMPARE1:
MOV SI,BX
LEA DI,TEMP1
CALL TEMPSAVE ;TEMP1指向第一个数,错啦,为什么呢,因为那样比不会进行变化
MOV SI,BX
MOV DH,1
LEA DI,TEMP1
PUSH SI
COMPARE2:
LODSB
MOV AH,[DI]
CMP AL,2CH
JE EQUAL
CMP AL,AH
JB BELOW
CMP AL,AH
JA ABOVE
INC DI
JMP COMPARE2
BELOW:
INC DH
POP SI
PUSH SI
LEA DI,TEMP1
CALL TEMPSAVE ;使TEMP1存入当前最小,因为TEMP1当前元已经存在了
;不可以再转存,否则出错
POP SI
ADD SI,N
INC SI
PUSH SI
CMP DH,CL
JA GOON2
LEA DI,TEMP1
JMP COMPARE2
EQUAL:
INC DH ;不交换
POP SI
ADD SI,N
INC SI
PUSH SI
CMP DH,CL
JA GOON2 ;比较CL次
LEA DI,TEMP1
JMP COMPARE2
ABOVE: ;TEMP1始终指向当前最小,若当前值大于时最小时前移
;此时TEMP1不便,只需前移就好,交换前后两个数的大小
INC DH
POP SI
PUSH SI
SUB SI,N
SUB SI,1
MOV DI,SI
POP SI
PUSH SI
CALL CHANGE
POP SI
ADD SI,N
INC SI
PUSH SI
CMP DH,CL
JA GOON2 ;比较CL次
LEA DI,TEMP1
JMP COMPARE2
GOON2:
LOOP COMPARE1
JMP GO
RET
COMPARE ENDP
;存储函数思路:从最后一位开始存,首位均置零,最高10位
BUFFERTOSTORE PROC
MOV CL,10
ADD SI,2
; SUB DI,3
STORE:
MOV AL,[SI]
CMP AL,2CH ;直到SI指向,(结束一个数),再进行存储 JE STORE2
INC SI
JMP STORE
STORE2:MOV BX,SI ;存储SI
STOREIN:
ADD DI,N
;ADD DI,3
MOV DX,DI ;存储DI
STOREIN1:
MOV AL,[SI]
MOV [DI],AL
DEC SI
LEA AX,BUFFER
ADD AX,1 ;注意边界要取好,因其也有值
CMP SI,AX
JE JMP1
MOV AL,[SI]
CMP AL,2CH
JE JMP1
JMP STOREIN1 ;条件控制循环
JMP1 :MOV SI,BX
INC SI ;进行存储下个数
INC DX ;使DI加1因为前几位已经用了
MOV DI,DX
LOOP STORE
;MOV AL,"$"
;INC DI
;MOV [DI],AL
RET
BUFFERTOSTORE ENDP
CHANGE PROC
PUSH SI
LEA DI,TEMP3
CALL TEMPSAVE ;TEMP3存放SI当前值
POP DI ;往SI存入值
POP SI
PUSH SI
CALL TEMPSAVE ;******把DI的值存入SI中
POP DI
LEA SI,TEMP3
CALL TEMPSAVE ;*******把SI的值存入DI中
RET
CHANGE ENDP
TEMPSAVE PROC ;存储中间变量的函数,以DI,SI,为入口,以,标志位结束
STEMP:LODSB
MOV [DI],AL
INC DI
CMP AL,2CH
JMP STEMP
NEXT:
RET
TEMPSAVE ENDP
TURNLINE PROC
MOV DL,0AH
MOV AH,02H
INT 21H
RET
TURNLINE ENDP CODE ENDS
END START
输出结果为:。