Assembly - пузырьковая сортировка для сортировки строк
Я пишу программу на ассемблере, используя tasm. Моя задача - написать программу, которая будет использовать сортировку по пузырькам для сортировки введенной строки по алфавиту. Ex. если вы введете "привет", следует написать "эхло". Я написал просьбу ввести строку и отсортировать ее (я думаю, что она работает хорошо до конца, где он должен распечатать результат, но в конце он просто записывает мои.data один раз и заканчивает свою работу) PS извините за плохой английский
.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 ответ
1) Для пузырьковой сортировки вам понадобятся две вложенные петли. Внешний цикл сбрасывает начальные параметры для внутреннего цикла, пока не останется ничего для замены.
2) Вы сортируете персонажей. Это 8-битные значения (байты). Вы не можете загрузить их напрямую в 16-битный регистр (mov ax, [bx+si]
).
3) [bx+si]
& [bx+si+1]
: это так неправильно, что я не могу объяснить ошибку:-) .
Вместо того, чтобы исправлять ваш код, я написал пример "с нуля": следуя иллюстрации в http://en.wikipedia.org/wiki/Bubble_sort:
.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
А вот еще одна "анимированная" иллюстрация: