汇编语言:输入10个数排序并输出

    xiaoxiao2025-09-22  27

    文章目录

    一:题目描述二:伪指令的定义1.数据段2.堆栈段3.代码段 三:模块分解与实现1. DOS输入10个数字1.1 输入函数子程序 2.实现冒泡排序3.DOS输出到屏幕4.求累加和5.其他函数 四:流程图1. 总体流程图2. 子程序流程图2.1 Input2.2 Print2.3 Bubble_Sort2.4 Get_Sum 五:代码与运行截图1,完整版代码(在MASM运行通过)2. 正确运行时截图3. 错误输入时截图

    一:题目描述

    在键盘输入任意10个数

    按从小到大排序后,在计算机屏幕上先输出来。要有结果提示(字符串显示)。将10个数做累加,结果在计算机屏幕显示累加和。

    二:伪指令的定义

    1.数据段

    DATAS SEGMENT string_1 DB 'Please input a numbers(0-65536):','$' string_2 DB 'ERROR: OVERFLOW! Please input again:','$' string_3 DB 'The array you have input is:',0ah,0dh,'$' string_4 DB 'After Sort the num is:',0ah,0dh,'$' string_5 DB ' ','$' DATA DW 10 DUP(?) massege DB 'The sum of the array is: ',0ah,0DH,'$' DATAS ENDS

    说明:

    string_1输入范围提示string_2输入错误提示string_3输出原数组提示string_4输出排序后数组提示string_5空格符DATA缓冲区数组

    2.堆栈段

    STACKS SEGMENT DW 256 dup(?) STACKS ENDS

    3.代码段

    CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS

    三:模块分解与实现

    1. DOS输入10个数字

    输入10个无符号数存入缓冲区,并且保证 n u m < 65536 num < 65536 num<65536

    为何输入范围是65536呢 一个字的最大表示范围是 F F F F FFFF FFFF 其在十进制的表示下为 65535

    HEXFFFFDEC65535BIN1111 1111 1111 1111

    1.1 输入函数子程序

    ;---------输入函数(单数字输入)------------ Input PROC Near push AX push BX push CX push DX ;---------输入提示-------------- MOV BX, 0 CLC MOV DX, 0 ;----------输入数字-------------- Lp_0: MOV AH, 1 INT 21H CMP AL, 20H ;回车 JE L_CRLF ;----- x belong to [0,9] ---------- SUB AL, 30H ; ASCII -> int JL L_ERROR CMP AL, 9 JG L_ERROR ;------- string -> int ----------- MOV AH, 0 ;将 AL扩展成 AX XCHG AX, BX ;保护 AX值 MOV CX, 10 MUL CX ; bx *= 10 ADD AX , BX JC L_ERROR ; OVERFLOW处理 XCHG AX, BX JMP Lp_0 L_ERROR: MOV DX, 0 MOV BX, 0 CALL CRLF ; 换行 CALL ERROR ; 输出错误提示 JMP Lp_0 L_CRLF: ; 以换行作为一个数的结束标志 MOV DX, 0 MOV DATA[SI], BX ; POP DX POP CX POP BX POP AX RET Input ENDP

    解析函数功能:

    本质类似于高精度计算,将读入的一个串转成数字存储在DATA数组中

    分成三大部分

    一: 输入提示

    二: 错误判断及提示

    三: 转化为数字

    L_ERROR 错误处理

    L_CRLF 结束处理

    我们来举一个 1234 1234 1234 的例子

    Register1234AX1234BX0112123CX10101010

    A X + ( B X ∗ C X ) AX + (BX * CX) AX+(BXCX)

    最后将结果存储在DATA数组里

    2.实现冒泡排序

    冒泡排序作为一个简单的排序算法,时间复杂度 O ( n 2 ) O(n^2) O(n2) 需要两层循环,为了提高代码的可读性,我们将内层的循环写成一个子程序每次调用

    内层循环很简单,每次从头比到尾,遇到比它小的交换就可以了。因为是字操作数,所以循环的下标到18为结束条件。

    ;---------Bubble_sort-------------------- Bubble_sort PROC NEAR PUSH BX PUSH DX MOV SI,DI LOOP1: ADD SI,2 MOV BX,DATA[DI] CMP BX,DATA[SI] JA SWAP JMP NEXT SWAP: MOV DX,DATA[SI] MOV DATA[DI],DX MOV DATA[SI],BX NEXT: CMP SI,18 JL LOOP1 POP DX POP BX RET Bubble_sort ENDP

    外层调用:每次 D I + 2 DI + 2 DI+2

    ;----------Sort----------- MOV CX, 9 MOV DI, 0 FOR1: CALL Bubble_sort ADD DI, 2 LOOP FOR1

    3.DOS输出到屏幕

    CALL CRLF MOV DX, OFFSET string_4 ;'After Sort the num is:' MOV AH, 9 INT 21H MOV CX, 10 MOV DI, 0 FOR2: CALL Print CALL Space ADD DI , 2 LOOP FOR2 CALL CRLF

    输出DATA内的数字,每次输出一个数字然后在输出一个空格

    Print函数:

    利用DIV函数的特点——每次除10的商放在AX, 余数放入DX并利用栈的 FILO(First in Last Out)的特点

    依旧以1234的例子来看一下是怎么处理的

    DATA[Num]1234123121DX4321Stack(PUSH DX)44,34,3,24,3,2,1Print(POP DX)4342341234

    D A T A [ N u m ] / 10 DATA[Num] / 10 DATA[Num]/10 的余数存入DX

    Print PROC Near PUSH AX PUSH BX PUSH CX PUSH DX MOV CX, 0 MOV BX, 10 MOV AX, DATA[DI] LAST: MOV DX, 0 DIV BX ; DIV商放AX,余数放入DX PUSH DX INC CX CMP AX, 0 JNZ LAST AGE: POP DX OR DX, 30H MOV AH, 2 INT 21H LOOP AGE POP DX POP CX POP BX POP AX RET Print ENDP

    4.求累加和

    全部累加到 D A T A [ 0 ] DATA[0] DATA[0] 上直接调用 Print 函数,因为Print函数是针对DATA数组设计的,所以把最后的结果存入DATA数组中不需要额外的输出函数。 ;-------SUM------------- Get_sum PROC NEAR PUSH BX PUSH CX MOV BX, 0 MOV CX , 9 MOV DI, 2 LOP1: MOV BX, DATA[0] ADD BX, DATA[DI] MOV DATA[0], BX ADD DI , 2 LOOP LOP1 POP CX POP BX RET Get_sum ENDP

    5.其他函数

    ;----换行子函数(一个数输入完毕)------- CRLF PROC Near push AX push DX MOV DL, 0ah MOV AH, 2 INT 21H pop DX pop AX RET CRLF ENDP ;---------空格----------- Space PROC Near push AX push DX MOV DX, OFFSET string_5 ;' ' MOV AH, 9 INT 21H pop DX pop AX RET Space ENDP ;----------错误提示------------- ERROR PROC Near push BX push DX MOV DX, OFFSET string_2 ; ERROR: OVERFLOW! Please input again: MOV AH, 9 INT 21H pop DX pop BX RET ERROR ENDP

    四:流程图

    1. 总体流程图

    2. 子程序流程图

    2.1 Input

    2.2 Print

    2.3 Bubble_Sort

    2.4 Get_Sum

    五:代码与运行截图

    1,完整版代码(在MASM运行通过)

    ;-----数据段------------ DATAS SEGMENT string_1 DB 'Please input 10 numbers(0-65536):','$' string_2 DB 'ERROR: OVERFLOW! Please input again:','$' string_3 DB 'The array you have input is:',0ah,0dh,'$' string_4 DB 'After Sort the num is:',0ah,0dh,'$' string_5 DB ' ','$' DATA DW 10 DUP(?) massege DB 'The sum of the array is: ',0ah,0DH,'$' DATAS ENDS ;-----堆栈段------------ STACKS SEGMENT DW 256 dup(?) STACKS ENDS ;-----代码段------------ CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS ;-----------程序开始------------ START: MOV AX,DATAS MOV DS,AX MOV SI, 0 ;指针初始化 MOV CX, 10 ;循环次数 ;---------Input---------- MOV DX, OFFSET string_1 ;Please input 10 numbers(0-65536) MOV AH, 9 INT 21H Lp: CALL Input ADD SI, 2 Loop Lp ;--------结束输入,换行--------------- CALL CRLF MOV DX, OFFSET string_3 ;'The array you have input is:' MOV AH, 9 ;首地址 DS:DX INT 21H ;-------输出 ---------------- MOV CX, 10 MOV DI, 0 Again: CALL Print CALL Space ADD DI , 2 Loop Again ;/******************************/ ;----------Sort----------- MOV CX, 9 MOV DI, 0 FOR1: CALL Sort ADD DI, 2 LOOP FOR1 CALL CRLF MOV DX, OFFSET string_4 ;'After Sort the num is:' MOV AH, 9 INT 21H MOV CX, 10 MOV DI, 0 FOR2: CALL Print CALL Space ADD DI , 2 LOOP FOR2 CALL CRLF ;-------求和输出--------------------- MOV DX, OFFSET massege; MOV AH, 9 INT 21H CALL Get_sum MOV DI, 0 CALL Print EXIT: MOV AH, 4CH INT 21H ;/************子程序调用****************/ ;---------输入函数(单数字输入)------------ Input PROC Near push AX push BX push CX push DX MOV BX, 0 CLC MOV DX, 0 ;----------输入数字-------------- Lp_0: MOV AH, 1 INT 21H CMP AL, 20H ;空格 JE L_CRLF ;----- x belong to [0,9] ---------- SUB AL, 30H ; ASCII -> int JL L_ERROR CMP AL, 9 JG L_ERROR ;------- string -> int ----------- MOV AH, 0 ;将 AL扩展成 AX XCHG AX, BX ;保护 AX值 MOV CX, 10 MUL CX ; bx *= 10 ADD AX , BX JC L_ERROR ; OVERFLOW处理 XCHG AX, BX JMP Lp_0 L_ERROR: MOV DX, 0 MOV BX, 0 CALL CRLF ; 换行 CALL ERROR ; 输出错误提示 JMP Lp_0 L_CRLF: ; 以换行作为一个数的结束标志 MOV DX, 0 MOV DATA[SI], BX ; POP DX POP CX POP BX POP AX RET Input ENDP ;----换行子函数(一个数输入完毕)------- CRLF PROC Near push AX push DX MOV DL, 0ah MOV AH, 2 INT 21H pop DX pop AX RET CRLF ENDP ;---------空格----------- Space PROC Near push AX push DX MOV DX, OFFSET string_5 ;' ' MOV AH, 9 INT 21H pop DX pop AX RET Space ENDP ;----------错误提示------------- ERROR PROC Near push BX push DX MOV DX, OFFSET string_2 ; ERROR: OVERFLOW! Please input again: MOV AH, 9 INT 21H pop DX pop BX RET ERROR ENDP ;---------输出函数(单数字输出)------------- Print PROC Near PUSH AX PUSH BX PUSH CX PUSH DX MOV CX, 0 MOV BX, 10 MOV AX, DATA[DI] LAST: MOV DX, 0 DIV BX ; DIV商放AX,余数放入DX PUSH DX INC CX CMP AX, 0 JNZ LAST AGE: POP DX OR DX, 30H MOV AH, 2 INT 21H LOOP AGE POP DX POP CX POP BX POP AX RET Print ENDP ;---------SORT--------------------- SORT PROC NEAR PUSH BX PUSH DX MOV SI,DI LOOP1: ADD SI,2 MOV BX,DATA[DI] CMP BX,DATA[SI] JA CHANGE JMP NEXT CHANGE: MOV DX,DATA[SI] MOV DATA[DI],DX MOV DATA[SI],BX NEXT: CMP SI,18 JL LOOP1 POP DX POP BX RET SORT ENDP ;-------SUM------------- Get_sum PROC NEAR PUSH BX PUSH CX MOV BX, 0 MOV CX , 9 MOV DI, 2 LOP1: MOV BX, DATA[0] ADD BX, DATA[DI] MOV DATA[0], BX ADD DI , 2 LOOP LOP1 POP CX POP BX RET Get_sum ENDP CODES ENDS END START

    2. 正确运行时截图

    3. 错误输入时截图

    最新回复(0)