Консультация # 189065: Уважаемые эксперты! Пожалуйста, ответьте на вопрос: Написать программу на языке ассемблер: Заменить элементы главной диагонали на суммы элементов соответствующих строк, затем отсортировать получившийся массив по возрастанию элементов главной диагонали....
Уважаемые эксперты! Пожалуйста, ответьте на вопрос: Написать программу на языке ассемблер: Заменить элементы главной диагонали на суммы элементов соответствующих строк, затем отсортировать получившийся массив по возрастанию элементов главной диагонали.
Здравствуйте, vanek-doter121! Вот Вам программа. Как для человека, незнающего Ассемблер, будет непросто. Комментариев много, изучайте! Будут вопросы, спрашивайте в мини-форуме...
;Заменить элементы главной диагонали на суммы элементов соответствующих строк,
;затем отсортировать получившийся массив по возрастанию элементов главной диагонали
.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
Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 05.04.2016, 12:57
5
Огромное спасибо :) ----- Дата оценки: 05.04.2016, 19:25
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались.
Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора -
для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение.
Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал,
который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом.
Заходите - у нас интересно!