当前位置: 代码迷 >> 汇编语言 >> 人名排序有关问题
  详细解决方案

人名排序有关问题

热度:1940   发布时间:2013-02-26 00:00:00.0
人名排序问题
;例 6.11 人名排序的程序实现
;***********************************************************

.MODEL SMALL
.STACK 40H

;***********************************************************
.DATA ;定义DATA数据段
NAMEPAR LABEL BYTE
MAXLEN DB 21
NAMELEN DB ? ;名字长度,未设初值
NAMEFLD DB 21 DUP(?) ;定义NAMEFLD为21字节长,未设置初值
CRLF DB 13,10,'$'
ENDADDR DW ? ;定义ENDADDR类型为字,初值未设定
MESSG1 DB 'Name?','$' ;定义MESSG1为字符串Name?
MESSG2 DB 'Sorted name:',13,10,'$' ;定义MESSG2为字符串Sorted name:
NAMECTR DB 0 ;名字计数器,初始设为0
NAMETAB DB 30 DUP(20 DUP(' ')) ;长度30,每个可存储20字节的字符串
NAMESAV DB 20 DUP(?),13,10,'$' ;这个变量用来暂存名字
SWAPPED DB 0

;***********************************************************

.CODE ;定义代码段

;------------------------------------------------------------
BEGIN PROC FAR ;主程序开始
MOV AX,@DATA ;将DATA地址传给AX
MOV DS,AX ;将AX值传给DS和ES
MOV ES,AX
CLD ;DF设为0
LEA DI,NAMETAB ;将NAMETAB的有效地址传给DI

A20LOOP:

CALL B10READ ;调用B10READ子程序,用来接收输入的人名
CMP NAMELEN,0 ;两数比较
JZ A30 ;等于0时,转到A30
CMP NAMECTR,30 ;再将NAMECTR和30进行比较
JE A30 ;若等于30则转移到A30
CALL D10STOR ;调用子程序D10STOR,存储名字到NAMETAB中
JMP A20LOOP ; 转移到A20LOOP循环,读入名字,直到不输入或计数器到了30为止

A30:

CMP NAMECTR,1 ;比较
JBE A40 ;小于或者等于1,转移到A40
CALL G10SORT ;调用G10SORT,人名排序
CALL K10DISP ;调用K10DISP,显示人名
A40: MOV AX,4C00H ;将值4C00赋值给AX
INT 21H
BEGIN ENDP ;主程序结束

;------------------------------------------------

B10READ PROC NEAR ;子程序B10READ
MOV AH,09
LEA DX,MESSG1 ;将MESSG1的有效地址传送给DX
INT 21H ;显示MESSG1:Name?
MOV AH,0AH
LEA DX,NAMEPAR ;将NAMEPAR的有效地址传送给DX
INT 21H
MOV AH,09
LEA DX,CRLF ;将CRLF的有效地址传送给DX
INT 21H ;显示CRLF中的内容(换行)


MOV BH,0
MOV BL,NAMELEN ;将NAMELET传送给BL
MOV CX,21 ;21(16进制里的15)
SUB CX,BX ;CX-BX并将值返回给CX

B20: MOV NAMEFLD[BX],20H
INC BX ;BX加1??
LOOP B20 ;循环执行B20
RET ;子程序返回
B10READ ENDP ;退出

;------------------------------------------------

D10STOR PROC NEAR ;子程序D10STOR
INC NAMECTR ;计数器加1
CLD ;方向标志DF设置为0
LEA SI,NAMEFLD ;将NAMEFLD的有效地址传送给源地址寄存器SI
MOV CX,10
REP MOVSW ;重复执行字传送10次串操作MOVSW
RET ;子程序返回
D10STOR ENDP ;退出

;------------------------------------------------

G10SORT PROC NEAR ;子程序G10SORT:冒泡排序的实现
SUB DI,40 ;DI减40(16进制里的28)
MOV ENDADDR,DI

G20: MOV SWAPPED,0
LEA SI,NAMETAB ;将NAMETAB的有效地址传送给SI

G30 : MOV CX,20
MOV DI,SI
ADD DI,20 ;DI加20(即16进制的14)
MOV AX,DI
MOV BX,SI
REPE CMPSB
JBE G40 ;如果CF或ZF等于1则转移到G40??
CALL H10XCHG ;调用子程序H10XCHG(交换名字)

G40: MOV SI,AX
CMP SI,ENDADDR ;比较SI和ENDADDR
JBE G30 ;小于或等于时,转移到G30
CMP SWAPPED,0 ;比较SWAPPED和0
JNZ G20 ;若不等于转移到G20
RET ;子程序返回
G10SORT ENDP ;退出

;------------------------------------------------

H10XCHG PROC NEAR ;子程序H10XCHG(交换两个名字)
MOV CX,10 ;10(即A传给CX)
LEA DI,NAMESAV
MOV SI,BX
REP MOVSW ;重复执行串操作直到CX=0
MOV CX,10
MOV DI,BX
REP MOVSW ;重复执行10次串操作MOVSW
MOV CX,10
LEA SI,NAMESAV ;将NAMESAV的有效地址传送给SI
REP MOVSW ;重复执行10次串操作MOVSW
MOV SWAPPED,1 ;1传给SWPPED
RET ;子程序返回
H10XCHG ENDP ;退出

;------------------------------------------------

K10DISP PROC NEAR ;子程序K10DISP(显示排序后的名字)
  相关解决方案