Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【汇编】微机原理与接口技术课程设计

【汇编】微机原理与接口技术课程设计

作者头像
zstar
发布于 2022-06-14 07:10:10
发布于 2022-06-14 07:10:10
1K00
代码可运行
举报
文章被收录于专栏:往期博文往期博文
运行总次数:0
代码可运行

本文是微机原理与接口技术课程设计 完整的程序和实验报告可在此处下载:https://gitee.com/zstar1003/xdu-homework/tree/master/%E5%BE%AE%E6%9C%BA%E5%8E%9F%E7%90%86

一、题目要求

编写程序实现下列5项功能,通过从键盘输入1~5进行菜单式选择。 (1) 按数字键“1”,完成将字符串中的小写字母变换成大写字母。用户输入由英文大小写字母或数字0~9组成的字符串(以回车结束),变换后按下列格式在屏幕上显示:

<原字符串>:abcdgyt0092 <新字符串>:ABCDGYT0092 按任意键重做;按Esc键返回主菜单

(2) 按数字键“2”,完成在字符中找最大值。用户输入由英文大小写字母或数字0~9组成的字符串(以回车结束),找出最大值后按下列格式在屏幕上显示:

<原字符串>The maximum is <最大值>. 按任意键重做;按Esc键返回主菜单。

(3) 按数字键“3”,完成输入数据组的排序。用户输入一组十进制数值(小于255),然后变换成十六进制数,并按递增方式进行排序,按下列格式在屏幕上显示:

<原数值串> <新数值串> 按任意键重做;按Esc键返回主菜单。

(4) 按数字键“4”,完成时间的显示。在屏幕的右上角实时显示出时间HH:MM:SS。 按任意键重做;按Esc键返回主菜单。

(5) 按数字键“5”,结束程序的运行,返回操作系统。

二、实验环境

2.1 软件环境

操作系统:Windows10 编辑器:emu8086

2.2 硬件环境

CPU:i7-10750H RAM:32GB

三、问题分析

3.1 功能一分析

功能一要求完成字符串大小写的转换,同时需输出原字符串和处理后的字符串。对功能进行分解,需要完成以下几个子任务: (1) 键盘字符的读取和存储 (2) 异常输入的检测 (3) 字符串的显示 (4) 大小写的转换

3.2 功能二分析

功能二要求在字符中找最大值,同时需输出原字符串和字符中的最大值。对功能进行分解,需要完成以下几个子任务: (1) 键盘字符的读取和存储 (2) 异常输入的检测 (3) 字符串的显示 (4) 比较字符并记录字符最大值

3.3 功能三分析

功能三要求将输入的十进制数转换成十六进制数输出,并对这些数按递增方式进行排序输出。对功能进行分解,需要完成以下几个子任务: (1) 键盘字符的读取和存储 (2) 异常输入的检测 (3) 字符串的显示 (4) 十进制数转换成十六进制数 (5) 输入数据的递增排序

3.4 功能四分析

功能四要求将获取系统当前时间,并将该时间显示在屏幕的右上角。对功能进行分解,需要完成以下两个子任务: (1) 系统时间的获取 (2) 时间位置的确定

3.5 功能五分析

功能五要求结束程序的运行,返回操作系统。该功能实现较为简单,通过DOS的中断调用即可实现。

四、解决方法

4.1 整体设计和基本功能

4.1.1 实验整体设计

本实验采用的是交互式的程序设计,即初始化为一个菜单,可以根据用户的输入分别选择5项功能。同时,当每一项功能结束时,用户可以选择重新尝试或者返回主菜单。 具体的流程如下图所示:

4.1.2 获取用户的输入

总体流程中以及各个子任务中都需获取用户的输入并进行存储,这项功能的实现使用了DOS的中断调用。由于其需频繁使用,因此在程序中,将其封装成宏定义函数get_char,其功能是获取单个输入字符并存储在AL中。 相关代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get_char macro  
    MOV    AH,1  
    INT    21h  
endm  

4.1.3 异常输入的检测

在每次获取用户输入后,都需要对输入数据进行检测,若输入异常值则需要提示错误信息并使用户重新输入。 例如,在主菜单中,用户的输入只能为1-5,输入其他值会报错,该部分可由下面的代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CMP    AL,31h  
JB     main_input_error  
CMP    AL,35h  
JA     main_input_error  
JMP    select 

由于字符在计算机中使用ASCII码来进行存储。因此使用CMP指令,将输入字符的ASCII码和目标字符的ASCII码进行比较。其中31h为数字“1”的ASCII码,35h为数字“5”的ASCII码。若输入字符的ASCII码小于31h或大于35h,则跳转到错误提示代码块(main_input_error),否则进入选择代码块(select)。

4.1.4 字符串的显示

在程序中,提示字符串与处理结果的字符串都需要进行显示。由于这项功能也需要被频繁使用,因此在程序中将其封装为宏定义函数print_string,相关代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
print_string macro string  
    LEA    DX,string  
    MOV    AH,09h  
    INT    21h  
endm

该函数的传入参数为string,通过DOS的中断调用,可以在屏幕上显示出DS:DX地址处的字符串。

4.1.5 换行显示功能

