Консультация № 185769
07.04.2012, 16:01
75.68 руб.
0 32 1
Здравствуйте, уважаемые эксперты! Прошу вас написать программу вот с таким заданием:

Дана матрица размером m x m. Записать главную диагональ (любую из двух) в обратном порядке.

Желательно к каждой строке прописать комментарии.
И сделайте пожалуйста без использования процедур и макросов.

п.с.
Ассемблер : TASM
Размер переменных: Слово
Числа в матрице рандомные
Размер матрицы не будет больше 5x5

Заранее спасибо.

Обсуждение

Неизвестный
08.04.2012, 18:23
общий
Адресаты:
а может быть два варианта вы сможете сделать, с ними и без?!

Ну в регистрах должно четко видно какая диагональ была до этого и после
давно
Посетитель
7438
7205
09.04.2012, 10:49
общий
Полагаю, что слова "неправильно написано" буквально означают наличие ошибок.
Матрицу на экран выводим или не выводим?
PS Матрица будет храниться в памяти, а не в регистрах
Разумеется, под отладчиком все можно увидеть...
Ок, нарисую Вам пару вариантов... (если не опередят, конечно)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 11:17
общий
Адресаты:
ну матрицу выводить не надо, надо чтобы в начале программы диагональ была записана в регистре и в конце уже модифицированный вариант диагонали.
давно
Посетитель
7438
7205
09.04.2012, 11:33
общий
Матрица, а значит, и диагональ будут в памяти
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 15:07
общий
Адресаты:
Да, согласен.
давно
Посетитель
7438
7205
09.04.2012, 16:43
общий
это ответ
Здравствуйте, Yankov Dmitry!
Предлагаю такую программу.
Для заполнения матрицы использовал несложный генератор псевдослучайных чисел.
Для его инициализации - системное время.
Если что непонятно, спрашивайте.
[code h=200]
.model small

N equ 5 ;размерность матрицы
.data
seed dw ? ;очередное псевдослучайное число
matrix dw 5*5 dup (?) ;матрица 5*5 слов

.code
start:
mov ax, @data
mov ds, ax
mov es, ax

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

;заполним матрицу псевдослучайными числами 0-99
lea di, matrix ;адрес
mov cx, N*N ;количество
formMatrixLoop:
call rand ;получаем число
stosw ;пишем в матрицу
loop formMatrixLoop ;по всем элементам матрицы

;запишем главную диагональ в обратном порядке
xor si, si ;смещение элемента левого верхнего угла матрицы (самого первого)
mov di, 2*(N*N-1) ;смещение элемента правого нижнего угла матрицы (самого последнего)
ChangeLoop: ;по элементам главной диагонали
cmp si, di ;меняем, пока первый индекс меньше второго
jae ChangeEnd ;все сделано - на выход
mov ax, matrix[si] ;меняем местами matrix[si] и matrix[di]
xchg ax, matrix[di]
xchg ax, matrix[si]
add si, 2*(N+1) ;смещаем на следующий диагональный
sub di, 2*(N+1) ;смещаем на предыдущий диагональный
jmp ChangeLoop ;на следующий обмен
ChangeEnd:

mov ax, 4c00h
int 21h

;инициализация последовательности псевдослучайных чисел
randInit proc
mov ah, 2ch ;запрашиваем текущее время
int 21h ;получим: ch - секунды, cl - сотые секунды, dh - часы, dl - минуты
xor cx, dx ;сделаем более "случайным"
xchg ch, cl ;и чтобы младший байт шел первым
mov seed, cx ;сохраним
ret
randInit endp

;получение очередного псевдослучайного числа в диапозоне 0-99
rand proc near
mov ax, seed ;предыдущее случайное число
mov dx, 8E45h ;возьмем вот такое число
mul dx ;и умножим на него
inc ax ;чтобы исключить "зацикливание" на нуле
mov seed, ax ;сохраним
xor dx, dx ;получим число в диапозоне 0-99
mov bx, 100 ;для этого разделим на 100
div bx
mov ax, dx ;и возьмем остаток от деления
ret
rand endp
end start
[/code]
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 17:36
общий
Адресаты:
А как посмотреть вариант главной диагонали, а вариант после модернизирования
просто непонятно где исходный вариант, а где модернизированный
Неизвестный
09.04.2012, 17:39
общий
Адресаты:
И что значит системное время?!
Неизвестный
09.04.2012, 17:43
общий
Адресаты:
Как вообще все это происходит в регистрах? просто непонятно..
не могли бы объяснить все..
давно
Посетитель
7438
7205
09.04.2012, 17:59
общий
Во-первых, матрица представляет собой расположенные друг за другом сначала столбцы нулевой строки,
затем - первой и так до последней. Всего 5*5 = 25 слов.
Во-вторых, следующий фрагмент заполняет матрицу случайными числами.
Код:
;заполним матрицу псевдослучайными числами 0-99
lea di, matrix ;адрес
mov cx, N*N ;количество
formMatrixLoop:
call rand ;получаем число
stosw ;пишем в матрицу
loop formMatrixLoop ;по всем элементам матрицы

Поэтому, останавливаемся в отладчике по адресу matrix = 5eh и смотрим матрицу.
При этом элементы главной диагонали лежат по адресам: matrix, matrix+12, matrix+24, matrix+36 и matrix+48 (числа десятичные)
В-третьих, изменение главной диагонали происходит в следующем фрагменте:
Код:
;запишем главную диагональ в обратном порядке
xor si, si ;смещение элемента левого верхнего угла матрицы (самого первого)
mov di, 2*(N*N-1) ;смещение элемента правого нижнего угла матрицы (самого последнего)
ChangeLoop: ;по элементам главной диагонали
cmp si, di ;меняем, пока первый индекс меньше второго
jae ChangeEnd ;все сделано - на выход
mov ax, matrix[si] ;меняем местами matrix[si] и matrix[di]
xchg ax, matrix[di]
xchg ax, matrix[si]
add si, 2*(N+1) ;смещаем на следующий диагональный
sub di, 2*(N+1) ;смещаем на предыдущий диагональный
jmp ChangeLoop ;на следующий обмен
ChangeEnd:

Поэтому измененную матрицу смотрим после его отработки.
В-четвертых, как работает... Да очень просто...
Пробегаем с двух сторон, с начала главной диагонали и с ее конца и меняем местами два элемента
Делаем это, пока адреса не "пересекутся".
Проверкой выхода из обмена является команда cmp si,di

И если индекс, который с начала главной диагонали меньше индекса с конца, то
меняем местами элементы.
После чего смещаемся на следующие элементы главной диагонали.
Обратите внимание, что везде смещения умножаются на 2. Это потому, что у нас слова, длина которых - 2 байта
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 18:05
общий
Адресаты:
Спасибо огромное за пояснение. Буду разбираться
давно
Посетитель
7438
7205
09.04.2012, 18:19
общий
Да, был еще вопрос, что значит системное время...
Команды
mov ah, 2ch
int 21h
запрашивают текущее время
Результат возвращается в регистрах
ch - секунды, cl - сотые секунды, dh - часы, dl - минуты
Для чего это сделано? Плюс еще некоторые преобразования...
Да чтобы получить наиболее "случайный" старт расчета случайных чисел...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 18:27
общий
Адресаты:
Понятно, а возможен вариант этой же программы, только с изменением, т.е ввод чисел вводится соответственно из самого файла, т.е. типа того:

dw 1, 2, 3, 4 ; 4 dup (?)

и т.д.
т.е. я так понимаю генератор случайных чисел придется убирать.

я отблагодарю.
давно
Посетитель
7438
7205
09.04.2012, 18:37
общий
Возможно все!
Да, для Вашего уровня знаний, генератор лучше убрать и задать данные самому...
Но все же рекомендую разобраться и в том варианте тоже... Может, чему-то научитесь...

Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 18:39
общий
Адресаты:
Ну да, я тоже так думаю, все таки хотелось бы научиться чему-нибудь.
давно
Посетитель
7438
7205
09.04.2012, 18:40
общий
09.04.2012, 18:50
Вот Вам вариант с данными в сегменте данных
От программы осталось только преобразование главной диагонали
Код:

.model small

N equ 5 ;размерность матрицы
.data
matrix dw 00h,01h,02h,03h,04h ;матрица 5*5 слов
dw 10h,11h,12h,13h,14h
dw 20h,21h,22h,23h,24h
dw 30h,31h,32h,33h,34h
dw 40h,41h,42h,43h,44h

.code
start:
mov ax, @data
mov ds, ax

;запишем главную диагональ в обратном порядке
xor si, si ;смещение элемента левого верхнего угла матрицы (самого первого)
mov di, 2*(N*N-1) ;смещение элемента правого нижнего угла матрицы (самого последнего)
ChangeLoop: ;по элементам главной диагонали
cmp si, di ;меняем, пока первый индекс меньше второго
jae ChangeEnd ;все сделано - на выход
mov ax, matrix[si] ;меняем местами matrix[si] и matrix[di]
xchg ax, matrix[di]
xchg ax, matrix[si]
add si, 2*(N+1) ;смещаем на следующий диагональный
sub di, 2*(N+1) ;смещаем на предыдущий диагональный
jmp ChangeLoop ;на проверку
ChangeEnd:

mov ax, 4c00h
int 21h

end start

Значения дал такие, чтобы было видно, на каком месте стоит элемент
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 18:49
общий
Адресаты:
Все таки не понимаю как значения диагонали выглядят в регистре(((
Неизвестный
09.04.2012, 18:52
общий
Адресаты:
Допустим вот эта диагональ

00h 11h 22h 33h 44h
давно
Посетитель
7438
7205
09.04.2012, 18:52
общий
Обратите внимание, я поменял модель память с tiny на small.
Вас, наверное, учили использовать small?
На автомате написал...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 18:53
общий
Адресаты:
Да, учили
давно
Посетитель
7438
7205
09.04.2012, 18:55
общий
"в регистре" О каком регистре идет речь?
Есть память, где хранится матрица, есть регистры, которые мы используем для доступа к нашей матрице.
Результат работы остается в памяти...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
09.04.2012, 18:58
общий
когда мы пишем mov ax, matrix[si], то мы загружаем элемент матрицы в регистр ax, что-то с ним делаем, меняем смещение в si и опять, теми же командами грузим в регистр ax новый элемент, т.к. адрес его будет уже другой (si изменен)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 18:59
общий
Адресаты:
Спасибо, теперь понятно.
давно
Посетитель
7438
7205
09.04.2012, 19:04
общий
Сведем все к вектору: диагональ - это фактически вектор...
vec= 00h 11h 22h 33h 44h - наш вектор,
В начале si = 0, di = 4 (индекс последнего элемента)
шаг 1: проверяем si<di
да, меняем местами 0 и 4 элемент, получаем:
vec= 44h 11h 22h 33h 00h
si = si+1 = 1, di = di-1 = 3
шаг 2: проверяем si<di
да, меняем местами 1 и 3 элемент, получаем:
vec= 44h 33h 22h 11h 00h
si = si+1 = 2, di = di-1 = 2
шаг 2: проверяем si<di
нет, выходим...
Я тут свел к байтам для простоты...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
09.04.2012, 19:06
общий
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 19:11
общий
Адресаты:
Если размерность матрицы поставить допустим 2*2 или 4*4 считать будет абсолютно так же?!
давно
Посетитель
7438
7205
09.04.2012, 19:15
общий
Адресаты:
Да, только не забудьте и данные матрицы оформить соответственно
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 20:31
общий
Адресаты:
А что значит соответственно?
И такой еще вопрос, что значит h в конце?
Можно без нее записать?

Глупый вопрос, но все же.
давно
Посетитель
7438
7205
09.04.2012, 23:23
общий
А то и значит, что для новой размерности необходимо правильно задать элементы,
чтобы на нужных местах стояли нужные числа. Например, придерживаясь того же принципа, для N=2, задаем:
matrix dw 00h, 01h
dw 10h, 11h

А h означает число в 16-ричной системе счисления...
Мне, например, намного удобнее работать именно в 16-ричной сс, чем в десятичной
Я даже порой быстрее складываю/вычитаю в уме, чем в десятичной
Можно, конечно, работать и в десятичной. В Вашем случае, никто не мешает задать числа, например, в виде
matrix dw 00,01,02,03,04
dw 10,11,12,13,14
dw 20,21,22,23,24
dw 30,31,32,33,34
dw 40,41,42,43,44
Но! При этом под отладчиком Вы не увидите,например, число 10, а число 0ah
(та же десятка, но в 16-ричной сс)!!! Т.к. отладчики предпочитают показывать в 16-ричной сс
Вы никогда не слышали о 16-ричной системе счисления? А о 8-ричной? Двоичной?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2012, 23:31
общий
Адресаты:
слышал конечно, просто поинтересовался)) спасибо еще раз огромное за ответ)))
Форма ответа