Sorting 程序集-排序字符串的气泡排序
我正在用tasm编写汇编程序。我的任务是编写一个程序,它将使用冒泡排序按字母顺序对输入的字符串进行排序。如果你输入“hello”,它应该写“ehllo”。我已经写了请求输入字符串并对其进行排序(我认为它工作正常,直到最后打印出结果,但最后它只写了一次我的数据,就完成了它的工作)P.S抱歉英语不好Sorting 程序集-排序字符串的气泡排序,sorting,assembly,bubble-sort,tasm,Sorting,Assembly,Bubble Sort,Tasm,我正在用tasm编写汇编程序。我的任务是编写一个程序,它将使用冒泡排序按字母顺序对输入的字符串进行排序。如果你输入“hello”,它应该写“ehllo”。我已经写了请求输入字符串并对其进行排序(我认为它工作正常,直到最后打印出结果,但最后它只写了一次我的数据,就完成了它的工作)P.S抱歉英语不好 .model small .stack 100h .data request db 'This program is using bubblesort to get alphabetical
.model small
.stack 100h
.data
request db 'This program is using bubblesort to get alphabetical order of your enterd string', 0Dh, 0Ah, 'Enter your string:', 0Dh, 0Ah, '$'
result db 0Dh, 0Ah, 'Result:', 0Dh, 0Ah, '$'
buffer db 100, ?, 100 dup (0)
.code
start:
MOV ax, @data
MOV ds, ax
MOV ah, 09h
MOV dx, offset request
int 21h
MOV dx, offset buffer
MOV ah, 0Ah
INT 21h
MOV si, offset buffer
INC si
MOV bh, [si]
INC si
sort:
mov cx, [si]
mov bx, [si]
nextelement:
mov ax, [bx+si]
cmp ax, [bx+si+1]
jge noswap
xchg ax, [bx+si+1]
mov ax, [bx+si]
noswap:
inc si
cmp cx, si
jl nextelement
loop nextelement
MOV ah, 09h
MOV dx, offset result
int 21h
char:
LODSB
MOV ah, 2
MOV dl, al
INT 21h
DEC bh
JZ ending
JMP char
ending:
MOV ax, 4c00h
INT 21h
end start
1) 对于冒泡排序,需要两个嵌套循环。外部循环重置内部循环的启动参数,直到没有任何东西可交换为止
2) 您可以对字符进行排序。是8位值(字节)。您不能将它们直接加载到16位寄存器中(mov-ax,[bx+si]
)
3) [bx+si]
&[bx+si+1]
:这是非常错误的,我无法解释错误:-)
我没有更正代码,而是“从头开始”编写了一个示例:如中的插图所示:
。型号小
.堆叠1000小时;不要吝啬用堆栈!
.数据
结构0a等于$;整数21h/0Ah的缓冲区(最大值、最大值、最小值)
最大分贝100;缓冲区可容纳的最大字符数(包括CR(0Dh))
得到了db0;实际读取的字符数(不包括CR(0Dh))
buf-db-100dup(0);读取的实际字符,包括最终回车符(0Dh)
换行数据库13,10,'$'
GetString数据库“输入字符串:$”
.代码
开始:
mov-ax,@DATA;初始化DS
mov-ds,ax
; 输入字符串
mov啊,09h
mov dx,偏移量GetString
int 21h
mov dx,偏移量结构0A
mov啊,0Ah
INT 21h
mov-si,偏移量buf;[si+bx]的基数
异或bx,bx;为以下字节加载准备BX
mov-bl,got;端部字符串的加载长度=0Dh
mov字节PTR[si+bx],“$”;int 21h/09h的分隔符
外部:
12月bx;最后一个字符已位于正确的位置
jz完成;没有剩余字符=完成
mov-cx,bx;循环变量
移动si,偏移buf
xor-dl,dl;DL(hasSwapped)=假
内部:
mov-ax,[si];加载**两个**字符
cmp al,啊,;艾尔:1。查尔:2。烧焦
jbe S1;请注意,bh寄存器与bx共享上8位,因此如果加载后者,则前者也会被覆盖。好的,我将在将来记住这一点。我非常感谢您的帮助。我了解冒泡排序的外观以及如何用其他语言编程,只是我真的不懂汇编程序。还感谢您花时间在某些CPU上编写完整的程序:),通过始终交换并使存储有条件,避免缓存线拆分/未对齐的负载,这可能是一个胜利。e、 g.mov al,[si]
/rolax,8
/cmp/jbe
。您甚至可以使用lodsb
(但在现代CPU上,它比mov
/inc
慢)。这在AX上创建了一个循环承载的依赖关系,但是如果需要大量交换,它可以避免从存储到部分重叠负载的存储转发暂停。但是冒泡排序的唯一原因首先是紧凑的代码大小,而不是性能,所以我不会对使用缓慢的循环指令抱怨太多。@PeterCordes:如果目标是8086rol ax,8
不可用。@PeterCordes:如果您想知道当您按下立即值时TASM中默认情况下会发生什么,这就是它生成的代码类型:push ax
push bp
mov bp,sp
mov word ptr[bp+2],如果使用指令“推送33h”
,将生成33hpop bp
。如果大多数人从不调试代码或生成列表文件,他们就不会意识到这一点。如果文件中没有指令或命令行上没有覆盖,TASM将以静默方式执行这些类型的转换,因为它默认为8086 code gen.@PeterCordes:不确定是否有方法在TASM中关闭该转换。在使用TASM进行开发时,在不指定.186
或更高版本的情况下,以实模式代码为目标时,我始终牢记这一点。另一方面,如果在以8086为目标时尝试使用不受支持的指令,而不是以静默方式生成等效代码,则MASM将出错。
.MODEL small
.STACK 1000h ; Don't skimp with stack!
.DATA
Struct0A EQU $ ; Buffer for INT 21h/0Ah (max,got,buf)
max db 100 ; Maximum characters buffer can hold (incl. CR (0Dh))
got db 0 ; Number of characters actually read, (excl. CR (0Dh))
buf db 100 dup (0) ; Actual characters read, including the final carriage return (0Dh)
Linefeed db 13, 10, '$'
GetString db 'Enter string: $'
.CODE
start:
mov ax, @DATA ; Initialize DS
mov ds, ax
; Input String
mov ah, 09h
mov dx, OFFSET GetString
int 21h
mov dx, OFFSET Struct0A
mov ah, 0Ah
INT 21h
mov si, OFFSET buf ; Base for [si + bx]
xor bx, bx ; Prepare BX for following byte load
mov bl, got ; Load length of string = 0Dh at the end
mov BYTE PTR [si + bx], '$' ; Delimiter for int 21h / 09h
outer:
dec bx ; The last character is already at the right place
jz done ; No characters left = done
mov cx, bx ; CX: loop variable
mov si, OFFSET buf
xor dl, dl ; DL (hasSwapped) = false
inner:
mov ax, [si] ; Load **two** characters
cmp al, ah ; AL: 1. char, AH: 2. char
jbe S1 ; AL <= AH - no change
mov dl, 1 ; hasSwapped = true
xchg al, ah ; Swap characters
mov [si], ax ; Store swapped characters
S1:
inc si ; Next pair of characters
loop inner
test dl, dl ; hasSwapped == true?
jnz outer ; yes: once more
done:
; Print result
mov dx, OFFSET Linefeed
mov ah, 09h
int 21h
mov dx, OFFSET buf
mov ah, 09h
int 21h
mov ax, 4C00h
int 21h
END start