;необходимо повернуть внешнею часть матрицы по часовой стрелки,
;внутреннею против.
; 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
PrintMatrix 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 ;строка
call 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
stoi 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
А можно ли...
Калашников О.А. Ассемблер? Это просто! Учимся программировать
Справочник по системе программирования Турбо Ассемблер
Assembler IBM PC
Очень полезная информация
Ralf Brown's Interrupt List
Сайт Владислава Пирогова
Зубков С.В. Ассемблер для DOS, Windows и Unix
Кулаков В. Программирование на аппаратном уровне
Рихтер Дж. Создание эффективных WIN32-приложений
Петцольд Ч. Программирование для Windows 95
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.