汇编语言 输入10个数排序并输出的实现

一:题目描述

在键盘输入任意10个数

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

二:伪指令的定义

1.数据段

ATAS 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个无符号数存入缓冲区,并且保证 num<65536num < 65536num<65536

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

HEX FFFF
DEC 65535
BIN 1111 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 结束处理

我们来举一个123412341234 的例子

Register 1 2 3 4
AX 1 2 3 4
BX 0 1 12 123
CX 10 10 10 10

AX+(BX∗CX)AX + (BX * CX)AX+(BX∗CX)

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

2.实现冒泡排序

冒泡排序作为一个简单的排序算法,时间复杂度 O(n2)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 

外层调用:每次DI+2DI + 2DI+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函数:

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

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

DATA[Num] 1234 123 12 1
DX 4 3 2 1
Stack(PUSH DX) 4 4,3 4,3,2 4,3,2,1
Print(POP DX) 4 34 234 1234

DATA[Num]/10DATA[Num] / 10DATA[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.求累加和全部累加到DATA[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)

相关推荐

  • 汇编语言 输入10个数排序并输出的实现

    一:题目描述 在键盘输入任意10个数 按从小到大排序后,在计算机屏幕上先输出来.要有结果提示(字符串显示). 将10个数做累加,结果在计算机屏幕显示累加和. 二:伪指令的定义 1.数据段 ATAS 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

  • C#实现输入10个数存入到数组中并求max和min及平均数的方法示例

    本文实例讲述了C#实现输入10个数存入到数组中并求max和min及平均数的方法.分享给大家供大家参考,具体如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int nu1, max,min,number;

  • Java 对10个数进行排序的实现代码

    题目:对10个数进行排序 程序分析:可以利用选择法,即从后9个比较过程中,选择一个最小的与第一个元素交换, 下次类推,即用第二个元素与后8个进行比较,并进行交换. 程序设计: import java.util.Arrays; import java.util.Random; import java.util.Scanner; public class Ex28 { public static void main(String[] args) { int arr[] = new int[11];

  • java 输入3个数a,b,c,按大小顺序输出的实例讲解

    题目: 输入3个数a,b,c,按大小顺序输出. 代码: import java.util.Scanner; public class lianxi34 { public static void main(String[] args) { Scanner s = new Scanner(System.in); System.out.println("请输入3个整数:"); int a = s.nextInt(); int b = s.nextInt(); int c = s.nextIn

  • java 键盘输入一个数,输出数组中指定元素的示例

    如下所示: package com.lcn.day05; import java.util.Scanner; public class ArrayDemo7 { /** *键盘输入一个数,输出数组中指定元素 */ public static void main(String[] args) { // 定义一个数组 int[] array = new int[]{123,456,789,321,654,987}; //创建输入对象 Scanner sc = new Scanner(System.i

  • python代码 输入数字使其反向输出的方法

    如下所示: # 输入数字使其反向输出 num = int(input("请输入一个数:")) i = 0 num1 = num while True: if num1 // 10 == 0: break i += 1 num1 = num1 // 10 sum = 0 while i >= 0: sum = sum + (num % 10) * (10 ** i) num = num // 10 i = i - 1 print(sum) 以上这篇python代码 输入数字使其反向

  • Java控制台输入数组并逆序输出的方法实例 原创

    输入一个数组,然后颠倒次序进行输出,这种算法在程序开发中经常用到,下面我们通过一个小实例来看看怎么实现在控制台输入一个数组,并让其逆序输出的. 源码: import java.util.Scanner; public class Test01 { public static void main(String[] args){ System.out.println("请输入五个数"); int[]l=new int [5]; for(int i=0;i<5;i++) l[i]=ne

  • PHP查找数值数组中不重复最大和最小的10个数的方法

    本文实例讲述了PHP查找数值数组中不重复最大和最小的10个数的方法.分享给大家供大家参考.具体如下: 1. php代码如下: //随机生成1万个元素的数组 for($i=0;$i<10000;$i++){ $ary[]=rand(1,100000); } $ary=array_unique($ary); //去重复数值 sort($ary);//顺序排序 $min_10=array_slice($ary,0, 10);//取出最小的10个数值 $max_10=array_slice($ary,-

  • javascript随机抽取0-100之间不重复的10个数

    目前只学会两种简单的方法,帮助大家实现随机抽取0-100之间不重复的10个数,具体内容如下 第一种利用数组长度可改写的特点 思路:可以从0到100的数用for循环出来放在一个数组中,然后将这100个数利用sort()随机打乱,然后通过将这个数组的length改写为10,便取到了10个不同的数. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

  • 利用C++的基本算法实现十个数排序

    冒泡排序法原理:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成. 冒泡排序算法的运作如下:1.比较相邻的元素.如果第一个比第二个大,就交换他们两个. 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. 3.针对所有的元素重复以上的步骤,除了最后一个. 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较. 示例代码:

随机推荐