Блочная сортировка как реализовать? - Assembler

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

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

Нужна помощь в реализации алгоритма сортировки bucket sort на ассемблере x86 тасм

Решение задачи: «Блочная сортировка как реализовать?»

textual
Листинг программы
  1. LOCALS
  2.  
  3. .model small, NOLANGUAGE
  4.  
  5. .stack 1024h
  6.  
  7. .data
  8.         CrLf    db      0Dh, 0Ah, '$'
  9.  
  10.         A       dw      4, 25, 45, 11, 15, 73, 53, 59, 25, 23, 27, 99, 7
  11.         ArSize  equ     ($-A)/2
  12.  
  13.         hor     equ     10      ;т.к. остатки от деления на 10 в диапазоне 0..9
  14.         ver     equ     ArSize+1
  15.  
  16. .code
  17.  
  18. main    proc
  19.         mov     ax,     @data
  20.         mov     ds,     ax
  21.         ;вывод исходного массива
  22.         mov     cx,     ArSize
  23.         lea     dx,     A
  24.         call    ShowArray
  25.         mov     ah,     09h
  26.         lea     dx,     CrLf
  27.         int     21h
  28.  
  29.         ;обработка - сортировка массива
  30.         mov     cx,     ArSize
  31.         lea     dx,     A
  32.         call    bucketSort
  33.  
  34.         ;вывод результата - отсортированного массива
  35.         call    ShowArray
  36.         mov     ah,     09h
  37.         lea     dx,     CrLf
  38.         int     21h
  39.  
  40.         mov     ax,     4C00h
  41.         int     21h
  42. main    endp
  43.  
  44. ;блочная сортировка массива слов
  45. ;на входе
  46. ; cx    - длина массива
  47. ; ds:dx - указатель на массив
  48. bucketSort      proc
  49. ;объявление переменных
  50. LOCAL   buckets:word:(hor*ver), X:word, Count:word, Ten:word;
  51. ;выделение памяти в стеке под переменные (т.к. язык не указан - делаем вручную)
  52.         push    bp
  53.         mov     bp,     sp
  54.         sub     sp,     hor*ver*2+3*2   ;размер локальных переменных
  55.         ;сохранение регистров
  56.         push    ax
  57.         push    bx
  58.         push    cx
  59.         push    dx
  60.         push    si
  61.         push    di
  62.         ;вспомогательная переменная
  63.         mov     Ten,    10
  64.         ;for(x=1; x<=100; x *= 10)
  65.         mov     X,      1
  66. @@ForX:
  67.         ;всем элементам buckets присваиваем метку "не использовалось" значение (-1)
  68.         push    cx
  69.         push    es
  70.         push    ss
  71.         pop     es
  72.         mov     ax,     -1
  73.         lea     di,     ss:buckets
  74.         mov     cx,     (hor*ver)
  75.         rep     stosw
  76.         pop     es
  77.         pop     cx
  78.  
  79.         ;count = 0      //обнуляем счётчик ячеек исходного массива чисел
  80.         ;на самом деле Count - смещение в исходном массиве, а не просто индекс
  81.         mov     Count,  0
  82.         ;for(i=0; i < size; i++)
  83.         push    cx
  84.         push    dx
  85.         mov     bx,     dx      ;задание базы для обращения к исходному массиву
  86.         mov     si,     0       ;i=0
  87.         @@ForI:
  88.                 mov     ax,     [bx+si] ;ax=array[i]
  89.                 mov     dx,     0       ;temp=array[i] / x
  90.                 div     X
  91.                 mov     dx,     0       ;oststok = temp % 10
  92.                 div     Ten
  93.                 mov     ax,     dx      ;ax - остаток от деления
  94.  
  95.                 mov     di,     hor*2   ;получаем смещение в двумерном массиве
  96.                 mul     di
  97.                 add     ax,     si
  98.                 mov     di,     ax      ;di = смещение, соответствующее bucket[ostatok][i]
  99.  
  100.                 mov     ax,     [bx+si] ;ax = array[i]
  101.                 mov     buckets[di],ax  ;buckets[oststok][i] = array[i]
  102.  
  103.                 add     si,     2       ;i++ (т.к. si - смещение, то увеличиваем на размер элемента)
  104.         loop    @@ForI
  105.         pop     dx
  106.         pop     cx
  107.  
  108.         ;вложенные циклы по всем элементам buckets проще представить
  109.         ;одним циклом по всем элементам с индексом от 0 до (hor*ver-1)
  110.         ;т.к. ячейки двумерного массива располагаются в памяти последовательно и
  111.         ;построчно
  112.         ;for(i=0; i<hor; i++)
  113.         ;  for(j=0; j<ver;j++)
  114.         push    cx
  115.         push    dx
  116.         mov     cx,     (hor*ver)
  117.         mov     di,     0
  118.         mov     bx,     dx
  119.         @@ForIJ:
  120.                 mov     ax,     buckets[di]     ;if (buckets[i][j] != -1
  121.                 cmp     ax,     -1
  122.                 je      @@Skip
  123.                 mov     si,     Count           ;  array[count] = bucket[i][j]
  124.                 mov     [bx+si],        ax
  125.                 add     Count,  2               ;  count++
  126.         @@Skip:
  127.                 add     di,     2               ;i++, j++
  128.         loop    @@ForIJ
  129.         pop     dx
  130.         pop     cx
  131.  
  132.         mov     ax,     X       ;X:= X*10
  133.         add     ax,     ax      ;ax = 2*X
  134.         mov     bx,     ax      ;bx = 2*X
  135.         add     ax,     ax
  136.         add     ax,     ax      ;ax= 8*X
  137.         add     ax,     bx      ;ax = 10*X
  138.         mov     X,      ax
  139.  
  140.         cmp     X,      100
  141.         ja      @@BreakForX
  142.         jmp     @@ForX
  143.  
  144. @@BreakForX:
  145.  
  146.         ;восстановление регистров
  147.         pop     di
  148.         pop     si
  149.         pop     dx
  150.         pop     cx
  151.         pop     bx
  152.         pop     ax
  153.         ;освобождение памяти от локальных переменных
  154.         mov     sp,     bp
  155.         pop     bp
  156.         ;возврат из процедуры и освобождение памяти от аргументов
  157.         ret     0
  158. bucketSort      endp
  159.  
  160. ;Вывод массива слов
  161. ;cx - количество выводимых элементов
  162. ;ds:dx - адрес массива
  163. ShowArray       proc
  164.         push    ax
  165.         push    bx
  166.         push    cx
  167.         push    dx
  168.         push    si
  169.         push    di
  170.  
  171.         jcxz    @@Exit          ;если массив пустой - завершить
  172.  
  173.         mov     si,     1       ;индекс элемента массива
  174.         mov     di,     dx      ;адрес текущего элемента массива
  175.         @@ForI:
  176.                 mov     ax,     [di]
  177.                 call    Show_AX
  178.                 mov     ah,     02h
  179.                 mov     dl,     ' '
  180.                 int     21h
  181.                 ;переход к следующему элементу
  182.                 inc     si
  183.                 add     di,     2
  184.         loop    @@ForI
  185. @@Exit:
  186.         pop     di
  187.         pop     si
  188.         pop     dx
  189.         pop     cx
  190.         pop     bx
  191.         pop     ax
  192.         ret
  193. ShowArray       endp
  194.  
  195. ; выводит число из регистра AX на экран
  196. ; входные данные:
  197. ; ax - число для отображения
  198. Show_AX proc
  199.         push    ax
  200.         push    bx
  201.         push    cx
  202.         push    dx
  203.         push    di
  204.  
  205.         mov     cx, 10
  206.         xor     di, di          ; di - кол. цифр в числе
  207.  
  208.         ; если число в ax отрицательное, то
  209.         ;1) напечатать '-'
  210.         ;2) сделать ax положительным
  211.         or      ax, ax
  212.         jns     @@Conv
  213.         push    ax
  214.         mov     dx, '-'
  215.         mov     ah, 2           ; ah - функция вывода символа на экран
  216.         int     21h
  217.         pop     ax
  218.  
  219.         neg     ax
  220.  
  221. @@Conv:
  222.         xor     dx, dx
  223.         div     cx              ; dl = num mod 10
  224.         add     dl, '0'         ; перевод в символьный формат
  225.         inc     di
  226.         push    dx              ; складываем в стэк
  227.         or      ax, ax
  228.         jnz     @@Conv
  229.         ; выводим из стэка на экран
  230. @@Show:
  231.         pop     dx              ; dl = очередной символ
  232.         mov     ah, 2           ; ah - функция вывода символа на экран
  233.         int     21h
  234.         dec     di              ; повторяем пока di<>0
  235.         jnz     @@Show
  236.  
  237.         pop     di
  238.         pop     dx
  239.         pop     cx
  240.         pop     bx
  241.         pop     ax
  242.         ret
  243. Show_AX endp
  244.  
  245. end     main

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

  1. Объявление секции LOCALS для определения локальных переменных
  2. Определение модели выполнения программы и размера стека
  3. Инициализация переменных в секции .data, включая массив A, содержащий 13 заранее заданных значений, и другие переменные.
  4. Инициализация процедуры main
  5. Загрузка адресного регистра ds и первоначальные шаги вывода исходного массива
  6. Сортировка массива с помощью процедуры bucketSort
  7. Вывод отсортированного массива
  8. Выход из программы Процедура bucketSort:
  9. Объявление локальных переменных
  10. Выделение памяти в стеке под переменные и сохранение регистров
  11. Производится блочная сортировка массива слов по указанной логике
  12. Восстановление регистров и освобождение памяти от локальных переменных Процедура ShowArray:
  13. Вывод массива слов на экран Процедура Show_AX:
  14. Подготовка числа для отображения (поиск количества цифр в числе и обработка отрицательных чисел)
  15. Вывод числа на экран, конвертированного в символьный формат Реализация программы заканчивается секцией end и выходом из процесса main.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

12   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут