Консультация # 189230: Уважаемые эксперты! Пожалуйста, помогите составить программу на assembler'e^ Требуется: Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода пустая строка) и сортирует их ...
Уважаемые эксперты! Пожалуйста, помогите составить программу на assembler'e^
Требуется: Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода пустая строка) и сортирует их в лексикографическом порядке.
Использование в emu8086 - assembler and microprocessor emulator 0.03 Желательно, делать комментарии к
строкам.
.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
Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 22.04.2016, 20:02
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались.
Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора -
для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение.
Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал,
который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом.
Заходите - у нас интересно!