在程序运行中,为了使显示界面更为美观,需要频繁使用换行显示的功能,因此在程序中也将其封装为宏定义函数,相关代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
print_line macro  
    MOV    AH,2      ;调用2号功能系统,将DL的内容显示到屏幕  
    MOV    DL,0DH    ;0DH是回车符的ASCIIINT    21h  
    MOV    AH,2  
    MOV    DL,0AH    ;0AH是换行符的ASCIIINT    21h  
endm   

换行的本质是打印出一串空行,这里通过显示回车符和换行符的方式实现换行这一效果。

4.2 功能一:字符串小写转大写

在问题分析中,明确了功能一需要完成以下四个子任务: (1) 键盘字符的读取和存储 (2) 异常输入的检测 (3) 字符串的显示 (4) 大小写的转换 其中,前三个子任务已经在宏定义中实现,因此本功能只要完成第四个任务。 考虑到字符在计算机中是以ASCII码的方式进行存储,而大小写字母之间的ASCII码相差20H,因此,只需将所有小写字母的ASCII码减去20H,即可转换成大写字母。 核心代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cmp_data:   
    ;CL用来记录剩余的处理字符数量,若CL无空值,直接跳出     
    CMP    CL,00h      
    JE     task1_finish  
    MOV    AL,[SI]  
    ;只有小写字母才进行转换,若不是小写字母直接输出  
    CMP    AL,61h  
    JB     cmp_data_finish  
    SUB    AL,20h    ;小写转大写:小写字母-20H  
      
cmp_data_finish:  
    ;[DI]用来存储处理后的字符数据  
    MOV    [DI],AL  
    INC    SI  
    DEC    CL ;处理完一个字符,CL-1   
    INC    DI   
    ;CL不为0,代表没处理完  
    JMP    cmp_data  

其中,CL用来记录剩余的处理字符数量,SI为原字符存储的变址索引,DI为处理后的字符存储的变址索引。 功能一的流程图如下所示:

4.3 功能二:在字符中找最大值

在问题分析中,明确了功能二需要完成以下四个子任务: (1) 键盘字符的读取和存储 (2) 异常输入的检测 (3) 字符串的显示 (4) 比较字符并记录字符最大值 其中,前三个子任务已经在宏定义中实现,因此本功能只要完成第四个任务。 本程序采用遍历的思路进行比较。在获取每个字符之后,通过源变址寄存器SI对原字符串进行遍历,比较每个字符的ASCII码,初始化最大值为第一个字符,若后面的存在字符比当前最大值大,则最大值替换为该字符。最后,对源字符串和目标字符结尾加入字符串结束标记“$”,调用宏定义函数进行输出。 比较过程的核心代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func_2_cmp_data:  
    ;假如已经遍历完毕则进行跳出      
    CMP    CL,00h      
    JE     func2_finish  
    MOV    AL,[SI]  
    MOV    AH,[DI]  
    ;假如AL>AH,进行跳转,将AL的值存入[DI],即最大值  
    CMP    AL,AH  
    JA     func_2_cmp_data_finish     ;JA:无符号大于则跳转  
    INC    SI  
    DEC    CL  
    JMP    func_2_cmp_data  

功能二的流程图如下所示:

4.4 功能三:输入数据组的排序

在问题分析中,明确了功能三需要完成以下五个子任务: (1) 键盘字符的读取和存储 (2) 异常输入的检测 (3) 字符串的显示 (4) 十进制数转换成十六进制数 (5) 输入数据的递增排序 其中,前三个子任务已经在宏定义中实现,因此本功能只要完成后两个任务。

4.4.1 十进制数转换成十六进制数

考虑到用户输入的数字在计算机内部存储为ASCII码,因此第一步必须将ASCII码转换成十进制数。数字“0”的ASCII码为30H,因此将输入的0-9的ASCII码-30H即可提取到对应的十进制数,也可以将0-9的ASCII码的高位清零,直接获得对应的十进制数。高位清零操作可以用当前数据和OFH取逻辑与来实现。 实际上,寄存器是以十六进制来进行数据的存储,因此当数字仅有一位时,十六进制和十进制完全一样。因此只需考虑多位数据的情况。这一功能中,不同的数据采用空格进行分隔,在检测到空格之前,每一个数据先进行存储,当存在下一位数据时,之间的数据*10再加上下一位数据,这样就实现了十进制数向十六进制数的转换。 相关代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MOV    DL,0   
MOV    DH,10    
task_3_real_store:  
    get_char  
    CMP    AL,0DH   ;判断是否按下回车键   
    JE     task3_next_step  
    CMP    AL,20H   ;判断是否按下空格键   
    JE     task3_save_num    
    ;小于0或大于9跳转报错  
    CMP    AL,30H ;30H为"0"ASCIIJB     task3_error_input  
    CMP    AL,39H ;39H为"9"ASCIIJA     task3_error_input   
    MOV    BH,0        
    ;这里首先需要将ASCII码转换成十进制数,0ASCII码为30H,因此可以用ASCII-30H或者将高位清零  
    AND    AL,0FH ;4位清零   
    MOV    BL,AL  
    MOV    AL,DL  
    MUL    DH     ;每一个高位*10  
    ADD    AX,BX  
    MOV    DL,AL   
    JMP    task_3_real_store 

4.4.2 输入数据的递增排序

为了将输入数据进行递增排序,本程序运用了双层循环的选择排序方法。 相关代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sort:   
    LEA    SI,string_task3_count  
    MOV    CL,[SI]  
    LEA    SI,string_task3       
;外循环  
fori:  
    LEA    DI,string_task3_count   
    MOV    CH,CL  
    MOV    DI,SI  
    INC    DI    
;内循环   
forj:  
    MOV    BL,[SI]      
    MOV    BH,[DI]  
    CMP    BL,BH                                     
    JBE    afterswap  
    MOV    [SI],BH  
    MOV    [DI],BL      
afterswap:  
    DEC    CH  
    INC    DI  
    CMP    CH,1  
    JA     forj   
    INC    SI  
    DEC    CL  
    CMP    CL,1                                 
    JA     fori  

第i轮外循环,BL指向原字符串第i个字符,外循环的次数由CH来确定。第j轮内循环,BH指向原字符串第j个字符,j初始值为i+1,内循环的次数由CL来确定。每一次内循环中,第i个字符分别与其后面的字符一一比较,若BL>BH,则进行两数交换。第一次外循环确定第一位最小值,第二次外循环确定第二位最小值,直到所有位置的最小都确定,从而实现递增排序。 功能三的流程图如下所示:

4.5 功能四:右上角显示系统时间

在问题分析中,明确了功能四需要完成以下两个子任务: (1) 系统时间的获取 (2) 时间位置的确定

4.5.1 系统时间的获取

本程序使用DOS中断INT 21H的2CH号功能来获取当前系统时间,小时值会存放在CH中,分值会存放在CL中,秒值会存放在DH中。 相关代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MOV AH,2Ch     ;CH=,CL=,DH=INT 21h   

4.5.2 时间位置的确定

本程序使用DOS中断INT 10H的2H号功能来设置光标显示在右上角。其中,DH代表行号,DL代表列号。 相关代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MOV DH,0  ;行号      
MOV DL,72  ;列号    
MOV BH,0    
MOV AH,2     
INT 10h   

4.6 功能五:结束程序的运行

本程序使用DOS中断INT 21H的4CH号功能来实现结束程序运行。 相关代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MOV AH, 4CH  
INT 21h  

五、遇到的问题及调试

5.1 问题一:代码冗长问题

在编程中,遇到重复的代码多次使用导致整体代码冗长的问题,例如字符获取、字符显示、换行等操作,需使用重复的代码。 解决方法:通过宏定义的方式将重复用到的代码进行封装,从而大大减小代码冗余量。

5.2 问题二:程序错误问题

在编写功能三的时候,初次运行时,递增后的字符和输入的字符不相同。 解决方法:通过调试,发现错误原因是在功能三中,使用了DL寄存输入的字符数据,而在中途使用换行语句时,调用了INT 21H的2号功能,导致DL发生变化。因此,在换行前后通过入栈出栈的方式来保护DL数值,从而使问题得到解决。

六、程序运行效果

下面是各个功能的运行效果截图。 6.1 功能一运行效果

6.2 功能二运行效果

6.3 功能三运行效果

6.4 功能四运行效果

七、完整程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.	DATAS SEGMENT     
2.	    ;此处输入数据段代码   
3.	    string_main db 'plase input the function number (1~5)$'  
4.	    tip DB 'please input string:','$'  
5.	    string_task2_result2 db 'The maximum is :$'  
6.	    string_error db 'Wrong number, please input again. $'  
7.	    string_task3_info db 'please input the DECimAL numbers:',0DH,0AH,'$'    
8.	    again_or_return db 'What do you want to do next" Main Menu or Redo"[ESC/any other key]: $'  
9.	    task1_info db 'Now, we are doing fuction 1: $'   
10.	    task2_info db 'Now, we are doing fuction 2: $'   
11.	    task3_info db 'Now, we are doing fuction 3: $'   
12.	    ; emu8086不支持dup(?) 因此用0来初始化  
13.	    string_task1 db 100 dup(0)  
14.	    string_task1_result db 100 dup(0)  
15.	    string_task2 db 100 dup(0)    
16.	    string_task2_result db 10 dup(0)       
17.	    string_task3 db 100 dup(0)   
18.	    string_task3_count db 10 dup(0)  
19.	    string_task3_result db 100 dup(0)             
20.	    hour db 0  
21.	    minute db 0  
22.	    second db 0  
23.	    time db "00:00:00$"    
24.	    len equ $-time  
25.	    num db 0     
26.	  
27.	DATAS ENDS  
28.	  
29.	STACKS SEGMENT  
30.	    TOP LABEL WORD  
31.	    ;此处输入堆栈段代码   
32.	    DW      100H    DUP(0)  
33.	STACKS ENDS           
34.	  
35.	;换行   
36.	print_line macro  
37.	    MOV    AH,2      ;调用2号功能系统,将DL的内容显示到屏幕  
38.	    MOV    DL,0DH    ;0DH是回车符的ASCII39.	    INT    21h  
40.	    MOV    AH,2  
41.	    MOV    DL,0AH    ;0AH是换行符的ASCII42.	    INT    21h  
43.	endm         
44.	  
45.	;调用DOS功能,该功能为显示DSDX地址处的字符     
46.	print_string macro string  
47.	    LEA    DX,string  
48.	    MOV    AH,09h  
49.	    INT    21h  
50.	endm    
51.	  
52.	;用来获取单个输入字符     
53.	get_char macro  
54.	    MOV    AH,1  
55.	    INT    21h  
56.	endm  
57.	            
58.	CODES SEGMENT  
59.	    ASSUME CS:CODES,DS:DATAS,SS:STACKS  
60.	START:  
61.	    MOV AX,DATAS  
62.	    MOV DS,AX       
63.	      
64.	menu:  
65.	    print_string string_main  
66.	    get_char     
67.	    ;只能输入1-5  
68.	    CMP    AL,31h  
69.	    JB     main_input_error  
70.	    CMP    AL,35h  
71.	    JA     main_input_error  
72.	    JMP    select  
73.	      
74.	main_input_error:  
75.	    print_line  
76.	    print_string string_error      
77.	    print_line  
78.	    JMP    menu      
79.	      
80.	select:      
81.	     CMP   AL,31h  
82.	     JE    Task1  
83.	     CMP   AL,32h  
84.	     JE    Task2  
85.	     CMP   AL,33h  
86.	     JE    Task3  
87.	     CMP   AL,34h  
88.	     JE    Task4  
89.	     CMP   AL,35h  
90.	     JE    Task5  
91.	   
92.	return_menu:  
93.	     print_line  
94.	     JMP    menu       
95.	  
96.	;任务一:实现小写转化成大写  
97.	Task1 PROC  
98.	    print_line   
99.	    print_line   
100.	    print_string task1_info  
101.	    print_line   
102.	    print_string tip  
103.	    LEA    SI,string_task1  
104.	    MOV    CL,00H;CL用来存储需要处理字符的数量,初始化置0             
105.	      
106.	restore_input:      
107.	    get_char  
108.	    MOV    BL,AL  ;BL用来存储输入的字符信息,保护数据  
109.	    ;假如当前字符输入是回车(0DH),则不进行存储,直接跳出  
110.	    CMP    AL,0DH  
111.	    JE     deal_first   
112.	    ;对空格字符进行存储,单独判断  
113.	    CMP    AL,20H ;20H为"空格"ASCII114.	    JE     real_store    
115.	    ;设置输入字符的范围,只能存储数字、大小写字母,否则报错       
116.	    CMP    AL,30H ;30H为"0"ASCII117.	    JB     input_error  
118.	    CMP    AL,39H ;39H为"9"ASCII119.	    JBE    real_store  
120.	    CMP    AL,41H ;41H为"A"ASCII121.	    JB     input_error  
122.	    CMP    AL,5AH ;5AH为"Z"ASCII123.	    JBE    real_store  
124.	    CMP    AL,61H ;61H为"a"ASCII125.	    JB     input_error      
126.	    CMP    AL,7AH ;7AH为"z"ASCII127.	    JBE    real_store      
128.	      
129.	;错误跳转信息,并重新提示输入    
130.	input_error:  
131.	    print_line  
132.	    print_string string_error  
133.	    print_line  
134.	    print_string tip  
135.	    LEA    SI,string_task1  
136.	    MOV    CL,00H;CL用来存储需要处理字符的数量,初始化置0    
137.	    JMP    restore_input  
138.	  
139.	;存储当前字符     
140.	real_store:       
141.	    MOV    AL,BL ;BL存储的字符重新赋值给AL  
142.	    MOV    [SI],AL ;AL存储的字符传输到[SI]进行存储  
143.	    INC    SI  
144.	    INC    CL  
145.	    INC    DI   
146.	    ;未检测到结束标志“回车”,返回上一步继续存储下一个字符  
147.	    JMP    restore_input  
148.	  
149.	;重新回到存储的首地址位置,对每一个字符进行处理      
150.	deal_first:      
151.	    LEA    SI,string_task1  
152.	    LEA    DI,string_task1_result  
153.	      
154.	cmp_data:   
155.	    ;CL用来记录剩余的处理字符数量,若CL无空值,直接跳出     
156.	    CMP    CL,00h      
157.	    JE     task1_finish  
158.	    MOV    AL,[SI]  
159.	    ;只有小写字母才进行转换,若不是小写字母直接输出  
160.	    CMP    AL,61h  
161.	    JB     cmp_data_finish  
162.	    SUB    AL,20h    ;小写转大写:小写字母-20H  
163.	      
164.	cmp_data_finish:  
165.	    ;[DI]用来存储处理后的字符数据  
166.	    MOV    [DI],AL  
167.	    INC    SI  
168.	    DEC    CL ;处理完一个字符,CL-1   
169.	    INC    DI   
170.	    ;CL不为0,代表没处理完  
171.	    JMP    cmp_data  
172.	      
173.	task1_finish:  
174.	    print_line   
175.	    ;为输入和输出字符串添加结束标志  
176.	    MOV    [SI],'$'      
177.	    MOV    [DI],'$'   
178.	    ;这里显示输入  
179.	    print_string string_task1  
180.	    print_line             
181.	    ;这里显示输出结果  
182.	    print_string string_task1_result  
183.	    print_line  
184.	      
185.	    ;判断返回菜单或者重试  
186.	    print_string again_or_return      
187.	    get_char  
188.	    CMP    AL,1BH   ;判断是否按下esc   
189.	    JE     return_menu    
190.	  
191.	    JMP    Task1     
192.	  
193.	Task1 ENDP  
194.	  
195.	;任务二:在字符中找最大值  
196.	Task2 PROC     
197.	    print_line   
198.	    print_line   
199.	    print_string task2_info  
200.	    print_line   
201.	    print_string tip  
202.	    LEA    SI,string_task2  
203.	    MOV    CL,00H;CL用来存储需要处理字符的数量,初始化置0   
204.	      
205.	task_2_restore_input:      
206.	    get_char  
207.	    MOV    BL,AL  ;BL用来存储输入的字符信息,保护数据  
208.	    ;假如当前字符输入是回车(0DH),则不进行存储,直接跳出  
209.	    CMP    AL,0DH  
210.	    JE     task2_dealfirst   
211.	      
212.	     ;设置输入字符的范围,只能存储数字、大小写字母,否则报错       
213.	    CMP    AL,30H ;30H为"0"ASCII214.	    JB     task2_input_error  
215.	    CMP    AL,39H ;39H为"9"ASCII216.	    JBE    task2_store  
217.	    CMP    AL,41H ;41H为"A"ASCII218.	    JB     task2_input_error  
219.	    CMP    AL,5AH ;5AH为"Z"ASCII220.	    JBE    task2_store  
221.	    CMP    AL,61H ;61H为"a"ASCII222.	    JB     task2_input_error      
223.	    CMP    AL,7AH ;7AH为"z"ASCII224.	    JBE    task2_store     
225.	              
226.	task2_store:  
227.	    MOV    AL,BL  
228.	    MOV    [SI],AL  
229.	    INC    SI  
230.	    INC    CL  
231.	    JMP    task_2_restore_input   
232.	   
233.	;错误跳转信息,并重新提示输入    
234.	task2_input_error:  
235.	    print_line  
236.	    print_string string_error  
237.	    print_line  
238.	    print_string tip   
239.	    JMP    Task2  
240.	      
241.	task2_dealfirst:      
242.	    LEA    SI,string_task2  
243.	    LEA    DI,string_task2_result      
244.	    MOV    AL,[SI]  
245.	    MOV    [DI],AL   ;[DI]用来存储输入的数据  
246.	    INC    SI  
247.	    DEC    CL  
248.	      
249.	;遍历比较      
250.	func_2_cmp_data:  
251.	    ;假如已经遍历完毕则进行跳出      
252.	    CMP    CL,00h      
253.	    JE     func2_finish  
254.	    MOV    AL,[SI]  
255.	    MOV    AH,[DI]  
256.	    ;假如AL>AH,进行跳转,将AL的值存入[DI],即最大值  
257.	    CMP    AL,AH  
258.	    JA     func_2_cmp_data_finish     ;JA:无符号大于则跳转  
259.	    INC    SI  
260.	    DEC    CL  
261.	    JMP    func_2_cmp_data  
262.	      
263.	func_2_cmp_data_finish:  
264.	    MOV    [DI],AL  
265.	    INC    SI  
266.	    DEC    CL  
267.	    JMP    func_2_cmp_data  
268.	      
269.	func2_finish:  
270.	    print_line  
271.	    MOV    [SI],'$'  
272.	    INC    DI      
273.	    MOV    [DI],'$'  
274.	    ;先输出原字符串     
275.	    print_string string_task2  
276.	    ;补一个空格进行分隔  
277.	    MOV    DL,20h  
278.	    MOV    AH,2  
279.	    INT    21H   
280.	    print_string string_task2_result2 ;the maximum is :$  
281.	    print_string string_task2_result  
282.	    print_line  
283.	      
284.	    ;判断返回菜单或者重试  
285.	    print_string again_or_return      
286.	    get_char  
287.	    CMP    AL,1BH   ;判断是否按下esc   
288.	    JE     return_menu   
289.	  
290.	    JMP    Task2    
291.	  
292.	Task2 ENDP  
293.	   
294.	;任务三:输入数据组的排序  
295.	Task3 PROC   
296.	    print_line   
297.	    print_line   
298.	    print_string task3_info  
299.	    print_line       
300.	    print_string string_task3_info     
301.	    LEA    SI,string_task3  
302.	    MOV    CL,0  
303.	    MOV    BH,0      
304.	    MOV    DI,0    
305.	        
306.	task3_store:      
307.	    MOV    DL,0   
308.	    MOV    DH,10    
309.	      
310.	task_3_real_store:  
311.	    get_char  
312.	    CMP    AL,0DH   ;判断是否按下回车键   
313.	    JE     task3_next_step  
314.	    CMP    AL,20H   ;判断是否按下空格键   
315.	    JE     task3_save_num    
316.	    ;小于0或大于9跳转报错  
317.	    CMP    AL,30H ;30H为"0"ASCII318.	    JB     task3_error_input  
319.	    CMP    AL,39H ;39H为"9"ASCII320.	    JA     task3_error_input   
321.	    MOV    BH,0        
322.	    ;这里首先需要将ASCII码转换成十进制数,0ASCII码为30H,因此可以用ASCII-30H或者将高位清零  
323.	    AND    AL,0FH ;4位清零   
324.	    MOV    BL,AL  
325.	    MOV    AL,DL  
326.	    MUL    DH     ;每一个高位*10  
327.	    ADD    AX,BX  
328.	    MOV    DL,AL   
329.	    JMP    task_3_real_store   
330.	      
331.	task3_error_input:   
332.	    print_line  
333.	    print_string string_error     
334.	    JMP    Task3  
335.	  
336.	;检测到空格则进行一次数值保存   
337.	task3_save_num:      
338.	    CMP    BH,0  
339.	    JNZ    task3_before_store  
340.	    MOV    [SI],DL  
341.	    INC    SI  
342.	    INC    CL    
343.	      
344.	task3_before_store:      
345.	    MOV    BH,1  
346.	    JMP    task3_store       
347.	  
348.	;输出回车之后      
349.	task3_next_step:  
350.	    ;注意,换行会改变DL数值,因此必须用堆栈保护DL,栈仅能对字节进行操作  
351.	    PUSH   DX   
352.	    print_line  
353.	    POP    DX  
354.	    MOV    [SI],DL   
355.	    INC    SI  
356.	    INC    CL  
357.	    LEA    DI,string_task3_count  
358.	    MOV    [DI],CL  
359.	  
360.	task3_finish:  
361.	    LEA    DI,string_task3_count  
362.	    MOV    CL,[DI]      
363.	          
364.	    LEA    DI,string_task3  
365.	    PUSH   DX   
366.	    print_line  
367.	    POP    DX  
368.	  
369.	;将十六进制数转换成ASCII码显示输出   
370.	task3_write:     
371.	    MOV    BH,[DI]  
372.	    MOV    DL,BH  
373.	    AND    DL,0F0H ;低位清零  
374.	    SHR    DL,4    ;逻辑右移,将DL右移4375.	    CMP    DL,0AH  
376.	    JGE    task3_writehighchar  
377.	    ADD    DL,30H  ;数值0-9要进行显示需转换成ASCII码,需+30H  
378.	    JMP    task3_writehigh    
379.	  
380.	;用来写当前十六进制数的高位      
381.	task3_writehighchar:  
382.	    ADD    DL,37H  ;数值A-F要进行显示需转换成ASCII码,需+37H     
383.	      
384.	task3_writehigh:  
385.	    MOV    AH,2  
386.	    INT    21H  
387.	    MOV    DL,BH  
388.	    AND    DL,00FH ;高位清零    
389.	    CMP    DL,0AH  
390.	    JGE    task3_writelowchar    ;JGE大于等于  
391.	    ADD    DL,30H  
392.	    JMP    task3_writelow   
393.	      
394.	;写当前十六进制数的低位      
395.	task3_writelowchar:  
396.	    ADD    DL,37H       
397.	        
398.	task3_writelow:   
399.	       
400.	    MOV    AH,2  
401.	    INT    21H     
402.	    ;每输出一个十六进制数在后面添加H标识  
403.	    MOV    DL,48H  
404.	    MOV    AH,2  
405.	    INT    21H     
406.	    ;每输出一个十六进制数显示空格进行分隔  
407.	    MOV    DL,20h  
408.	    MOV    AH,2  
409.	    INT    21H      
410.	       
411.	    INC    DI  
412.	    DEC    CL  
413.	    CMP    CL,0   ;CL记录剩余处理的字符数量,假如不为0,继续跳转运行  
414.	    JNE    task3_write  
415.	   
416.	;采用选择排序实现十六进制从小到大输出  
417.	;BL用来存储第i位,BH用来存储第i+1,i+2,i+3...位,每次外循环确定第i位最小值  
418.	sort:   
419.	    LEA    SI,string_task3_count  
420.	    MOV    CL,[SI]  
421.	    LEA    SI,string_task3     
422.	      
423.	;外循环  
424.	fori:  
425.	    LEA    DI,string_task3_count   
426.	    MOV    CH,CL  
427.	    MOV    DI,SI  
428.	    INC    DI    
429.	;内循环   
430.	forj:  
431.	    MOV    BL,[SI]      
432.	    MOV    BH,[DI]  
433.	    CMP    BL,BH                                     
434.	    JBE    afterswap  
435.	    MOV    [SI],BH  
436.	    MOV    [DI],BL      
437.	      
438.	afterswap:  
439.	    DEC    CH  
440.	    INC    DI  
441.	    CMP    CH,1  
442.	    JA     forj  
443.	      
444.	    INC    SI  
445.	    DEC    CL  
446.	    CMP    CL,1                                 
447.	    JA     fori  
448.	               
449.	task3_finish2:  
450.	    LEA    DI,string_task3_count  
451.	    MOV    CL,[DI]      
452.	    LEA    DI,string_task3  
453.	    PUSH   DX   
454.	    print_line  
455.	    POP    DX  
456.	      
457.	;输出排序后的结果      
458.	task3_write2:     
459.	    MOV    BH,[DI]  
460.	    MOV    DL,BH  
461.	    AND    DL,0F0H ;低位清零  
462.	    SHR    DL,4    ;逻辑右移,将DL右移4463.	    CMP    DL,0AH  
464.	    JGE    task3_writehighchar2  
465.	    ADD    DL,30H  ;数值0-9要进行显示需转换成ASCII码,需+30H  
466.	    JMP    task3_writehigh2    
467.	  
468.	task3_writehighchar2:  
469.	    ADD    DL,37H  ;数值A-F要进行显示需转换成ASCII码,需+37H     
470.	      
471.	task3_writehigh2:  
472.	    MOV    AH,2  
473.	    INT    21H  
474.	    MOV    DL,BH  
475.	    AND    DL,00FH ;高位清零    
476.	    CMP    DL,0AH  
477.	    JGE    task3_writelowchar2    ;JGE大于等于  
478.	    ADD    DL,30H  
479.	    JMP    task3_writelow2   
480.	      
481.	;写当前十六进制数的低位      
482.	task3_writelowchar2:  
483.	    ADD    DL,37H       
484.	        
485.	task3_writelow2:    
486.	    MOV    AH,2  
487.	    INT    21H      
488.	    ;每输出一个十六进制数在后面添加H标识  
489.	    MOV    DL,48H  
490.	    MOV    AH,2  
491.	    INT    21H     
492.	    ;每输出一个十六进制数显示空格进行分隔  
493.	    MOV    DL,20h  
494.	    MOV    AH,2  
495.	    INT    21H          
496.	    INC    DI  
497.	    DEC    CL  
498.	    CMP    CL,0             ;CL记录剩余处理的字符数量,假如不为0,继续跳转运行  
499.	    JNE    task3_write2     
500.	       
501.	    PUSH   DX   
502.	    print_line  
503.	    POP    DX   
504.	    ;判断返回菜单或者重试  
505.	    print_string again_or_return      
506.	    get_char  
507.	    CMP    AL,1BH   ;判断是否按下esc   
508.	    JE     return_menu   
509.	  
510.	    JMP    Task3   
511.	               
512.	Task3 ENDP  
513.	  
514.	  
515.	;任务四:输出系统时间到屏幕右上角  
516.	Task4 PROC     
517.	;首先对窗口清屏      
518.	clear:      
519.	    MOV AX,CS  
520.	    MOV SS,AX  
521.	    MOV SP,0x7c00  ;set stack and SP  
522.	  
523.	    MOV AH,0x06  
524.	    MOV AL,0  
525.	  
526.	    MOV CH,0  ;(0,0)  
527.	    MOV CL,0  
528.	    MOV DH,24  ;(24,79)  
529.	    MOV DL,79  
530.	    MOV BH,0x07 ;黑底白字  
531.	    INT 0x10  
532.	  
533.	;设置光标位置   
534.	setshow:      
535.	    MOV DH,0  ;行号      
536.	    MOV DL,72  ;列号    
537.	    MOV BH,0  
538.	    ;置光标位置  
539.	    MOV AH,2     
540.	    INT 10h     
541.	  
542.	;获取系统时间  
543.	get_system_time:   
544.	    ;获取时间  
545.	    MOV AH,2Ch     ;CH=,CL=,DH=546.	    INT 21h           
547.	    MOV hour,CH  
548.	    MOV minute,CL  
549.	    MOV second,DH      
550.	    ;时间显示到字符串  
551.	    MOV AX,0        
552.	    MOV AL,hour     ;:AL,余数:AH  
553.	    MOV num,10  
554.	    DIV num  
555.	    ADD AL,30h  
556.	    MOV time[0],AL  
557.	    ADD AH,30h  
558.	    MOV time[1],AH   
559.	      
560.	    MOV AX,0  
561.	    MOV AL,minute  
562.	    MOV num,10  
563.	    DIV num  
564.	    ADD AL,30h  
565.	    MOV time[3],AL  
566.	    ADD AH,30h  
567.	    MOV time[4],AH  
568.	      
569.	    MOV AX,0  
570.	    MOV AL,second  
571.	    MOV num,10  
572.	    DIV num  
573.	    ADD AL,30h  
574.	    MOV time[6],AL  
575.	    ADD AH,30h  
576.	    MOV time[7],AH  
577.	      
578.	    ;输出系统时间  
579.	    LEA DX, time  
580.	    MOV AH, 9     
581.	    INT 21h    
582.	  
583.	    ;判断返回菜单或者重试  
584.	    print_string again_or_return      
585.	    get_char  
586.	    CMP    AL,1BH   ;判断是否按下esc   
587.	    JE     return_menu   
588.	  
589.	    JMP    setshow   
590.	  
591.	Task4 ENDP  
592.	   
593.	   
594.	;任务五:退出   
595.	Task5 PROC  
596.	    MOV AH, 4CH  
597.	    INT 21h  
598.	Task5 ENDP      
599.	      
600.	CODES ENDS  
601.	    END START  
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入理解MySQL触发器
触发器(trigger)是数据库中的一个很重要的、很实用的基于事件的处理器,在处理一些业务需求的时候,使用触发器会很方便。似乎在《高性能MySQL》中,对触发器作了一定的描述,也提到使用中的一些优势和局限性,但感觉还是不能完全理解触发器的全部功能和实现。于是自己在网上看了一些文章,结合官网(https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html)中的案例,写下这篇总结。
星哥玩云
2022/08/18
8400
深入理解MySQL触发器
《MySQL核心知识》第12章:触发器
今天是《MySQL核心知识》专栏的第12章,今天为大家系统的讲讲MySQL中的触发器,希望通过本章节的学习,小伙伴们能够举一反三,彻底掌握MySQL中的触发器知识。好了,开始今天的正题吧。
冰河
2022/12/01
4120
《MySQL核心知识》第12章:触发器
mysql触发器的作用及语法 转
触发器是一种特殊的存储过程,它在插入,删除或改动特定表中的数据时触发运行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。
双面人
2019/04/10
3.6K0
MySQL触发器介绍
在学习 MySQL 的过程中,可能你了解过触发器的概念,不清楚各位是否有详细的去学习过触发器,最近看了几篇关于触发器的文档,分享下 MySQL 触发器相关知识。
MySQL技术
2021/08/24
4K0
Mysql之存储过程(下)
存储过程是由一组 SQL 语句构成的数据库对象,存储过程可以被存储在数据库中并在需要时执行。它支持控制流结构(如 IF 语句、CASE 语句、循环等),能够封装和重用数据库操作,提升代码的模块化和可维护性。
猫咪-9527
2025/04/29
1460
Mysql之存储过程(下)
MySQL存储过程、函数、视图、触发器、索引和锁的基本知识
视图存储了查询,当调用的时候会生成查询语句对应的结果集,一个视图可以看成是一个虚拟的表。
青山师
2023/05/05
1.2K0
MY SQL存储过程、游标、触发器--Java学习网
大多数SQL语句都是针对一个或多个表的单条语句。并非所有的操作都怎么简单。经常会有一个完整的操作需要多条才能完成
用户1289394
2021/05/31
1.9K0
数据库(七)
视图是由一张表或多张表的查询结果构成的一张虚拟表,建立一张视图后会在数据库中保留一个以 frm 后缀结尾的文件,只保留了数据结果,所有的数据都来自 sql 语句。
py3study
2020/01/20
8530
MariaDB 视图与触发器
数据库中的视图是一个虚拟表,同真实的表一样,视图包含一系列带有名称的行和列数据,行和列数据来自由定义视图查询所引用的表,并且在引用视图时动态生成,视图是从一个或者多个表中导出的,视图的行为与表非常相似,但视图是一个虚拟表.在视图中用户可以使用SELECT语句查询数据,以及使用INSERT、UPDATE和DELETE修改记录,视图可以使用户操作方便,而且可以保障数据库系统的安全.
王 瑞
2022/12/28
1.3K0
数据库中的存储过程、游标、触发器与常用的内置函数
(1)after insert 触发器,在插入数据之后获得@id变量以显示最新的自增长ID
用户10175992
2022/11/21
1.5K0
MySQL 视图/存储过程/触发器
视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
用户9615083
2022/12/25
2.7K0
MySQL 视图/存储过程/触发器
MySQL基础-变量/流程控制/游标/触发器
在MySQL数据库的存储过程和函数中,可以使用变量来存储查询或计算的中间结果数据,或者输出最终的结果数据
用户9645905
2023/04/02
1.6K0
MySQL基础-变量/流程控制/游标/触发器
MySQL存储过程,视图,用户管理
一张虚拟表,就是将一个经常被使用的查询作为一个虚拟表,开发者查询的时候不需要再次书写SQL,而是直接调用对应的视图就可,调用视图以后MySQL会执行这个查询SQL。
石的三次方
2021/01/05
9770
MySQL 进阶之存储过程/存储函数/触发器
上面给大家演示了存储过程中的基本语法,现在只是在存储过程中定义了一条简单的select 语句 ,并没有任何逻辑。
叫我阿杰好了
2022/11/07
2.5K0
MySQL 进阶之存储过程/存储函数/触发器
SQL视图、存储过程、触发器
视图(view)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。
海盗船长
2023/10/11
4310
盘点MySQL数据库的数据类型、库和表常见操作、索引、视图、函数等知识点
在日常开发中,存储数据的最常用的方式便是数据库了,其中最为著名的便是MySQL数据库,因它简便易于上手而且可扩展性强大,跨平台使得它广为使用。上一篇文章,我们讲到了它的安装,今天我们就来具体聊聊它的这篇文章分为11个部分,分别包括MySQL数据库的数据类型、库和表常见操作、索引、视图、函数、游标、触发器、存储过程、事务、备份与还原、用户账号、其它等知识点。
前端皮皮
2021/10/08
1.8K0
MySQL 进阶全套
《MySQL入门全套》讲的是MySQL的基本操作,禁不住大家的热情,所以进阶来了。这一篇讲的是进阶,会有一点难以理解,本节主要内容MySQL视图,存储过程,函数,事务,触发器,以及动态执行SQL。
测试小兵
2019/11/19
8740
MySql[二]
视图就是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需要使用[名称]即可获取结果集并可以将其当做代表来使用·
Wyc
2018/09/11
5120
mysql 存储过程返回更新前记录
在数据库管理中,有时候我们需要在执行更新操作后,能够获取到更新前的数据记录,以便进行数据对比或者回滚操作。MySQL的存储过程可以帮助我们实现这一需求。本文将深入浅出地讲解如何通过MySQL存储过程获取更新前的记录,并提供具体的代码示例。
Jimaks
2024/05/27
3100
MySQL技能完整学习列表8、触发器、视图和事务——1、触发器(Triggers)的使用——2、视图(Views)的创建和使用——3、事务(Transactions)的管理
MySQL的触发器(Triggers)是一种特殊类型的存储过程,它会在数据表上的特定操作(插入、更新或删除)发生时自动执行。触发器可以帮助我们实现数据的自动处理、验证和维护等任务。下面将详细说明MySQL触发器的使用方法,并提供具体的示例。
红目香薰
2023/12/01
6590
推荐阅读
相关推荐
深入理解MySQL触发器
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验