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

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


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

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

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

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

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

Номер выпуска:1381
Дата выхода:12.11.2010, 13:30
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:224 / 66
Вопросов / ответов:1 / 1

Вопрос № 180597: Здравствуйте дорогие эксперты. Пожалуйста помоги те в написание программы. Задание такое " необходимо повернуть внешнею часть матрицы по часовой стрелки,внутреннею против. матрица 5х5" Элементы матрицы определенны за ранее, и находятс...



Вопрос № 180597:

Здравствуйте дорогие эксперты.
Пожалуйста помоги те в написание программы.
Задание такое " необходимо повернуть внешнею часть матрицы по часовой стрелки,внутреннею против. матрица 5х5" Элементы матрицы определенны за ранее, и находятся в таком порядке .
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
.
В помощь могу предоставить программу написанную на С++. "хотел разобраться и поэтому решил что в си это будет проще, окозалось что так и есть а вот переоформить не смог."
необходимое условие данного задания это использование стека.

Отправлен: 07.11.2010, 13:16
Вопрос задал: Константин (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, Константин!
Можно cделать по разному. Я реализовал следующий алгоритм:
Рассматриваем четыре позиции в матрице (по углам меняемых областей)
Затем циклически меняем их местами. Сдвигая "углы" соответственно вправо, вниз, влево, вверх,
проходим по всем элементам области матрицы. Запись элементов матрицы реализовано с помощью push/pop
Разрядность (разрешено от 5 до 10) и матрицу вводим с клавиатуры.
Вводить числа можно, как разделенные, например, пробелами, так и в разных строках.
Удобно вводить построчно...
Ну и реализован вывод матрицы на экран.
Код:
;необходимо повернуть внешнею час
 ть матрицы по часовой стрелки,
;внутреннею против.
; 1 2 3 4 5
; 6 7 8 9 10
;11 12 13 14 15
;16 17 18 19 20
;21 22 23 24 25
;конечный результат.
;21 16 11 6 1
;22 9 14 19 2
;23 8 13 18 3
;24 7 12 17 4
;25 20 15 10 5

.model tiny

.data
sGet db 'Enter matrix capacity: $' ;приглашение для ввода размерности
sMatrix db 0ah,'Enter matrix (row by row):',0dh,'$';приглашение для ввода элементов
sSource db 0ah,0ah,'Source matrix:',0dh,0ah,'$'
sResult db 0ah,'Result matrix:',0dh,0ah,'$'
sPress db 0ah,'Press any key for exit$'
sError db 0ah,0ah,'Capacity may be >=5 and <=10',0dh,0ah,0ah,'$'

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

N dw ? ;размерность матрицы
array label word ;матрица (разместим в конце)

.code
.startup

repeat:
call GetMatrix ;введем матрицу
jz continue
lea dx, sError ;сообщение об ошибке
mov ah, 9
int 21h
jmp repeat

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

;вращаем внешний край матрицы по часовой стрелке
xor bx, bx ;смещение левого верхнего угла (ЛВ)
mov ax, N
dec ax
mov cx, ax ;N-1 = число обменов в строке
mov si, ax
shl si, 1 ;(N-1)*2 = смещение правого верхнего угла (ПВ)
mul N
shl ax, 1
mov bp, ax ;N*(N-1)*2 = смещение левого нижнего угла (ЛН)
mov ax, N
mul N
dec ax
shl ax, 1
mov di, ax ;(N*N-1)*2 = смещение правого нижнего угла (ПН)
OutRightLoop:
push array[bx] ;сохраним ЛВ
push array[bp]
pop array[bx] ;ЛВ = ЛН
push array[di]
pop array[bp] ;ЛН = ПН
push array[si]
pop array[di] ;ПН = ПВ
pop array[si] ;ПВ = ЛВ
add bx, 2 ;сд винем ЛВ на 1 вправо
add si, N
add si, N ;сдвинем ПВ на 1 вниз
sub di, 2 ;сдвинем ПН на 1 влево
sub bp, N
sub bp, N ;сдвинем ЛН на 1 вверх
loop OutRightLoop ;повторим N-1 раз

;вращаем внутреннюю часть против часовой
mov bx, N
inc bx
shl bx, 1 ;(N+1)*2 = смещение левого верхнего угла внутренней части (ЛВ)
mov si, N
shl si, 1
dec si
dec si
shl si, 1 ;(2*N-2)*2 = смещение правого верхнего угла внутренней части (ПВ)
mov ax, N
dec ax
mul N
dec ax
dec ax
shl ax, 1
mov di, ax ;(N*(N-1)-2)*2 = смещение правого нижнего угла внутренней части (ПН)
mov ax, N
dec ax
dec ax
mul N
inc ax
shl ax, 1
mov bp, ax ;(N*(N-2)+1)*2 = смещение левого нижнего угла внутренней части (ЛН)
mov cx, N
sub cx, 3 ;N-3 = число обменов в строке
InLeftLoop:
push array[bx] ;сохраним ЛВ
push array[si]
pop array[bx] ;ЛВ = ПВ
push array[di]
pop array[si] ;ПВ = ПН
push array[bp]
pop array[di] ;ПН = ЛН
pop array[bp] ;ЛН = ЛВ
add bx, N
add bx, N ;сдвинем ЛВ на 1 вниз
sub si , 2 ;сдвинем ПВ на 1 влево
sub di, N
sub di, N ;сдвинем ПН на 1 вверх
add bp, 2 ;сдвинем ЛН на 1 вправо
loop InLeftLoop ;повторим N-3 раз

lea dx, sResult ;выведем результат
call PrintMatrix

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 ;вывод матрицы NxN
mov ah, 9
int 21h ;вывод заголовока из dx

lea si, array ;адрес массива
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
Pri ntMatrix endp

PrintNum proc ;вывод беззнакового числа из ax
push 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
pop cx ;восстановим счетчик колонок матрицы
ret
PrintNum endp

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

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

lea si, sBuf ;строка
ca ll stoi ;преобразовываем в число
cmp ax, 5 ;проверим на корректность
jb GM_err
cmp ax, 10 ;ждем 5 <= N <= 10
ja GM_err
mov N, ax ;сохраняем размерность

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

lea di, array ;адрес массива

mov ax, N ;адрес за массивом (для контроля конца)
mul N
shl ax, 1
add ax, offset array
mov bp, ax ;сохраним в bp
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, bp ;массив заполнен?
je GM_ok

call stoi ;[si] в число
jcxz GM_ask ;дошли до конца строки?
stosw ;сохраняем
jmp GM_next ;на следующее число в строке
GM_err:
or ax, 1 ;FZ == 0 -> ошибка размерности
GM_ok:
ret ;FZ == 0 -> все ок
GetMatrix endp

st oi proc ;преобразование строки [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

end

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

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

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

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


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

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

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

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

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

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

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


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

    В избранное