Циклический сдвиг элементов массива - 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

Объяснение кода листинга программы

В данном коде реализован циклический сдвиг элементов массива. Список действий:

  1. Задаются начальные значения переменных и заполняется массив.
  2. Считывается направление сдвига (вправо или влево).
  3. Определяется на сколько позиций необходимо сдвинуть элементы массива.
  4. Выполняется основной цикл сдвига. Если необходимо сдвинуть элементы влево, то устанавливается прямой шаг, иначе — реверс.
  5. Выполняется цикл вывода элементов массива на экран.
  6. Выполняется завершающая обработка и выход из программы. Количество элементов в массиве — 9.

Оцени полезность:

13   голосов , оценка 4.077 из 5
Похожие ответы