【综合性汇编程序设计】—— 微机原理实验
综合性汇编程序设计
·
一、实验要求
- 计算S=1+2×3+3×4+4×5+…+N(N+1),直到N(N+1)项大于200为止。
分析如下:
- 构造一个循环结构,S = 1 + 2×3 + 3×4 + 4×5 + … + N(N + 1),逐项进行累加、判断,直到N(N + 1)项大于 200 为止,利用 LOOP 循环指令和比较整数指令 CMP;
- 计算结果显示主要是寄存器中十六进制数值转化为十进制显示在虚拟终端界面,用到的指令有传送指令 MOV、比较整数指令 CMP、无条件转移指令 JMP、除法指令 DIV、压入操作指令 PUSH、弹出操作指令 POP、加法指令 ADD 和输出一个字符的功能 INT 21H 指令。
- 求N!。N为键盘输入的不大于8的正整数。
分析如下:
- 从键盘输入一个不大于 8 的正整数,需要利用 DOS 功能调用的 INT 21H 指令来实现,并且判断输入的数值是否满足题目要求,给出异常显示提醒;
- 构造一个循环,N! = 1 × 2 × … × (N - 1) × N,N 是从键盘输入的数值,寄存器存储为十六进制,利用 LOOP 循环指令和比较整数指令 CMP,计算过程中注意区分输入数值为十进制,计算机识别为相应的 ASCII 码;
- 显示功能设计两部分,第一部分是字符串显示,一般调用 DOS 功能的 INT 21H 指令来实现,另外一部分是寄存器中十六进制数值转化为十进制显示在虚拟终端界面。
- 从键盘输入一行字符(以回车结束),并按字母、数字及其它字符分类计数,最后显示出这3个计数结果。
分析如下:
- 分支的极致运用,按照 ASCII 码从小到大进行比较;
- 用三个变量分别记录用户输入数字类型,字母类型和其它类型的个数。根据 ASCII 码判断类型,遍历完整个句子后调用十进制数输出子程序 dispdec 输出统计数字程序实现;
- 定义缓冲区:存放用户输入的句子,用 digit、letter、other 分别代表统计出的数字、字母、其它字符的个数,都初始化为 0。用 bx 指向用户输入句子的首地址,然后判断是
30H~39H
,则 digit 自增,还是41H~5AH
或61H~7AH
,则 letter 自增,否则 other 自增,然后 bx 自增,不断循环判断,循环次数为句子长度,即之前 cx = 用户输入句子的长度。最后输出结果。
- 编写一电子钟程序,在屏幕正中按以下格式显示:
YYYY年MM月DD日
HH:MM:SS
分析如下:
- 调用 DOS 操作系统模块10,输入时间的格式,输入的时间以字符串形式放在已定义的存储器缓冲区,继而调用子程序,将存放在存储器缓冲区的 ASCII 码,并将时分秒的值放置在寄存器;
- 调用延时1s的子程序,累加到存放秒值的寄存器中,并转换为十进制。在累加过程中不断对时分秒进行比较,秒分不能等于60,每60先置零然后在虚拟终端显示;
- 调用 DOS 功能的 INT 21H 指令来实现虚拟终端显示。
二、实验目的
- 综合多种汇编程序设计方法,掌握具有人机交互界面的较复杂的汇编应用程序的编写。
三、实验代码及实验结果
实验1
(1)实验代码:
DATA SEGMENT
STRING1 DB 'S= $'
DATA ENDS
CODE SEGMENT
START:
MOV AX,DATA
MOV DS,AX
MOV AX,2
MOV BX,AX
INC BX
MOV CX,15
MOV DX,1
FOR:
IMUL BL
CMP AL,200
JA OUTSIDE
ADD DX,AX
MOV AX,DX
MOV AX,BX
INC BX
LOOP FOR
OUTSIDE:
MOV AX,DX
PUSH AX
LEA DX,STRING1
MOV AH,09H
INT 21H
POP AX
CALL PRINT
MOV AX, 4C00H
INT 21H
CRLF:
PUSH AX
PUSH DX
MOV DL,0AH
MOV AH,2H
INT 21H
MOV DL,0DH
MOV AH,2H
INT 21H
POP DX
POP AX
RET
PRINT:
PUSH AX
MOV CX,0
MOV BX,10
DISP1:
MOV DX,0
DIV BX
PUSH DX
INC CX
OR AX,AX
JNE DISP1
DISP2:
MOV AH,2
POP DX
ADD DL, 30H
INT 21H
LOOP DISP2
POP AX
RET
CODE ENDS
END START
(2)实验结果:
实验2
(1)实验代码:
DATA SEGMENT
STRING0 DB 'PLEASE INPUT A NUMBER: $'
STRING1 DB 'INLEGAL CHARACTER! $'
STRING2 DB 'RESULT OF N! = $'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
LEA DX,STRING0
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
CALL CRLF
CMP AL,38H
JA INLEGAL
CMP AL,30H
JB INLEGAL
JE PART01
CMP AL,31H
JE PART01
SUB AL,30H
MOV CX,0
MOV CL,AL
DEC CL
MOV AX,1
MOV BX,2
MOV DX,0
MUL:
IMUL BX
MOV DX,AX
INC BX
LOOP MUL
PUSH DX
LEA DX,STRING2
MOV AH,09H
INT 21H
POP AX
CALL PRINT
TAIL:
MOV AX, 4C00H
INT 21H
PART01:
LEA DX,STRING2
MOV AH,09H
INT 21H
MOV AX,1
CALL PRINT
JMP TAIL
INLEGAL:
LEA DX,STRING1
MOV AH,09H
INT 21H
JMP TAIL
PRINT:
PUSH AX
MOV CX,0
MOV BX,10
DISP1:
MOV DX,0
DIV BX
PUSH DX
INC CX
OR AX,AX
JNE DISP1
DISP2:
MOV AH,2
POP DX
ADD DL,30H
INT 21H
LOOP DISP2
POP AX
RET
CRLF:
PUSH AX
PUSH DX
MOV DL,0AH
MOV AH,2H
INT 21H
MOV DL,0DH
MOV AH,2H
INT 21H
POP DX
POP AX
RET
ENDS
END START
(2)实验结果:
实验3
(1)实验代码:
DATA SEGMENT
STRING0 DB 'PLEASE INPUT A STRING: $'
STRING1 DB 'NUMBER OF ALPHABET: $'
STRING2 DB 'NUMBER OF NUMBER: $'
STRING3 DB 'NUMBER OF OTHER CHARACTER: $'
NUM_ALPH DB 0
NUM_NUM DB 0
NUM_CHAR DB 0
ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX, DATA
MOV DS, AX
LEA SI,NUM_ALPH
LEA DX,STRING0
MOV AH,09H
INT 21H
MOV CX,40
INPUT:
MOV AH,01H
INT 21H
CMP AL,0DH
JE PRINTF_NUM
CMP AL,48
JB ADD_CHAR
CMP AL,58
JB ADD_NUM
CMP AL,65
JB ADD_CHAR
CMP AL,91
JB ADD_ALPH
CMP AL,97
JB ADD_CHAR
CMP AL,123
JB ADD_ALPH
JMP ADD_CHAR
INSIDE:
LOOP INPUT
PRINTF_NUM:
CALL CRLF
CALL CRLF
LEA DX,STRING1
MOV AH,09H
INT 21H
MOV AL,[SI]
MOV AH,0
CALL PRINT
CALL CRLF
CALL CRLF
LEA DX,STRING2
MOV AH,09H
INT 21H
MOV AL,[SI+1]
MOV AH,0
CALL PRINT
CALL CRLF
CALL CRLF
LEA DX,STRING3
MOV AH,09H
INT 21H
MOV AL,[SI+2]
MOV AH,0
CALL PRINT
TAIL:
MOV AX, 4C00H
INT 21H
CRLF:
PUSH AX
PUSH DX
MOV DL,0AH
MOV AH,2H
INT 21H
MOV DL,0DH
MOV AH,2H
INT 21H
POP DX
POP AX
RET
PRINT:
PUSH AX
MOV CX,0
MOV BX,10
DISP1:
MOV DX,0
DIV BX
PUSH DX
INC CX
OR AX,AX
JNE DISP1
DISP2:
MOV AH,2
POP DX
ADD DL, 30H
INT 21H
LOOP DISP2
POP AX
RET
ADD_ALPH:
PUSH DX
MOV DL,[SI]
INC DL
MOV [SI],DL
POP DX
JMP INSIDE
ADD_NUM:
PUSH DX
MOV DL,[SI+1]
INC DL
MOV [SI+1],DL
POP DX
JMP INSIDE
ADD_CHAR:
PUSH DX
MOV DL,[SI+2]
INC DL
MOV [SI+2],DL
POP DX
JMP INSIDE
ENDS
END START
(2)实验结果:
实验4
(1)实验代码:
DATA SEGMENT
YEAR DW 0
MONTH DB 0
DAY DB 0
HOUR DB 0
MINUTE DB 0
SECOND DB 0
DATE DB '0000YEAR00MONTH00DAY$'
TIME DB '00:00:00$'
LEN EQU $-TIME
LEN EQU $-DATE
NUM DB 10
DATA ENDS
STACK SEGMENT
DW 128 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX
MOV ES,AX
BEGIN: CALL SETSHOW
CALL GET_SYSTEM_DATE
CALL SETSHOW1
CALL GET_SYSTEM_TIME
JMP BEGIN ;无线循环,不停获取到新的系统时间
GET_SYSTEM_DATE PROC ;获取系统日期
MOV AH,2AH
INT 21H
MOV YEAR,CX
MOV MONTH,DH
MOV DAY,DL
MOV AX,0
MOV BX,0
MOV AX,YEAR
MOV BL,100
DIV BL
MOV BH,AH
MOV AH,0
DIV NUM
ADD AL,30H
MOV DATE[0],AL
ADD AH,30H
MOV DATE[1],AH
MOV AX,0
MOV AL,BH
DIV NUM
ADD AL,30H
MOV DATE[2],AL
ADD AH,30H
MOV DATE[3],AH
MOV AX,0
MOV AL,MONTH
DIV NUM
ADD AL,30H
MOV DATE[8],AL
ADD AH,30H
MOV DATE[9],AH
MOV AX,0
MOV AL,DAY
DIV NUM
ADD AL,30H
MOV DATE[15],AL
ADD AH,30H
MOV DATE[16],AH
LEA DX,DATE
MOV AH,9
INT 21H
RET
GET_SYSTEM_DATE ENDP
GET_SYSTEM_TIME PROC ;获取系统时间
MOV AH,2CH
INT 21H
MOV HOUR,CH
MOV MINUTE,CL
MOV SECOND,DH
MOV AX,0
MOV AL,HOUR
DIV NUM
ADD AL,30H
MOV TIME[0],AL
ADD AH,30H
MOV TIME[1],AH
MOV AX,0
MOV AL,MINUTE
DIV NUM
ADD AL,30H
MOV TIME[3],AL
ADD AH,30H
MOV TIME[4],AH
MOV AX,0
MOV AL,SECOND
DIV NUM
ADD AL,30H
MOV TIME[6],AL
ADD AH,30H
MOV TIME[7],AH
LEA DX,TIME
MOV AH,9
INT 21H
RET
GET_SYSTEM_TIME ENDP
SETSHOW PROC ;设置光标位置
MOV DH,12 ;行号
MOV DL,29 ;列号
MOV BH,0
MOV AH,2
INT 10H
RET
SETSHOW ENDP
SETSHOW1 PROC ;设置光标位置
MOV DH,13
MOV DL,35
MOV BH,0
MOV AH,2
INT 10H
RET
SETSHOW1 ENDP
MOV AX,4CH
INT 21H
CODE ENDS
END START
(2)实验结果:
四、实验总结
通过本次实验,了解了与系统互动的操作,更加熟悉了顺序结构、循环结构、分支跳转结构和子程序等汇编程序的设计与应用,学到了更多的DOS功能调用,对各种汇编语言的使用也更加熟练。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献3条内容
所有评论(0)