Advertisement
intsashka

04-14_mer

May 9th, 2016
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. %include "io.inc"
  2.  
  3. CEXTERN malloc
  4. CEXTERN free
  5. CEXTERN printf
  6. CEXTERN scanf
  7.  
  8. ;ЗАМЕЧАНИЕ:
  9. ;Элемента списка это 8 байт, где первые 4 байта это ключ, а вторые 4 это ссылка на следующий элемент списка.
  10. section .bss
  11.     begin resd 1    ;Начало списка
  12.     number resd 1   ;Переменная для считывания числа
  13.  
  14. section .rodata
  15.     scanf_int db "%d", 0   ;Строка-формат для считывания числа
  16.     printf_int db "%d ", 0 ;Строка-формат для вывода числа
  17.     printf_per db `\n`, 0  ;Строка-формат для вывода переноса строки
  18.          
  19. section .text
  20. global CMAIN
  21. CMAIN:
  22.     push ebp
  23.     mov ebp, esp
  24.    
  25.     ;Прыгаем по стекку на 16 байт, для того, чтобы можно было вставлять аргументы функции.
  26.     sub esp, 16
  27.    
  28.     ;Изначально список пустой.
  29.     mov dword[begin], 0
  30.    
  31.     ;Задаем аргументы функции. (Аналог в Си - printf("%d", &number) )
  32.     mov dword[esp+4], number    
  33.     mov dword[esp], scanf_int
  34.  
  35. ;Так как список будет сортироваться, то без разницы как вставим в него элементы, поэтому
  36. ;каждый новый элемент вставляем в начало списка.
  37.  
  38.     .begin_for_scanf:
  39.         ;Вызов функции scanf
  40.         call scanf
  41.         ;Если функция вернула число отличное от 1, то выходим из цикла.
  42.         cmp eax, 1
  43.         jnz .end_for_scanf
  44.        
  45.         ;Вызов функции .insert_element. (Аналог в Си - insert_element(number, begin))
  46.         push dword[begin]
  47.         push dword[number]
  48.         call .insert_element
  49.         ;Удаляем из стека аргументы функции .insert_element
  50.         add esp, 8
  51.        
  52.         ;Изменяем начало списка.
  53.         mov dword[begin], eax
  54.                                
  55.         jmp .begin_for_scanf
  56.     .end_for_scanf:
  57.    
  58.     ;Сортировка списка алгоритмом выбора.
  59.     ;eax - переменная для внешнего цикла.
  60.     ;ebx - переменная для внутреннего цикла.
  61.     ;edx - текущий минимальный элемент.
  62.     mov eax, dword[begin]
  63.     ;Внешний цикл:
  64.     .begin_for_one:
  65.         ;Ищем значение минимального элемента, которые правее текущего элемента.
  66.         mov ebx, eax
  67.         mov edx, eax
  68.         ;Внутрений цикл:
  69.         .begin_for_two:
  70.             ;Если ключ элемнента ebx миньше ключа минимального элемента (edx), то изменяем указатель на минимальный элемент.
  71.             mov ecx, dword[edx]
  72.             cmp ecx, dword[ebx]
  73.             jle .not_change_min
  74.                 mov edx, ebx
  75.             .not_change_min:
  76.            
  77.             ;Переход к следующему элементу списка если он есть.
  78.             mov ebx, dword[ebx+4]
  79.             cmp ebx, 0
  80.             jnz .begin_for_two
  81.        
  82.         ;Обмениваем ключи текущего элемента списка (eax) с ключем минимального элемента списка (edx)
  83.         mov ecx, dword[edx]
  84.         mov esi, dword[eax]
  85.         mov dword[edx], esi
  86.         mov dword[eax], ecx
  87.        
  88.         ;Переход к следующему элементу списка если он есть.
  89.         mov eax, dword[eax+4]
  90.         cmp eax, 0
  91.         jnz .begin_for_one
  92.            
  93.    
  94.     ;Задаем формат-строку для вывода целых чисел.
  95.     mov dword[esp], printf_int
  96.    
  97.     ;В цикле проходим по списку и выводим ключ каждого элемента.
  98.     mov ebx, dword[begin]
  99.     .begin_for_printf:
  100.         mov eax, dword[ebx]
  101.         mov dword[esp+4], eax
  102.        
  103.         call printf
  104.        
  105.         mov ebx, dword[ebx+4]
  106.         cmp ebx, 0
  107.         jnz .begin_for_printf    
  108.    
  109.     ;Вывод переноса строки
  110.     mov dword[esp], printf_per
  111.     call printf
  112.    
  113.     ;Очистка динамически выделенной памяти для списка.
  114.     ;Проходим в цикле по всему списку и для каждого элемента вызываем функцию free.
  115.     mov ebx, dword[begin]
  116.     .begin_for_free:
  117.         mov dword[esp], ebx
  118.         mov ebx, dword[ebx+4]
  119.         call free
  120.         cmp ebx, 0
  121.         jnz .begin_for_free
  122.        
  123.     leave
  124.     xor eax, eax
  125.     ret
  126.    
  127.      
  128. ;Функция вставки элемента.
  129. ;Первый аргумент - значение элемента.
  130. ;Второй аргумент - следующий элемент в списке.
  131. ;
  132. ;Возвращаемое значение - указатель на элемент.    
  133. .insert_element:
  134.     push ebp
  135.     mov ebp, esp
  136.    
  137.     ;Сохраняем значение регистра ebx
  138.     push ebx
  139.    
  140.     ;Выделяем 8 байт памяти.
  141.     sub esp, 16
  142.     mov dword[esp], 8
  143.     call malloc
  144.     ;Задаем значение нового элемента.
  145.     mov ebx, dword[ebp+8]
  146.     mov dword[eax], ebx
  147.    
  148.     ;Задаем ссылку на следующий элемент.
  149.     mov ebx, dword[ebp+12]
  150.     mov dword[eax+4], ebx
  151.    
  152.     ;Вспоминаем значение регистра ebx
  153.     pop ebx
  154.    
  155.     leave
  156.     ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement