北邮微原软件实验三:代码转换程序设计
一.实验目的:
1.掌握几种最基本的代码转换方法;
2.运用子程序进行程序设计.二.实验内容:
1.从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来.
2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明.
3.对输入要有检错措施,以防止非法字符输入,并有适当的提示.
4.将整个程序分解为若干模块,分别用子程序实现.在报告中要给出模块层次图.
今天北京的空气可以炫耀
这种好日子能持续多久?
编程思路
用分模块的方法,分别把输入输出纠错都独立开来,主程序只顾大体流程,记录最小值。
完整代码
;---------------------------------- ;Exercise 3. ;Get arbitrary amount of 2-digit-decimal numbers, find out the smallest number, and print it to screen. ; Global variables: smallest_num[2], end_flag, current_num[2]. ; ; 1. Get input number. ; 2. Check if end_flag=1, if yes,jump to output. ; 3. Compare the current_num with the smallest_num, if current_num < smallest_num, set smallest_num=current_num ; 4. Repeat 1. ; 5. Output the smallest number, exit program. ; assume cs:codesg,ds:datasg,ss:stacksg Stacksg SEGMENT STACK 'STACK' DB 100H DUP(0) Stacksg ENDS datasg segment smallest_num db 9,9 end_flag db 0 current_num db 0,0 illegal_num_msg db 'ooooops,something wrong with your input. $' output_msg db 'The smallest number you input is: $' datasg ends codesg segment main proc initialize: sub ax,ax mov ax,datasg mov ds,ax get_input_num: call get_2digits_input cmp end_flag,1 jz output compare_10: mov al,current_num[0] cmp al,smallest_num[0] jb swap cmp al,smallest_num[0] jz compare_1 jmp get_input_num compare_1: mov al,current_num[1] cmp al,smallest_num[1] jb swap jmp get_input_num swap: mov al,current_num[0] mov smallest_num[0],al mov al,current_num[1] mov smallest_num[1],al jmp get_input_num output: call print_nl lea dx,output_msg call print_string mov al,smallest_num[0] call print_num mov al,smallest_num[1] call print_num call print_nl exit: mov ax,4c00H int 21H main endp ;-------------------------------------------- ; Process: get_2digits_input ; This process would get a 2-digit-decimal number input from DOS. ; This process requires 2 global variables: end_flag, current_num[2]. ; Input: null ; Output: a number(range 0-99 decimal) in current_num[2](global variable). If encounter a end_symbol, set end_flag to 1. ; 1. Initialize variables, set end_flag and current_num to 0. ; 2. Push registers into stack. ; 3. Get a char input. (input10) ; 4. Check if it is separate_symbol or end_symbol. If it is, end this process. (check_s,check_e) ; 5. Check if the input is legal(range '0' to '9'),and transform to number from ASCII. (check_legal) ; 6. Get another char input.(input1) ; 7. Check if it is separate_symbol or end_symbol. If it is, end this process. ,and check if the input is legal.(range '0' to '9') ; 8. If input legal,add to current_num directly. (add one) ; 9. Pop registers,return. (return) end_symbol EQU 'e' separate_symbol EQU ' ' get_2digits_input proc mov end_flag,0 mov current_num[0],0 mov current_num[1],0 push ax push bx push cx push dx input10: mov ah,01 int 21h check_s: cmp al,separate_symbol jnz check_e jmp return check_e: cmp al,end_symbol jnz check_legal mov end_flag,1 jmp return check_legal: call check_num add_tens: mov current_num[0],al input1: mov ah,01 int 21h check_s1: cmp al,separate_symbol jnz check_e1 jmp return check_e1: cmp al,end_symbol jnz check_legal1 mov end_flag,1 jmp return check_legal1: call check_num add_ones: mov current_num[1],al jmp input10 return: pop dx pop cx pop bx pop ax ;-----Debug------ ;call print_nl ;mov al,current_num[0] ;call print_num ;mov al,current_num[1] ;call print_num ;---------------- ret get_2digits_input endp ;-------------------------------------------- ; Process: check_num ; This is a sub-process of get_2digits_input ; input: al (ASCII) ; output: al (unsigned integer) check_num proc cmp al,'0'-1H jna illegal_num cmp al,'9'+1H jnb illegal_num sub al,'0'-0H ret illegal_num: push dx call print_nl lea dx,illegal_num_msg call print_string call print_nl mov al,0 pop dx ret check_num endp ;--------------------------- ;Process: print_num ;input: al = number ;output: a number char on screen. print_num proc push dx add al,'0'-0h mov ah,02h mov dl,al int 21h pop dx ret print_num endp ;--------------------------- ;Process: print_string ;input: DS:DX, set DS:DX to string address,and call this process. The string should end with '$' ;output: Screen. print_string proc mov ah,09h int 21h ret print_string endp ;--------------------------- ;Process: Print_nl ;input: Null. ;output: a newline on screen print_nl proc push dx mov ah,02h mov dl,0dh int 21h mov dl,0ah int 21h pop dx ret print_nl endp ;--------------------- ; Process: print_char ;input: DL,the ASCII of the char. ;output: a char on screen print_char proc mov ah,02h int 21h ret print_char endp codesg ends end main
实验结果
更优的方法
上面的代码里,是将输入的两位十进制数转换成8bits的二进制数进行存储和比较的,这样在转换和输出的时候,会遇到很多麻烦。
其实这种麻烦是可以避免的。因为数字的ASCII码也是从30H-39H从小到大排序的,我们可以直接记录输入的两位ASCII码,然后十进制按位比较,得出最小值,最后输出。整个过程无需进行十进制到二进制的转换。