Консультация № 189065
02.04.2016, 10:34
0.00 руб.
0 6 1
Уважаемые эксперты! Пожалуйста, ответьте на вопрос:
Написать программу на языке ассемблер:
Заменить элементы главной диагонали на суммы элементов соответствующих строк, затем отсортировать получившийся массив по возрастанию элементов главной диагонали.

Обсуждение

давно
Посетитель
7438
7205
02.04.2016, 11:14
общий
Адресаты:
Здравствуйте!
Сразу несколько вопросов:
1) DOS?
2) Формат? EXE, COM?
2) Какой Ассемблер? TASM, MASM, FASM, ...?
3) Как задается матрица? В тексте, случайно, вводится, из файла, ...?
4) Может, достаточно только подпрограммы?
5) Сами как-то пробовали написать? Покажите.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
400140
3
04.04.2016, 11:53
общий
[q=7438][/q]
1) Да
2) Exe
3) Tasm
4)Случайно
5) К сожалению, подпрограммы недостаточно
6) Нет, не пробовал, плохо разбираюсь в ассемблере
Буду благодарен за помощь!
давно
Посетитель
7438
7205
04.04.2016, 12:06
общий
Адресаты:
Хорошо, по свободе нарисую Вам программу, может, сегодня вечером...
Если, конечно, никто не опередит...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
04.04.2016, 18:43
общий
Адресаты:
Еще вопрос: сортировать вектор из диагональных элементов? Или как-то тасовать все элементы матрицы?
Если только вектор, то просто вывести или разместить в матрице на новых местах, не трогая все остальные элементы?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
400140
3
04.04.2016, 20:47
общий
[q=7438][/q]
Честно говоря я сам не знаю, сделайте как вам будет удобней. Ну или как покороче. Еще раз спасибо
давно
Посетитель
7438
7205
05.04.2016, 12:57
общий
это ответ
Здравствуйте, vanek-doter121!
Вот Вам программа. Как для человека, незнающего Ассемблер, будет непросто.
Комментариев много, изучайте! Будут вопросы, спрашивайте в мини-форуме...
[code lang=asm h=200]
;Заменить элементы главной диагонали на суммы элементов соответствующих строк,
;затем отсортировать получившийся массив по возрастанию элементов главной диагонали

.model small
.code
.startup

call srand ;Инициируем генератор псевдослучайных чисел

call GetN ;Введем размерность матрицы [2;9]
mov N, ax ;сохраним

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

call SetArray ;заполним матрицу случайными числами

lea dx, sSourceArray;строка - заголовок
call PrintArray ;выведем на экран матрицу

call FormDiag ;формируем новые диагональные элементы, как сумму элементов строк

lea dx, sMiddleArray
call PrintArray ;выводим промежуточный результат

call SortDiag ;сортируем элементы на главной диагонали

lea dx, sSortedArray
call PrintArray ;окончательный результат

mov ah, 0 ;ждем нажатия на клавишу
int 16h

mov ax, N ;подкорректируем стек (для порядка)
mul ax ; вообще говоря, можно не делать...
shl ax, 1
add sp, ax

.exit 0 ;выход в ДОС

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

mov ah, 1 ;ждем нажатие с выводом на экран
int 21h

push ax ;сохраним в стеке
mov ah, 2
mov dl, 0dh ;переход на новую строку
int 21h
mov dl, 0ah
int 21h
pop ax ;в al - ASCII-код

cmp al, '1' ;ждем символ-цифру ['1'-'9']
jl GetN ;иначе - на повтор ввода
cmp al, '9'
jg GetN
and ax, 0fh ;превратим ASCII-код в число 0-9
ret
GetN endp

PrintNum proc ;вывод знакового числа в AX на экран
push cx ;сохраним используемый регистр, в нем счетчик цикла в стеке
push ax ;сохраним выводимое значение
;выведем знак ' '/'-'
mov dl, ' ' ;считаем пока, что число положительное
test ax, ax ;проверяем число
jge print_sign ;для положительного - на вывод знака
;для отрицательного
pop ax ;уберем из стека число
neg ax ;найдем модуль числа!
push ax ;и сохраним в стеке уже положительное число!
mov dl, '-' ;знак отрицательного числа

print_sign:
mov ah, 2 ;выводим знак
int 21h
pop ax ;AX - модуль числа, т.е. строго положительное
;найдем все разряды числа и сохраним их в стеке в обратном порядке!
xor cx, cx ;счетчик разрядов
mov bx, 10 ;будем делить на 10 (10-ричная система счисления!)
digits_loop: ;цикл нахождения разрядов
xor dx, dx ;готовимся к делению dx:ax/bx
div bx ;dx - остаток от dx:ax/bx, ax - частное
push dx ;остаток - очередной десятичный разряд, сохраняем в стеке
inc cx ;считаем
test ax, ax ;проверим число
jne digits_loop ;повторяем, пока есть еще разряды
print_loop: ;выводим разряды в обратном порядке
pop dx ;очередной разряд
or dl, '0' ;число в ASCII-код
mov ah, 2 ;выводим символ
int 21h
loop print_loop ;для всех найденных разрядов, количество в CX
pop cx ;восстановим используемый регистр
ret
PrintNum endp

PrintArray proc ;вывод матрицы на экран, ее адрес в регистре BP
mov ah, 9 ;в dx - адрес строки-заголовка
int 21h ;выведем

mov cx, N ;количество строк
xor si, si ;индекс в матрице
PrintArray_rows_loop: ;цикл по строкам
push cx ;сохраним счетчик цикла по строкам
mov cx, N ;количество столбцов
PrintArray_cols_loop: ;цикл по столбцам очередной строки
mov ax, [si+bp] ;очередной элемент
call PrintNum ;выводим
mov dl, 9 ;отделим табуляцией
mov ah, 2
int 21h
add si, 2 ;индекс следующего элемента
loop PrintArray_cols_loop ;на вывод следующего элемента в строке
mov ah, 2 ;строка закончилась
mov dl, 0dh ;выводим перевод строки
int 21h
mov dl, 0ah
int 21h
pop cx ;восстановим счетчик строк
loop PrintArray_rows_loop ;на вывод следующей строки
ret
PrintArray endp

SetArray proc ;заполнение матрицы (адрес в BP) случайными знаковыми числами
mov di, 20 ;для простоты будем заполнять числами [-10;9]
;можно поменять на 200 и дальше - на 100
;получим числа [-100;99]
mov ax, N ;число строк/столбцов
mul ax ;число всех элементов = N^2
mov cx, ax ;счетчик всех элементов, матрицу рассматриваем, как вектор
xor si, si ;индекс очередного элемента
SetArray_loop: ;цикл по всем элементам
call rnd ;получаем очередно случайное число
xor dx, dx
div di ;делим на "размах" чисел
sub dx, 10 ;отнимаем от остатка середину, получаем знаковое число!
mov [si+bp], dx ;сохраняем!
add si, 2 ;индексируем следующий элемент
loop SetArray_loop ;циклим
ret
SetArray endp

FormDiag proc ;замена диагональных элементов матрицы
;суммой элементов соответствующей строки
mov cx, N ;счетчик по строкам

mov bx, N ;посчитаем смещение для диагонального элемента следующей строки
inc bx
shl bx, 1 ;=2(N+1)

xor di, di ;индекс диагонального элемента текущей строки
xor si, si ;индекс по всем элементам
FormDiag_rows_loop:
push cx
mov cx, N ;счетчик столбцов текущей строки
xor ax, ax ;сумма элементов строки
FormDiag_cols_loop: ;цикл подсчета суммы текущей строки
add ax, [si+bp] ;складываем
add si, 2 ;индекс следующего
loop FormDiag_cols_loop
mov [di+bp], ax ;сохраняем сумму на месте диагонального элемента
add di, bx ;индекс диагонального элемента следующей строки
pop cx ;счетчик строк
loop FormDiag_rows_loop
ret
FormDiag endp

;сортировка диагональных элементов методом "пузырька"
;остальные элементы матрицы не меняются
;алгоритм "пузырька":
;for(i=0;i<N-1;i++)
; for(j=i;j<N;j++)
; if (A[i]>A[j])
; change(A[i],A[j])
SortDiag proc

mov bx, N ;посчитаем смещение для диагонального элемента следующей строки
inc bx
shl bx, 1 ;=2(N+1)

mov ax, N ;посчитаем предельное значение индекса для внутреннего цикла
mul ax
shl ax, 1
mov dx, ax ;=2*N^2

sub ax, bx ;посчитаем предельное значение индекса для внешнего цикла
mov cx, ax ;=2*(N^2-N-1)

xor si, si ;индекс внешнего цикла
SortDiag_first_loop: ;внешний цикл
cmp si, cx ;дошли до конца?
jg SortDiag_first_ret ;конец сортировки
lea di, [si+bx] ;индекс внутреннего цикла
SortDiag_second_loop: ;внутренний цикл
cmp di, dx ;дошли до конца?
jg SortDiag_first_next ;на следующий цикл внешнего цикла
mov ax, [si+bp] ;проверяем, над ли менять местами
cmp ax, [di+bp] ;сравниваем элементы по индексам внешнего и внутреннего циклов
jle SortDiag_second_next ;если <=, то не трогаем
xchg ax, [di+bp] ;если больше, то меняем местами
mov [si+bp], ax
SortDiag_second_next:
lea di, [di+bx] ;индекс следующего диагонального элемента внутреннего цикла
jmp SortDiag_second_loop
SortDiag_first_next:
lea si, [si+bx] ;индекс следующего диагонального элемента внешнего цикла
jmp SortDiag_first_loop
SortDiag_first_ret: ;диагональ отсортирована
ret
SortDiag endp

srand proc ;инициализация генератора псевдослучайных чисел
mov ah, 2ch
int 21h ;возьмем текущее время
mov al, dl ;сотые секунды
mul dh ;умножаем на секунды
mov rand_value, ax ;сохраним, как текущее
ret
srand endp

;простые числа, необходимые для простейшего генератора псевдослучайных чисел
a equ 13013
c equ 16383

;rand = ((a * rand) / 65536) + c
rnd proc
mov ax, a
mul rand_value
add ax, c
mov rand_value, ax
ret
rnd endp

.data
sEnter db "Enter N [2-9] = $"
sSourceArray db "Source array:",0dh,0ah,'$'
sMiddleArray db "Middle array:",0dh,0ah,'$'
sSortedArray db "Sorted array:",0dh,0ah,'$'
N dw ?
rand_value dw ?

end
[/code]
5
Огромное спасибо :)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа