Sorting 程序集-排序字符串的气泡排序

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

我正在用tasm编写汇编程序。我的任务是编写一个程序,它将使用冒泡排序按字母顺序对输入的字符串进行排序。如果你输入“hello”,它应该写“ehllo”。我已经写了请求输入字符串并对其进行排序(我认为它工作正常,直到最后打印出结果,但最后它只写了一次我的数据,就完成了它的工作)P.S抱歉英语不好

.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:如果目标是8086
rol ax,8
不可用。@PeterCordes:如果您想知道当您按下立即值时TASM中默认情况下会发生什么,这就是它生成的代码类型:
push ax
push bp
mov bp,sp
mov word ptr[bp+2],如果使用指令“推送33h”
,将生成33h
pop 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