Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 405
∙ повысить рейтинг »
Куликов Роман Евгеньевич
Статус: 1-й класс
Рейтинг: 0
∙ повысить рейтинг »
Козлова Ольга Александровна
Статус: 1-й класс
Рейтинг: 0
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler

Номер выпуска:1603
Дата выхода:25.04.2016, 20:51
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:18 / 7
Вопросов / ответов:1 / 2

Консультация # 189230: Уважаемые эксперты! Пожалуйста, помогите составить программу на assembler'e^ Требуется: Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода пустая строка) и сортирует их ...

Консультация # 189230:

Уважаемые эксперты! Пожалуйста, помогите составить программу на assembler'e^

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


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

Дата отправки: 20.04.2016, 20:34
Вопрос задал: haustow_2012 (Посетитель)
Всего ответов: 2
Страница онлайн-консультации »


Консультирует Лысков Игорь Витальевич (Старший модератор):

Здравствуйте, haustow_2012!
Вот и программа.
Обмен строк сводится к обмену адресов, поэтому я его не вывел в подпрограмму.

Код (Assembler) :: выделить код
   .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
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Консультирует Зенченко Константин Николаевич (Модератор):

Здравствуйте, haustow_2012!

Вариант с обменом строк:

Код (Assembler) :: выделить код
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

Удачи!

Консультировал: Зенченко Константин Николаевич (Модератор)
Дата отправки: 25.04.2016, 14:04
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!


В избранное