22.04.2016, 20:02
общий
это ответ
Здравствуйте, haustow_2012!
Вот и программа.
Обмен строк сводится к обмену адресов, поэтому я его не вывел в подпрограмму.
[code lang=asm h=200]
.model small
MAX equ 1000
.data
sEnter db "Enter strings:",0dh,0ah,"$" ;приглашение ввести строки
sSorted db 0dh,0ah,"Sorted strings:",0dh,0ah,"$"
;буфер для ввода строки
buf db 128 ;размер буфера
len db ? ;реальная длина
String db 128 dup (?) ;сама строка
count dw ? ;количество строк
Arr dw MAX dup(?);массив адресов строк (не более MAX)
Pool label byte ;здесь будут сами строки
.code ;сегмент кода
.startup ;инициализация сегментов для выбранной модели памяти
lea dx, sEnter
mov ah, 9
int 21h ;приглашенние ввода строк
xor bx, bx ;индекс в массиве адресов
lea di, Pool ;адрес в пуле строк
xor cx, cx ;счетчик строк
Enter_loop: ;цикл ввода строк
lea dx, buf
mov ah, 0ah
int 21h ;вводим очередную строку
cmp len, 0 ;если введена пустая строка
je Sort ;то идем на сортировку
mov Arr[bx], di ;запоминаем начало строки в массиве адресов
lea si, String ;введенная строка
Copy_loop:
mov al, [si] ;копируем в пул,
cmp al, 0dh ;пока не встретится 0dh
je Copy_end
inc si
mov [di], al
inc di
jmp Copy_loop
Copy_end:
mov ah, 2 ;перейдем на новую строку
mov dl, 0ah
int 21h
mov byte ptr [di], 0 ;закроем строку нклем
inc di
add bx, 2 ;на следующий элемент в массиве адресов
inc cx ;считаем строку
cmp cx, MAX ;проверяем на максимум
jb Enter_loop
Sort: ;сортировка пузырьком
mov count, cx ;сохраним количество строк
cmp cx, 2 ;меньше 2 - нечего и сравнивать
jb Output
;определим правые границы внешнего и внутреннего цикла
mov dx, cx ;dx - граница для внутреннего цикла, считаем до конца массива
shl dx, 1 ;*2, т.к. идем по словам
dec cx ;cx - граница для внешнего цикла, на 1 меньше конца массива
shl cx, 1 ;и тоже умножаем на 2
xor bx, bx ;индекс внешнего цикла
Sort_loop1: ;внешний цикл
cmp bx, cx ;дошли до края?
jge Output
mov si, Arr[bx] ;адрес строки по внешнему циклу
lea bp, [bx+2] ;начало внутреннего цикла - со следующего элемента
Sort_loop2: ;внутренний цикл
cmp bp, dx ;дошли до края?
jge Sort_next1 ;на следующий шаг внешнего цикла
mov di, ds:Arr[bp] ;адрес строки по внутреннему циклу,
; DS: необходимо, т.е. BP по-умолчанию адресует в стеке!
call strcmp ;сравниваем строки [si] и [di]
test ax, ax ;проверяем результат
jle Sort_next2 ;<= - ничего не делаем
mov si, Arr[bx] ;> - меняем местами адреса строк!
xchg si, ds:Arr[bp]
mov Arr[bx], si ;одновременно, в si будет новый адрес строки по внешнему циклу
Sort_next2:
add bp, 2 ;на следующую сроку по внутреннему циклу
jmp Sort_loop2
Sort_next1:
add bx, 2 ;на следующую сроку по внешнему циклу
jmp Sort_loop1
Output: ;вывод результата
mov cx, count ;количество строк
jcxz wait_key ;если ни одной не ввели
lea dx, sSorted ;заголовок
mov ah, 9
int 21h
lea bx, Arr ;адрес массива адресов
mov ah, 2 ;ф-я вывода символа из dl
Output_loop: ;цикл вывода строк
mov si, [bx] ;адрес очередной строки
Output_string_loop: ;цикл вывода строки
mov dl, [si]
cmp dl, 0 ;до 0
je Output_next
inc si
int 21h
jmp Output_string_loop
Output_next:
mov dl, 0dh ;перевод строки
int 21h
mov dl, 0ah
int 21h
add bx, 2 ;на следующую строку
loop Output_loop
wait_key:
mov ah, 0
int 16h
.exit 0
strcmp proc ;сравнение строк
push si ;сохраним адреса строк
push di
strcmp_loop:
mov al, [si]
cmp al, [di]
jne not_equal ;не равны
cmp al, 0
je equal ;если равны до 0, значит, строки равны
inc di ;продолжаем сравнивать
inc si
jmp strcmp_loop
equal:
xor ax, ax ;ax = 0 - равны
jmp strcmp_ret
not_equal: ;не равны
mov ax, 1 ;считаем пока, что первая больше
jnc strcmp_ret ;если действительно больше, то выходим
mov ax, -1 ;если меньше
strcmp_ret:
pop di
pop si
ret
strcmp endp
end
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен