String 8086汇编中的字符串排序
我想编写一个8086汇编程序,从用户那里获取5个字符串作为输入,然后对这些字符串进行排序,并将排序后的结果打印为输出。实际上,我什么都做,但我在排序部分有一个大问题。我知道如何使用冒泡排序对数组中从特定地址开始的项目进行排序,但这里我有5个不同的字符串,它们不在同一个数组中。每个字符串都有自己的地址和字符。我试着比较每个字符串的最后一个字符,如果其中一个比另一个大,我交换整个字符串,然后我继续对所有字符串的整个字符进行交换 例如,如果我们的输入字符串是:String 8086汇编中的字符串排序,string,sorting,assembly,x86,x86-16,String,Sorting,Assembly,X86,X86 16,我想编写一个8086汇编程序,从用户那里获取5个字符串作为输入,然后对这些字符串进行排序,并将排序后的结果打印为输出。实际上,我什么都做,但我在排序部分有一个大问题。我知道如何使用冒泡排序对数组中从特定地址开始的项目进行排序,但这里我有5个不同的字符串,它们不在同一个数组中。每个字符串都有自己的地址和字符。我试着比较每个字符串的最后一个字符,如果其中一个比另一个大,我交换整个字符串,然后我继续对所有字符串的整个字符进行交换 例如,如果我们的输入字符串是: eab abe cbd
eab
abe
cbd
cda
adb
我将首先对每个字符串的最后一个字符进行排序,并得出以下结论:
cda
eab
adb
cbd
abe
然后我将按中间的字符进行比较:
eab
cbd
abe
cda
adb
最后是第一个字符,所有内容都已排序:
abe
adb
cbd
cda
eab
但这实际上是我的想法,我不知道谁应该在我的工作中实施这一点
; multi-segment executable file template.
data segment
data1 db 64,?,64 dup(?)
data2 db 64,?,64 dup(?)
data3 db 64,?,64 dup(?)
data4 db 64,?,64 dup(?)
data5 db 64,?,64 dup(?)
change db 66 dup(?)
msg db 0ah,0dh,"You enter a wrong option",0ah,0dh,"try again",0ah,0dh,"$"
prompt db 0ah,0dh,"Choose an option:",0ah,0dh,"$"
prompt1 db ".a: Sort in ascending order",0ah,0dh,"$"
prompt2 db ".d: Sort in descending order",0ah,0dh,"$"
prompt3 db ".q: Quit",0ah,0ah,0dh,"$"
enter db 0ah,0ah,0dh,"Enter 5 strings:",0ah,0dh,"$"
pkey db 0ah,0dh,"press any key...$"
ends
stack segment
dw 128 dup(0)
ends
code segment
main proc far
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
again:
; printing the prompts for the user
lea dx, prompt
mov ah, 09h
int 21h
lea dx, prompt1
mov ah, 09h
int 21h
lea dx, prompt2
mov ah, 09h
int 21h
lea dx, prompt3
mov ah, 09h
int 21h
; getting a character from the user as an input
mov ah, 01h
int 21h
; determining which option the user selects
cmp al, 'a'
je ascending
cmp al, 'd'
je descending
cmp al, 'q'
je quit
; this is for the time that the user enters a wrong char
lea dx, msg
mov ah, 09h
int 21h
jmp again ; again calling the application to start
ascending:
call input
call AscendSort
jmp again ; again calling the application to start
descending:
call input
call DescendSort
jmp again ; again calling the application to start
quit:
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
main endp
;.................................................
; this subroutine gets input from user
input proc
lea dx, enter
mov ah, 09h
int 21h
call newline
mov ah, 0ah
lea dx, data1
int 21h
call newline
mov ah, 0ah
lea dx, data2
int 21h
call newline
mov ah, 0ah
lea dx, data3
int 21h
call newline
mov ah, 0ah
lea dx, data4
int 21h
call newline
mov ah, 0ah
lea dx, data2
int 21h
call newline
ret
input endp
;................................................
; sorting the strings in the ascending order
AscendSort proc
mov si, 65
lea dx, change
mov al, data1[si]
cmp al, data2[si]
ja l1
?????
ret
AscendSort endp
;................................................
; sorting the strings in the descending order
DescendSort proc
ret
DescendSort endp
;................................................
; newline
newline proc
mov ah, 02h
mov dl, 0ah
int 21h
mov dl, 0dh
int 21h
ret
newline endp
ends
end main ; set entry point and stop the assembler.
; 多段可执行文件模板。
数据段
数据1 db 64,64重复(?)
数据2 db 64,64重复(?)
数据3 db 64,64重复(?)
数据4 db 64,64重复(?)
数据5分贝64,64重复(?)
更改数据库66重复(?)
msg db 0ah,0dh,“您输入了错误的选项”,0ah,0dh,“重试”,0ah,0dh,“$”
提示db 0ah,0dh,“选择一个选项:”,0ah,0dh,“$”
prompt1 db“.a:按升序排序”,0ah,0dh,“$”
prompt2 db“.d:按降序排序”,0ah,0dh,“$”
提示3 db“.q:退出”,0ah,0ah,0dh,“$”
输入db 0ah,0ah,0dh,“输入5个字符串:”,0ah,0dh,“$”
pkey db 0ah,0dh,“按任意键…”
末端
堆栈段
dw 128 dup(0)
末端
代码段
主进程far
; 设置段寄存器:
mov-ax,数据
mov-ds,ax
斧头
再一次:
; 为用户打印提示
lea dx,提示
mov啊,09h
int 21h
lea dx,提示1
mov啊,09h
int 21h
lea dx,提示2
mov啊,09h
int 21h
lea dx,提示3
mov啊,09h
int 21h
; 从用户处获取字符作为输入
mov-ah,01h
int 21h
; 确定用户选择的选项
“a”
乙脑上升
cmp al'd'
乙脑下降
cmp al,‘q’
我退出
; 这是指用户输入错误字符的时间
lea dx,味精
mov啊,09h
int 21h
jmp;再次调用应用程序启动
提升:
呼叫输入
调用升序排序
jmp;再次调用应用程序启动
降序:
呼叫输入
调用排序
jmp;再次调用应用程序启动
退出:
李安
莫夫啊,9
int 21h;ds:dx处的输出字符串
; 等钥匙。。。。
莫夫啊,1
int 21h
mov-ax,4c00h;退出操作系统。
int 21h
主端
;.................................................
; 此子例程从用户获取输入
输入过程
leadx,输入
mov啊,09h
int 21h
呼叫新线
mov啊,0ah
lea dx,数据1
int 21h
呼叫新线
mov啊,0ah
lea dx,数据2
int 21h
呼叫新线
mov啊,0ah
lea dx,数据3
int 21h
呼叫新线
mov啊,0ah
lea dx,数据4
int 21h
呼叫新线
mov啊,0ah
lea dx,数据2
int 21h
呼叫新线
ret
输入端
;................................................
; 按升序排序字符串
升序排序程序
莫夫·西,65岁
lea dx,更改
mov al,data1[si]
cmp铝,数据2[si]
ja l1
?????
ret
升序排序endp
;................................................
; 按降序排列字符串
下降排序程序
ret
下降排序endp
;................................................
; 新线
换行程序
mov啊,02h
mov-dl,0ah
int 21h
mov-dl,0dh
int 21h
ret
换行符endp
末端
端干管;设置入口点并停止汇编程序。
对这些字符串进行排序的任何其他算法也将受到欢迎。我自己实际上找到了答案,我使用字符串命令将字符串2×2进行比较,看看它们是否更大、更小或相等。类似于特定宏中的以下代码,该宏使用两个字符串来检查它们,并执行所需的操作,如交换字符串以使其排序:
check macro a, b
local next, finish
cld
mov cx, 64 ; the size of our buffer that saves the string
mov si, a
mov di, b
repe cmpsb ; comparing two strings with each other
ja next
jmp finish
next:
; swaping our strings if needed
mov cx, 64
mov si, a
lea di, change
rep movsb
mov cx, 64
mov si, b
mov di, a
rep movsb
mov cx, 64
lea si, change
mov di, b
rep movsb
finish:
endm
对于短且长度固定的字符串,您可以选择基数(又称分布)排序。总的来说,排序是一个非常复杂的问题,我会先用高级语言编写一个版本,让我的算法变得简单,然后把它移植到汇编程序中。你会一直精确地排序5个字符串吗,不能多也不能少?那你应该调查一下。这些排序算法比一般的排序算法更快、更简单。是的,对于输入来说,只需要对5个字符串进行排序,不多也不少。我不坚持这种基数排序,我知道如何在Java中实现这种排序,但在汇编中,一切都变成了一场噩梦。任何其他更简单的算法都会很好。只使用编译器可能会得到更好的结果。通常通过对指针数组进行排序来对字符串进行排序。所以交换只是交换指针,而不是整个字符串。当所有字符串大小相同时,您的解决方案(缓慢)工作。如果需要对字符串存储位置进行实际排序,则对指针进行排序,然后将所有字符串按顺序排列会更快,因此实际的字符串数据只会复制一次。另外,您可以通过执行
jnafinish
而不是janext/jmpfinish
来保存指令。