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

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


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

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

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

Boriss
Статус: Академик
Рейтинг: 2545
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2047
∙ повысить рейтинг »
vladisslav
Статус: 8-й класс
Рейтинг: 1327
∙ повысить рейтинг »

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

Номер выпуска:1388
Дата выхода:30.11.2010, 07:30
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:221 / 67
Вопросов / ответов:1 / 1

Вопрос № 180935: Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос: "Заменить элементы главной диагонали на суммы элементов соответствующих строк, затем отсортировать получившийся массив по возрастанию элементов главной диагонали"Р...



Вопрос № 180935:

Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос:
"Заменить элементы главной диагонали на суммы элементов соответствующих строк, затем отсортировать получившийся массив по возрастанию элементов главной диагонали"Размерность и элементы задавать с клавиатуры, при реализации использовать стек..
Программная реализация на Tasme, com приложение. помогите

Отправлен: 25.11.2010, 07:19
Вопрос задал: MarinaRegreneva (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, MarinaRegreneva!
А вот и программа "Прошу к столу, вскипело!"
Полагаю, разберетесь самостоятельно в хитросплетениях алгоритма...
Только замечу, что для сортировки вводится дополнительный вектор адресов строк.
Сначала сортируется сам вектор, а затем формируется отсортированная матрица,
для чего используетя временная матрица.
Все матрицы и вектор строятся в стеке...
Код:

.model tiny, pascal

.data
sGetDim db 0ah,'Enter matrix dimension (2-10): $' ;пр иглашение для ввода размерности
sMatrix db 0ah,'Enter matrix (row by row):',0dh,'$';приглашение для ввода элементов
sSource db 0ah,0ah,'Source matrix:',0dh,0ah,'$'
sSummed db 0ah,'Summed matrix:',0dh,0ah,'$'
sSorted db 0ah,'Sorted matrix:',0dh,0ah,'$'
sPress db 0ah,'Press any key for exit$'

.data?
;буфер для ввода числовой строки (для функции 0ah)
sNum db ? ;максимальный размер буфера
sCount db ? ;реальный размер строки
sBuf db 80 dup (?) ;сама строка

N dw ? ;размерность матрицы

.code
.startup

repeat:
call GetDim ;введем размерность
cmp ax, 2 ;проверим на корректность
jb repeat
cmp ax, 10
ja repeat

mov N, ax ;сохраняем размерность
mul ax ;N * N
shl ax, 1 ;по 2 байта
sub sp, ax ;выделим место под матрицу в стеке
mov bp, sp ;адрес матрицы

call GetMatrix, bp ;введем матрицу
lea dx, sSource
call PrintMatrix, bp ;выведем исходную матрицу

call SumMatrix, bp ;просуммируем
lea dx, sSummed
call PrintMatrix, bp ;выведем промежуточный результат (после суммирования)

call SortMatrix, bp ;отсортируем
lea dx, sSorted
call PrintMatrix, bp ;выведем результат

lea dx, sPress ;Press any key
mov ah, 9
int 21h

mov ah, 0 ;ждем "any key"
int 16h

mov ax, 4c00h ;выход
int 21h

PrintMatrix proc pArray:word ;вывод матрицы NxN
mov ah, 9
int 21h ;вывод заголовока из dx

mov si, pArray ;адрес массива
mov cx, N ;число строк
PrintRowLoop: ;вывод строк
push cx ;сохраним счетчик строк
mov cx, N ;чисо столбцов
PrintColLoop: ;вывод одной строки
lodsw ;очередное значение
call PrintNum ;вывод числовой строки
mov dl, 9 ;разделим табуляцией
int 21h ;ah = 2
loop PrintColLoop
mov dl, 0dh ;переход на новую строку
int 21h
mov dl, 0ah
int 21h
pop cx ;восстановим счетчик строк
loop PrintRowLoop
ret
PrintMatrix endp

PrintNum proc ;вывод беззнакового числа из ax
uses cx ;сохраним счетчик колонок
mov bx, 10 ;будем делить на 10
xor cx, cx ;счетчик цифр
DivLoop:
xor dx, dx ;готовимся к делению dx:ax / bx
div bx ;ax - частное, dx - остаток=очередной младшей цифре
push dx ;сохраним цифру в стеке
inc cx ;посчитаем
test ax, ax ;продолжим, пока не 0
jnz DivLoop
mov ah, 2 ;функция вывода
PrintLoop: ;будем выводить в обратном порядке, начиная со старшей шифры
pop dx ;восстановим очередной разряд
or dl, '0' ;превратим в символ
int 21h ;выведем
loop PrintLoop
ret
PrintNum endp

GetDim proc ;ввод числа - размерности матрицы
lea dx, sGetDim
mov ah, 9
int 21h ;приглашение на ввод размерности матрицы

mov sNum, 80 ;задаем максимальное значение
lea dx, sNum
mov ah , 0ah
int 21h ;водим строку

lea si, sBuf ;строка
call stoi ;преобразовываем в число
;ax - введенное число
ret
GetDim endp

GetMatrix proc pArray:word ;ввод матрицы
local pLast:word ;переменная для сравнения на конец

lea dx, sMatrix
mov ah, 9
int 21h ;приглашение на ввод элементов матрицы

mov di, pArray ;адрес массива

mov ax, N ;адрес за массивом (для контроля конца)
mul ax
shl ax, 1
add ax, pArray
mov pLast, ax ;сохраним
GM_ask:
mov ah, 2
mov dl, 0ah
int 21h ;переход на новую строку

mov sNum, 80
lea dx, sNum
mov ah, 0ah
int 21h
lea si, sBuf ;строка с числами, разделенная разделителями

GM_next:
cmp di, pLast ;массив заполнен?
je GM_ret

call stoi ;[si] -> ax
jcxz GM_ask ;дошли до конца строки?
stosw ;сохраняем
jmp GM_next ;на следующее число в строке
GM_ret:
ret
GetMatrix endp

;функция преобразовывает числовую строку в число
;преобразование заканчивается по любому разделителю или концу строки (0dh)
;признаком конца стр оки является cx = 0
stoi proc uses dx ;преобразование строки [si] в беззнаковое число AX
xor bx, bx ;здесь будем стоить число
xor cx, cx ;счетчик разрядов
stoi_next:
lodsb ;очередной символ
cmp al, 0dh ;конец стоки?
je stoi_eol
cmp al, '0'
jb stoi_sep ;любая нецифра - разделитель
cmp al, '9'
ja stoi_sep
push ax ;сохраним новый разряд
mov ax, 10
mul bx ;умножим старшие на 10
pop dx ;новый
and dx, 0fh ;'0'-'9' -> 0-9
add ax, dx ;добавляем новый разряд
mov bx, ax ;сохраняем
inc cx ;считаем
jmp stoi_next ;продолжаем
stoi_sep: ;встретили разделитель
jcxz stoi_next ;были только разделители - на продолжение
; иначе - конец числа и выходим
stoi_eol: ; если числа нет и встретили 0dh - конец строки
mov ax, bx ;число возвращаем в ax
dec si ;шаг назад, чтобы легче было проанализировать 0dh
ret
stoi endp

;запись на диаг ональные места сумм строк матрицы
SumMatrix proc pArray:word
mov bx, pArray ;адрес матрицы
mov cx, N ;число строк
xor si, si ;индекс для доступа к очередному элементу
mov di, si ;индекс диагонального элемента
mov dx, si ;приращение для следующего диагонального элемента
RowLoop: ;цикл по строкам
xor ax, ax ;начинаем складывать с 0
push cx ;сохраним счетчик строк
mov cx, N ;число столбцов
ColLoop: ;цикл по столбцам
add ax, [bx+si] ;складываем все элементы строки
inc si
inc si
loop ColLoop
mov [di+bx], ax ;сохраняем на месте диагонального элемента
;посчитаем индекс следующего диагонального элемента
inc dx ;инкремент приращения
inc dx
mov di, si ;di - начало следующей строки
add di, dx ;добавим приращение
pop cx
loop RowLoop ;по всем строкам
ret
SumMatrix endp

;сортировка матрицы
SortMatrix proc pArray:word
mov bx, pArray ;адрес матрицы
;выделим па мять под вектор индексов
mov ax, N ;размерность вектора
mov cx, ax ;число элементов
shl ax, 1 ;по 2 байта
sub sp, ax ;выделим место в стеке
mov bp, sp ;адрес вектора индексов

;проинициализируем адресами по порядку 0, 1, 2, ...
xor ax, ax
mov si, ax
InitIdx:
mov [bp+si], ax
inc ax
inc si
inc si
loop InitIdx

;отсортируем вектор индексов методом пузырька
mov cx, N
dec cx ;число сравнений
xor si, si ;индекс в векторе
SortLoop:
push cx ;сохраним число сравнений для текущего
lea di, [si+1] ;начинаем со следующего
SearchMinLoop: ;цикл по всем последующим
;сравниваем текущий со всеми последующими
call CmpDiag, bx, bp, si, di
jbe SortNext ;обходим обмен индексов
;меняем местами индексы
call IdxChange, bx, bp, si, di
SortNext:
inc di ;на следующий последующий
loop SearchMinLoop
inc si ;на следующий текущий
pop cx ;счетчик текущих
loop SortLoo p

;формируем массив, используя результат сортировки индексов
call FormSortedArray, bx, bp

mov ax, N ;выбрасываем из ст ека вектор индексов
shl ax, 1
add sp, ax
ret
SortMatrix endp

;сравнение элементов
CmpDiag proc pArray:word, pIdx:word, i1:word, i2:word
uses bx, si, di
mov bx, pIdx ;адрес вектора индексов
mov si, i1 ;индекс в векторе
shl si, 1 ;по два байта
mov si, [bx+si] ;номер строки в матрице

mov di, i2 ;аналогично для второго индекса
shl di, 1
mov di, [bx+di]

mov bx, pArray ;матрица
mov ax, N
mul si ;начало строки
add ax, si ;для диагонали номер строки равен номеру столбца
shl ax, 1
mov si, ax ;адрес диаглнального элемента

mov ax, N
mul di
add ax, di
shl ax, 1
mov di, ax ;адрес второго элемента

mov ax, [bx+si]
cmp ax, [bx+di] ;сравниваем
ret ;результат во флагах FZ, FC!
CmpDiag endp

;обмен индексами
IdxChange proc pArray:word, pIdx:word, i1:word, i2:word
uses bx, si, di
mov bx, pIdx ;вектор индексов
mov si, i1
shl si, 1 ;ад рес первого индекса

mov di, i2
shl di, 1 ;второго

mov ax, [bx+di] ;меняем местами
xchg ax, [bx+si]
mov [bx+di], ax
ret
IdxChange endp

;формируем отсортированную матрицу
FormSortedArray proc pArray:word, pIdx:word
mov bx, pIdx ;адрес вектора индексов
mov si, pArray ;адрес матрицы

mov ax, N
mul N
shl ax, 1
sub sp, ax ;выделяем в стеке место под новую матрицу
mov di, sp ;адрес новой матрицы

mov cx, N ;число строк
RowsLoop:
push cx ;сохраним число строк
push si ;сохраним адрес матрицы
mov ax, [bx] ;номер очередной строки
mul N
shl ax, 1 ;индекс начала
add si, ax ;адрес начала исходной строки
mov cx, N ;число элементов в строке
rep movsw ;копируем
pop si ;восстановим адрес начала матрицы
inc bx ;на следующий элемент вектора индексов
inc bx
pop cx
loop RowsLoop ;по всем строкам

;скопируем сформированную матрицу на исходное м есто
mov di, si ;адрес куда писать
mov si, sp ;откуда (адрес только что сформированной матрицы)
mov ax, N
mul N
mov cx, ax ;N*N слов
rep movsw ;копируем

mov ax, N ;выбрасываем из стека временную матрицу
mul N
shl ax, 1
add sp, ax
ret
FormSortedArray endp

end

-----
Люби своего ближнего, как самого себя

Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 26.11.2010, 13:40
Номер ответа: 264344
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru

Оценка ответа: 5

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 264344 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFPRO.RU, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.23 от 23.11.2010

    В избранное