Циклический сдвиг элементов массива - Assembler
Формулировка задачи:
Дан массив размера N и число k (0 <k <5, k <N). Осуществить циклический сдвиг элементов массива влево и вправо на k позиций. Помогите, если не сложно, не могу разобрать как сделать. Для TASM
Нашел в книге, как инициализировать массив, но почему-то кривовато работает...
Листинг программы
- MODEL tiny
- .code
- org 100h
- .code
- main:
- mov ds,ax
- xor ax,ax ;обнуление ax
- mov cx,10 ;значение счетчика цикла в cx
- mov si,1 ;индекс начального элемента в cx
- go: ;цикл инициализации
- mov bh,i ;i в bh
- mov mas[si],bh ;запись в массив i
- inc i ;инкремент i
- inc si ;продвижение к следующему
- ;элементу массива
- loop go ;повторить цикл
- ;вывод на экран получившегося массива
- mov cx,10
- mov si,0
- mov ah,09h
- lea dx,mes
- int 21h
- show:
- mov ah,02h ;функция вывода значения
- ;из al на экран
- mov dl,mas[si]
- add dl,30h ;преобразование числа в символ
- int 21h
- inc si
- loop show
- exit:
- mov ax,4c00h ;стандартный выход
- int 21h
- mes db 0ah,0dh,'Массив- ','$'
- mas db 10 dup (?) ;исходный массив
- i db 0
- end main ;конец программы
Решение задачи: «Циклический сдвиг элементов массива»
textual
Листинг программы
- org 100h
- jmp start
- mes0 db 13,10,'Type array: $'
- mes1 db 13,10,' Direction: $'
- mes2 db 13,10,' Offset: $'
- mes3 db 13,10,'--------------------------'
- db 13,10,' Result: $'
- array db 9 dup(0)
- direc db 0
- offs db 0
- ;---------------------------; заполняем массив
- start: mov dx,mes0 ;
- call message ;
- mov cx,9 ;
- mov di,array ;
- mov ah,1 ;
- save1: int 21h ;
- stosb ;
- loop save1 ;
- ;---------------------------; читаем направление сдвига
- mov dx,mes1 ;
- call message ;
- save2: xor ax,ax ;
- int 16h ;
- cmp al,'R' ; R
- je @@1 ;
- cmp al,'L' ; L
- jne save2 ;
- @@1: int 29h ;
- mov [direc],al ;
- ;---------------------------; на сколько позиций сдвигать
- mov dx,mes2 ;
- call message ;
- save3: xor ax,ax ;
- int 16h ;
- cmp al,'1' ; min.1
- jb save3 ;
- cmp al,'8' ; max.8
- ja save3 ;
- int 29h ;
- and al,0Fh ;
- mov [offs],al ;
- ;---------------------------; основная процедура сдвига
- cld ; прямой шаг
- shl ax,16 ; очищаем АХ
- shr bh,8 ; очищаем BH
- mov bl,[offs] ; счётчик внешнего цикла
- mov si,array ; указатели на массив
- mov di,si ; ^
- cmp [direc],'L' ; если нужно влево,
- je begin ; ..то оставляем прямой шаг
- std ; иначе: реверс
- add si,8 ; ..и указатели в конец
- mov di,si ;
- begin: push di si ; запомним позицию
- mov cx,8 ; счётчик внутреннего цикла
- lodsb ; запоминаем в AH первый элемент
- shl ax,8 ; приёмник отстал на 1
- write: lodsb ; читаем сл.элемент
- stosb ; ..и записываем его в приёмник
- loop write ; мотаем 8 раз..
- shr ax,8 ; берём первый элемент в AL
- stosb ; ..и ставим его последним
- pop si di ; восстановим указатели
- dec bx ; ..и мотаем внешн.цикл
- jnz begin ;
- ;---------------------------; выводим массив на экран
- cld ;
- mov dx,mes3 ;
- call message ;
- mov cx,9 ; всего 9 элементов
- mov si,array ;
- print: lodsb ;
- int 29h ; вывести символ на консоль
- loop print ;
- exit: xor ax,ax ;
- int 16h ;
- ret ;
- ;нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн
- message:
- mov ah,9
- int 21h
- ret
Объяснение кода листинга программы
В данном коде реализован циклический сдвиг элементов массива. Список действий:
- Задаются начальные значения переменных и заполняется массив.
- Считывается направление сдвига (вправо или влево).
- Определяется на сколько позиций необходимо сдвинуть элементы массива.
- Выполняется основной цикл сдвига. Если необходимо сдвинуть элементы влево, то устанавливается прямой шаг, иначе — реверс.
- Выполняется цикл вывода элементов массива на экран.
- Выполняется завершающая обработка и выход из программы. Количество элементов в массиве — 9.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д