Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %include "io.inc"
- CEXTERN malloc
- CEXTERN free
- CEXTERN printf
- CEXTERN scanf
- ;ЗАМЕЧАНИЕ:
- ;Элемента списка это 8 байт, где первые 4 байта это ключ, а вторые 4 это ссылка на следующий элемент списка.
- section .bss
- begin resd 1 ;Начало списка
- number resd 1 ;Переменная для считывания числа
- section .rodata
- scanf_int db "%d", 0 ;Строка-формат для считывания числа
- printf_int db "%d ", 0 ;Строка-формат для вывода числа
- printf_per db `\n`, 0 ;Строка-формат для вывода переноса строки
- section .text
- global CMAIN
- CMAIN:
- push ebp
- mov ebp, esp
- ;Прыгаем по стекку на 16 байт, для того, чтобы можно было вставлять аргументы функции.
- sub esp, 16
- ;Изначально список пустой.
- mov dword[begin], 0
- ;Задаем аргументы функции. (Аналог в Си - printf("%d", &number) )
- mov dword[esp+4], number
- mov dword[esp], scanf_int
- ;Так как список будет сортироваться, то без разницы как вставим в него элементы, поэтому
- ;каждый новый элемент вставляем в начало списка.
- .begin_for_scanf:
- ;Вызов функции scanf
- call scanf
- ;Если функция вернула число отличное от 1, то выходим из цикла.
- cmp eax, 1
- jnz .end_for_scanf
- ;Вызов функции .insert_element. (Аналог в Си - insert_element(number, begin))
- push dword[begin]
- push dword[number]
- call .insert_element
- ;Удаляем из стека аргументы функции .insert_element
- add esp, 8
- ;Изменяем начало списка.
- mov dword[begin], eax
- jmp .begin_for_scanf
- .end_for_scanf:
- ;Сортировка списка алгоритмом выбора.
- ;eax - переменная для внешнего цикла.
- ;ebx - переменная для внутреннего цикла.
- ;edx - текущий минимальный элемент.
- mov eax, dword[begin]
- ;Внешний цикл:
- .begin_for_one:
- ;Ищем значение минимального элемента, которые правее текущего элемента.
- mov ebx, eax
- mov edx, eax
- ;Внутрений цикл:
- .begin_for_two:
- ;Если ключ элемнента ebx миньше ключа минимального элемента (edx), то изменяем указатель на минимальный элемент.
- mov ecx, dword[edx]
- cmp ecx, dword[ebx]
- jle .not_change_min
- mov edx, ebx
- .not_change_min:
- ;Переход к следующему элементу списка если он есть.
- mov ebx, dword[ebx+4]
- cmp ebx, 0
- jnz .begin_for_two
- ;Обмениваем ключи текущего элемента списка (eax) с ключем минимального элемента списка (edx)
- mov ecx, dword[edx]
- mov esi, dword[eax]
- mov dword[edx], esi
- mov dword[eax], ecx
- ;Переход к следующему элементу списка если он есть.
- mov eax, dword[eax+4]
- cmp eax, 0
- jnz .begin_for_one
- ;Задаем формат-строку для вывода целых чисел.
- mov dword[esp], printf_int
- ;В цикле проходим по списку и выводим ключ каждого элемента.
- mov ebx, dword[begin]
- .begin_for_printf:
- mov eax, dword[ebx]
- mov dword[esp+4], eax
- call printf
- mov ebx, dword[ebx+4]
- cmp ebx, 0
- jnz .begin_for_printf
- ;Вывод переноса строки
- mov dword[esp], printf_per
- call printf
- ;Очистка динамически выделенной памяти для списка.
- ;Проходим в цикле по всему списку и для каждого элемента вызываем функцию free.
- mov ebx, dword[begin]
- .begin_for_free:
- mov dword[esp], ebx
- mov ebx, dword[ebx+4]
- call free
- cmp ebx, 0
- jnz .begin_for_free
- leave
- xor eax, eax
- ret
- ;Функция вставки элемента.
- ;Первый аргумент - значение элемента.
- ;Второй аргумент - следующий элемент в списке.
- ;
- ;Возвращаемое значение - указатель на элемент.
- .insert_element:
- push ebp
- mov ebp, esp
- ;Сохраняем значение регистра ebx
- push ebx
- ;Выделяем 8 байт памяти.
- sub esp, 16
- mov dword[esp], 8
- call malloc
- ;Задаем значение нового элемента.
- mov ebx, dword[ebp+8]
- mov dword[eax], ebx
- ;Задаем ссылку на следующий элемент.
- mov ebx, dword[ebp+12]
- mov dword[eax+4], ebx
- ;Вспоминаем значение регистра ebx
- pop ebx
- leave
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement