Консультация № 189230
20.04.2016, 20:34
0.00 руб.
0 7 2
Уважаемые эксперты! Пожалуйста, помогите составить программу на assembler'e^

Требуется: Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода пустая строка) и сортирует их в лексикографическом порядке.


Использование в emu8086 - assembler and microprocessor emulator 0.03
Желательно, делать комментарии к строкам.

Обсуждение

давно
Посетитель
7438
7205
20.04.2016, 22:09
общий
Адресаты:
Проще всего сделать массив строк, т.е. массив указателей на строки.
При сортировке менять местами не значения строк, а только указатели.
Так устроит?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
400240
3
20.04.2016, 23:32
общий
Почему бы и нет. Главное, что эти строки можно было вводить пользователю и дальнейший вывод на экран отсортированных
давно
Посетитель
7438
7205
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]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
400240
3
22.04.2016, 22:14
общий
Можете в кратце объяснить суть алгоритма "сортировка Пузырьком" ?
давно
Посетитель
7438
7205
23.04.2016, 12:14
общий
Адресаты:
На С можно записать так:
Код:

for(i=0;i<N-1;i++)
{
for(j=i+1;j<N;j++)
{
if (A[i] > A[j])
{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}

Суть такова:
Пробегаем во внешнем цикле по всем элементам с первого до предпоследнего
и сравниваем во внутреннем цикле со всеми, начиная с последующего за текущим внешнего цикла
Если "внешний" элемент больше "внутреннего", то меняем их местами.
Старый "внутренний" автоматически становится новым "внешним"
Все последующие сравнения будут уже с ним.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
400240
3
24.04.2016, 16:39
общий
Разобрался, спасибо.
давно
Старший Модератор
31795
6196
25.04.2016, 14:04
общий
это ответ
Здравствуйте, haustow_2012!

Вариант с обменом строк:
[code lang=asm h=200]model tiny,pascal
.code
org 100h
szStr equ 100
begin: lea si,dbTabl;адрес таблицы строк
test si,1;проверяем четность адреса
jz @@01;
inc si;делаеем адрес четным
@@01: mov ah,9;выводим сообщение
lea dx,dbMess
int 21h
mov ah,10
mov cx,szStr;длина строки
mov [si+2],cx;записываем длину строки
add cx,4;учитываем служебные байты
add cx,si;получаем адрес следующей строки
mov [si],cx;записываем его
mov bx,cx
xor cx,cx;маркер конца списка строк
mov [bx],cx;записываем
mov dx,si;получаем адрес вводимой строки
add dx,2
int 21h;вводим строку
xor bh,bh;старший байт
mov bl,[si+3];длина введенной строки
or bx,bx;
jz @@02;ноль выходим из цикла ввода
mov byte ptr[bx+si+4],'$';ставим маркер конца строки
mov si,[si];переходим к следующей строке
jmp short @@01
@@02: mov [si],bx;записываем маркер конца таблицы
lea bx,dbTabl;адрес начала таблицы
test bx,1;проверяем четность адреса
jz @@03
inc bx;корректируем
@@03: mov di,[bx];получаем вторую строку
@@04: cmp word ptr[di],0;проверяем конец списка
jz @@06;ноль выход
call CheckString,di,bx;контролируем строку
jnc @@05;флаг перноса установлен-перемещаем
call ChangeString,di,bx;меняем строки
@@05: mov di,[di];переходим к слудующей строке
jmp short @@04;переходим к началу цикла
@@06: mov bx,[bx];внешний цикл
cmp word ptr[bx],0;проверяем маркер цикла
jnz @@03;не ноль переходим
lea bx,dbTabl;адрес начала таблицы
test bx,1;корректируем четный адрес
jz @@07
inc bx
@@07: mov si,bx;начало списка
@@08: mov dx,si;выводимая строка
mov cx,0a0dh;перевод строки
mov [si+2],cx;записываем
add dx,2;корректируем начало выводимой строки
mov ah,9;вывод строки
int 21h
mov si,[si];следующая строка
cmp word ptr[si],0;проверяем маркер конца списка
jnz @@08;не ноль повторяем
ret;выход
;п/программа контроля строк
CheckString proc,a:word,b:word
uses bx,cx,dx,si,di;сохраняем регистры
mov si,a;адрес первой строки
mov di,b;адрес второй строки
mov bx,-1;начальное положение
ChS: inc bx;к следующему символу
mov al,[bx+si+4];читаем символ первой строки
mov ah,[bx+di+4];читаем символ второй строки
cmp bx,szStr;проверяем конец строки
jz ChS0;ноль выходим с цикла
cmp ah,al;сравниваем символы
jz ChS;равны- к следующему символу
jb ChS0;больше переходим
stc;устанавливаем флаг
ChS0: ret;выход
CheckString endp
;п/программа обмена строками
ChangeString proc,a:word,b:word
uses bx,cx,dx,si,di;сохраняем регистры
mov si,a;начало первой строки
mov di,b;начало второй строки
mov cx,szStr;длина строки
xor bx,bx;начальное положение
ChS1: mov al,[bx+si+4];загружаем символ
xchg al,[bx+di+4];меняем местами
mov [bx+si+4],al;возвращаем обратно символ
inc bx;к следующему
loop ChS1;в цикле
ret;выход
ChangeString endp
dbMess db 10,13,'enter string:$';
dbTabl label byte;
end begin[/code]
Удачи!
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа