Можно ли избежать цикла для вывода DW данных - Assembler

Узнай цену своей работы

Формулировка задачи:

Задача: сделать сортировку массива. [complect!] Но эти

массивы (начальный и конечный [отсортированный])

еще

нужно вывести

, я конечно хотел как строку все это показать, моим мега-макросом:
printstr macro s:req
    mov ah, 09h
    mov dx, offset s
    int 21h
endm
Но как и многие другие мои идеи в Ассемблере часто не нравятся компилятору Собственно код:
data segment para public    ; Обьявление сегмента данных
N dw 5                      ; Размерность массива
M dw 5, 2, 1, 11, 6         ; Массив
data ends

; Сегмент стека
stck segment para stack
dw 32 dup(?)
stck ends

; Сегмент кода
code segment para public
assume cs:code, ds:data, ss:stck

start:
    ; инициализация регистра DS 
    mov ax, data
    mov ds, ax
    ;---------ТЕЛО ПРОГРАММЫ----------
  
        mov bp,N                ; Размерность массива в регистр bp
C:                              ; Метка C
    mov cx, N                   ; Размерность массива в регистр CX (счетчик)
    dec cx                      ; Уменьшение значения CX
    lea bx, M                   ; Адрес массива в регистр bx
        xor si, si              ; Обнуляем регистр-индекс
                        
B:                              ; Метка B
    mov ax, [bx + si]           ; В регистр AX записываем адрес элемента массива со смещением
    mov di, si                  ; Запись занчения SI В регистр DI
    
A:                              ; Мета А
        add di, 2               ; Добавляем 2 к значению регистра DI
        mov dx, [bx + di]       ; Помещаем в регистр DX адрес элемента массива
 
        cmp ax, dx              ; Сравниваем занчения в регистрах ax,dx
        jl SKIP_ACTION          ; Если значение dx меньше переход по метке SKIP_ACTION
            mov [bx+di], ax     ; Если условие не выполнено ...
            mov [bx+si], dx     ; ...меняем местами элементы массива
            
    SKIP_ACTION:                ; метка SKIP_ACTION
 
     mov dx, N                  ; Запись размерность массива в регистр DX
     shl dx, 1                  ;  Cдвига разряд DX влево.
     cmp di, dx                 ; Сравниваем значения в регистрах di,dx
     jnl  A                     ; Если значение DX не меньше то переход по метки A
     add si, 2                  ; Добавляем 2 к значению регистра SI
     loop B                     ; Запуск цикла с метки B
         xor si, si             ; Обнуляем регистры
         xor di, di             ; Обнуляем регистры
         dec bp                 ; Уменьшаем значение BP
         cmp bp,0               ; Сравниваем значение регистра BP с нулем
         jne c                  ; Если не равно переходим по метки C

         mov ah,1               
         int 21h
         
         ;команды завершения программы
         ;mov ax, 4CH
         ;int 21h

code ends
end start
Массив

M

. В иннете лазию, нашел только решения с циклами. Неужели нет способа как-то проще показать в консоле что "мой" алгоритм сортировке работает??

Решение задачи: «Можно ли избежать цикла для вывода DW данных»

textual
Листинг программы
data segment para public    ; Обьявление сегмента данных
N dw 5                      ; Размерность массива
M dw 5, 2, 1, 11, 6         ; Массив
messageSource DB "Source array:",10,13,"$"
data ends
 
 
printstr macro s:req
    mov ah, 09h
    mov dx, offset s
    int 21h
endm
 
OutInt proc
    aam 
   add ax,3030h 
    mov dl,ah 
   mov dh,al 
   mov ah,02 
   int 21h 
   mov dl,dh 
    int 21h
OutInt endp
 
 
 
; Сегмент стека
stck segment para stack
dw 32 dup(?)
stck ends
 
 
; Сегмент кода
code segment para public
assume cs:code, ds:data, ss:stck
 
 
start:
    ; инициализация регистра DS 
    mov ax, data
    mov ds, ax
    ;---------ТЕЛО ПРОГРАММЫ----------
    
    ; Вывод исходного массива
    printstr messageSource      ; Сообщение пользователю
    ;MOV AX, offset M
    ;call OutInt
    
    ; ------------------- NEW CODE ------------------------
    lea bx, M                  ; Адрес массива в регистр bx
    xor si, si              ; Обнуляем регистр-индекс
 
showMess: ; тут начало цикла
 
push CX ; не уверен что CX сохранится после всех пертурбаций в ПП и функции поэтому в стек её
push BX ; см пред. комент
push SI ; см пред. комен
    mov ax, [bx + si]           ; В регистр AX записываем  элемент массива со смещением по адресу в bx + si
;  а не сам адрес
call OutInt ; за один проход ПП обрабатывает только одно слово массива
 
pop SI ; достаём что прятали
pop BX ; только в обратной
pop CX ; последовательности
add SI, 2 ; Добавляем 2 к значению регистра SI
loop showMess ; если CX не ноль - возврат на метку
; ---------------- END of new code ----------------------
    
    
    
  
        mov bp,N                ; Размерность массива в регистр bp
C:                              ; Метка C
    mov cx, N                   ; Размерность массива в регистр CX (счетчик)
    dec cx                      ; Уменьшение значения CX
    lea bx, M                   ; Адрес массива в регистр bx
        xor si, si              ; Обнуляем регистр-индекс
                        
B:                              ; Метка B
    mov ax, [bx + si]           ; В регистр AX записываем адрес элемента массива со смещением
    mov di, si                  ; Запись занчения SI В регистр DI
    
A:                              ; Мета А
        add di, 2               ; Добавляем 2 к значению регистра DI
        mov dx, [bx + di]       ; Помещаем в регистр DX адрес элемента массива
 
        cmp ax, dx              ; Сравниваем занчения в регистрах ax,dx
        jl SKIP_ACTION          ; Если значение dx меньше переход по метке SKIP_ACTION
            mov [bx+di], ax     ; Если условие не выполнено ...
            mov [bx+si], dx     ; ...меняем местами элементы массива
            
    SKIP_ACTION:                ; метка SKIP_ACTION
 
     mov dx, N                  ; Запись размерность массива в регистр DX
     shl dx, 1                  ;  Cдвига разряд DX влево.
     cmp di, dx                 ; Сравниваем значения в регистрах di,dx
     jnl  A                     ; Если значение DX не меньше то переход по метки A
     add si, 2                  ; Добавляем 2 к значению регистра SI
     loop B                     ; Запуск цикла с метки B
         xor si, si             ; Обнуляем регистры
         xor di, di             ; Обнуляем регистры
         dec bp                 ; Уменьшаем значение BP
         cmp bp,0               ; Сравниваем значение регистра BP с нулем
         jne c                  ; Если не равно переходим по метки C
 
 
 
         mov ah,1               
         int 21h
         
         ;команды завершения программы
         mov ax, 4CH
         int 21h
 
    
 
code ends
end start

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

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