;计数排序
assume cs:code
;排序前字符段,为了界面直观,不超过10个字符
chars segment
db 'ajdueioinx' ;给个初始值
chars ends
;记录每个字符位置的值
count segment
db 10 dup(0)
count ends
;排序后的字符段
order segment
db 10 dup(0)
order ends
;控制输入,分别为maxsize(最大为10)和length(根据chars设置为(0,10]的范围)
attribute segment
db 10 , 8
attribute ends
code segment
beforeOrder:
db '>>Before order:'
countNum:
db '>>Count value :'
afterOrder:
db '>>Finish order:'
start:
mov ax,0500h ;直接写显存(b800h)显示字符时,在windows 2003 server系统的
int 10h ;控制台直接直接执行可执行文件,无法显示.置0页为显示页.
call orderChars ;计算个字符应该在排序后的位置
call ordered ;按count的值构造出新序列
call paint ;输出数据
return:
mov ah , 07H
int 21H ;任意键退出
mov ax , 4C00H
int 21h
;================================
;计算原始字符串中各个字符在排序后应该处于的位置
orderChars:
push ds
push ax
push bx
push cx
push dx
push si
push di
mov ax , attribute
mov ds , ax
mov di , ds:[1] ;保存length
mov ax , chars
mov ds , ax ;chars段
mov ax , count
mov es , ax ;count段
mov si , 0 ;外层循环控制量 0<i=<length
mov cx , di ;外层循环次数
cmp cx , 0
je orderRet
outstart:
push cx
sub cx , 1 ;内层循环次数
cmp cx , 0
je nextOut
mov bx , si
add bx , 1 ;i<j=<length
instart:
mov al , ds:[si]
cmp al, ds:[bx]
ja owenCount
add byte ptr es:[bx] , 1
add bx , 1
loop inStart
jmp nextOut
owenCount:
add byte ptr es:[si] , 1
add bx , 1
loop instart
nextOut:
add si , 1
pop cx
loop outstart
orderRet:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop ds
ret
;==============================
;将chars中的每个char按照各自的count值放入order中相应位置
ordered:
push ds
push es
push ax
push bx
push cx
push dx
push si
mov ax , attribute
mov ds , ax
mov al , ds:[1]
mov ah , 0
mov si , 0
mov cx , ax
copy:
mov ax , chars
mov ds , ax
mov dh , ds:[si] ;字符
mov ax , count
mov ds , ax
mov dl , ds:[si] ;应该在排好序中的位置
mov ax , order
mov ds , ax
mov bx , 0
mov bl , dl
mov ds:[bx] , dh
add si , 1
loop copy
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret
;==============================================
;清屏
cls:
push es
push bx
push cx
push si
mov bx , 0B800H
mov es , bx
mov bx , 0
mov cx , 25
A:push cx
mov si , 0
mov cx , 80
B:mov byte ptr es:[bx+si] , 20H
add si , 2
loop B
add bx , 160
pop cx
loop A
pop si
pop cx
pop bx
pop es
ret
;==============================
;直接向显存写入显示信息,参数ds段地址;si偏移地址;cx长度;bl行数
viewStr:
push ds
push es
push ax
push cx
push si
push di
mov ax , 0B800H
mov es , ax
mov ax , 160
mul bl
mov bx , ax
mov di , 0
CR:mov al , ds:[si]
mov es:[bx+di] , al
add si , 1
add di , 2
loop CR
pop di
pop si
pop cx
pop ax
pop es
pop ds
ret
;=====================================================
;画界面中的格子。
paint:
push ds
push es
push ax
push bx
push cx
push dx
push si
push di
call cls ;清屏
;显示提示信息
mov ax , cs
mov ds , ax
mov si , offset beforeOrder
mov bl , 6
mov cx , 15
call viewStr
mov ax , cs
mov ds , ax
mov si , offset countNum
mov bl , 11
mov cx , 15
call viewStr
mov ax , cs
mov ds , ax
mov si , offset afterOrder
mov bl , 15
mov cx , 15
call viewStr
mov ax , 0B800H
mov es , ax
;第一个条格
mov dl , 5 ;dl控制在屏幕上的显示行数
mov dh , '-' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 2 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 41 ;显示多少个
call paintC
mov dl , 6 ;dl控制在屏幕上的显示行数
mov dh , '|' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 8 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 11 ;显示多少个
call paintC
mov dl , 7 ;dl控制在屏幕上的显示行数
mov dh , '-' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 2 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 41 ;显示多少个
call paintC
;排序前的字符串
mov ax , attribute
mov ds , ax
mov cx , ds:[1] ;一共有多少个字符
cmp cx , 0
je paintCount
mov dl , 6 ;dl控制在屏幕上的显示行数
mov di , 8 ;寻址的增量
mov bx , 0 ;遍历字符空间
mov si , 4 ;变址初始值
mov ax , chars
mov ds , ax
mov al , 0AH ;al控制颜色
A2:push cx
mov cx , 1 ;显示多少个
mov dh , ds:[bx] ;dh表示显示什么字符
call paintC
add bx , 1
pop cx
loop A2
paintCount:
;第二个条格
mov dl , 10 ;dl控制在屏幕上的显示行数
mov dh , '-' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 2 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 41 ;显示多少个
call paintC
mov dl , 11 ;dl控制在屏幕上的显示行数
mov dh , '|' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 8 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 11 ;显示多少个
call paintC
mov dl , 12 ;dl控制在屏幕上的显示行数
mov dh , '-' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 2 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 41 ;显示多少个
call paintC
;count值
mov ax , attribute
mov ds , ax
mov cx , ds:[1] ;一共有多少个字符
cmp cx , 0
je paintOrder
mov dl , 11 ;dl控制在屏幕上的显示行数
mov di , 8 ;寻址的增量
mov bx , 0 ;遍历字符空间
mov si , 4 ;变址初始值
mov ax , count
mov ds , ax
mov al , 0AH ;al控制颜色
A3:push cx
mov cx , 1 ;显示多少个
mov dh , ds:[bx] ;dh表示显示什么字符
add dh , 30H
call paintC
add bx , 1
pop cx
loop A3
paintOrder:
;第三个条格
mov dl , 14 ;dl控制在屏幕上的显示行数
mov dh , '-' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 2 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 41 ;显示多少个
call paintC
mov dl , 15 ;dl控制在屏幕上的显示行数
mov dh , '|' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 8 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 11 ;显示多少个
call paintC
mov dl , 16 ;dl控制在屏幕上的显示行数
mov dh , '-' ;dh表示显示什么字符
mov al , 7 ;al控制颜色
mov di , 2 ;寻址的增量
mov si , 0 ;变址初始值
mov cx , 41 ;显示多少个
call paintC
;排序后的字符串
mov ax , attribute
mov ds , ax
mov cx , ds:[1] ;一共有多少个字符
cmp cx , 0
je paintRet
mov dl , 15 ;dl控制在屏幕上的显示行数
mov di , 8 ;寻址的增量
mov bx , 0 ;遍历字符空间
mov si , 4 ;变址初始值
mov ax , order
mov ds , ax
mov al , 0AH ;al控制颜色
A4:push cx
mov cx , 1 ;显示多少个
mov dh , ds:[bx] ;dh表示显示什么字符
call paintC
add bx , 1
pop cx
loop A4
paintRet:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret
;=============================
;向显存中写一个字符,仅是为了简化paint方法,参数意义见paint中的描述
paintC:
push bx
push ax
mov ax , 160
mul dl
mov bx , ax
pop ax
mov ah , 0
A1:mov es:[bx+si+40] , dh
mov es:[bx+si+40+1] , al
add si , di
loop A1
pop bx
ret
code ends
end start
[07/09/24] |