计算机编程输入3个数排序,汇编语言 输入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 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函数:

利用DIV函数的特点——每次除10的商放在AX, 余数放入DX

并利用栈的 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. 总体流程图

3a0d5f071a637e1f4330b82fb0dd0f16.png

2. 子程序流程图

2.1 Input

5b68da9e79c80061b73d25037ec69f2c.png

2.2 Print

8749c9d43795c09505797945fdde4287.png

2.3 Bubble_Sort

e4036d859ab9b1ecbae3e4f42005753d.png

2.4 Get_Sum

cfd7d85f7cffa71ee9549c938e02f3db.png

五:代码与运行截图

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. 正确运行时截图

1ee54ee085d0ca7f568e9a17e83ed1e1.png

3. 错误输入时截图

8dc41946876da60cb1609ca28fe0fd34.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值