section .data
; Рядки для сортування (закінчуються нулем)
w1 db "Orange", 0
w2 db "Apple", 0
w3 db "Banana", 0
w4 db "Apricot", 0
w5 db "Zebra", 0
; Масив вказівників (адрес) на ці рядки
; Використовуємо dq (define quadword), бо адреси 64-бітні
ptr_array dq w1, w2, w3, w4, w5
; Обчислення кількості елементів
arr_len equ ($ - ptr_array) / 8
; Символ нового рядка для виводу
newline db 0xA
section .text
global _start
_start:
; --- 1. Сортування ---
; Передаємо параметри через стек: адресу масиву і довжину
push ptr_array
push arr_len
call bubble_sort
add rsp, 16 ; Очищаємо стек (2 аргументи * 8 байт)
; --- 2. Вивід результату ---
push ptr_array
push arr_len
call print_array
add rsp, 16 ; Очищаємо стек
; --- 3. Вихід з програми ---
mov rax, 60 ; sys_exit
xor rdi, rdi ; status 0
syscall
; ---------------------------------------------------------
; Процедура виводу (Print Array)
; Параметри в стеку: [rbp+16] = count, [rbp+24] = array pointer
; ---------------------------------------------------------
print_array:
push rbp
mov rbp, rsp
; Збережемо регістри, які будемо використовувати (callee-saved)
push rbx
push r12
mov rcx, [rbp + 16] ; Кількість слів
mov rbx, [rbp + 24] ; Адреса масиву
xor r12, r12 ; Індекс по масиву (0)
.p_loop:
push rcx ; Зберігаємо лічильник циклу
; Отримуємо вказівник на рядок: rsi = array[r12]
mov rsi, [rbx + r12*8]
; --- Рахуємо довжину рядка
(strlen) --- xor rdx, rdx ; RDX буде лічильником довжини
.calc_len:
cmp byte [rsi + rdx], 0 ; Чи кінець рядка?
je .do_print
inc rdx
jmp .calc_len
.do_print:
; --- Виводимо слово ---
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
; rsi вже має адресу рядка
; rdx вже має довжину
syscall
; --- Виводимо перенос рядка (\n) ---
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
pop rcx ; Відновлюємо лічильник циклу
inc r12 ; Наступний елемент масиву
dec rcx
jnz .p_loop
; Відновлюємо регістри
pop r12
pop rbx
mov rsp, rbp
pop rbp
ret
; ---------------------------------------------------------
; Процедура сортування (Bubble Sort)
; Параметри: [rbp+16] = count, [rbp+24] = array pointer
; ---------------------------------------------------------
bubble_sort:
push rbp
mov rbp, rsp
mov rcx, [rbp + 16] ; Кількість елементів
dec rcx ; N-1
cmp rcx, 0
jle .bs_done
mov rbx, [rbp + 24] ; Адреса масиву
.bs_outer:
push rcx
mov rdx, rcx ; Лічильник внутрішнього циклу
xor rsi, rsi ; Індекс (0)
.bs_inner:
; Завантажуємо два сусідні вказівники
mov rdi, [rbx + rsi*8] ; Вказівник 1
mov rax, [rbx + rsi*8 + 8] ; Вказівник 2
; Зберігаємо контекст перед викликом порівняння
push rsi
push rdx
push rcx
push rbx
push rax ; Зберігаємо RAX, бо він зміниться
mov rsi, rax ; Другий аргумент для str_compare
call str_compare
; Результат в RAX: >0 якщо рядок1 > рядок2
; Відновлюємо
pop r8 ; Це був старий rax (вказівник 2), забираємо в r8, щоб не затерти результат порівняння
pop rbx
pop rcx
pop rdx
pop rsi
cmp rax, 0
jle .bs_noswap ; Якщо порядок правильний, пропускаємо
; Обмін (Swap) вказівників у масиві
; rdi = ptr1, r8 = ptr2 (ми відновили його зі стеку)
mov [rbx + rsi*8], r8
mov [rbx + rsi*8 + 8], rdi
.bs_noswap:
inc rsi
dec rdx
jnz .bs_inner
pop rcx
loop .bs_outer
.bs_done:
mov rsp, rbp
pop rbp
ret
; ---------------------------------------------------------
; Порівняння рядків
(аналог
strcmp) ; Вхід: RDI = str1, RSI = str2
; Вихід: RAX > 0 якщо str1 > str2, < 0 якщо str1 < str2
; ---------------------------------------------------------
str_compare:
xor rax, rax
.cmp_loop:
mov al, byte [rdi]
mov bl, byte [rsi]
cmp al, bl
jne .cmp_diff ; Знайшли різницю
test al, al ; Чи кінець рядка (0)?
jz .cmp_equal ; Рядки ідентичні
inc rdi
inc rsi
jmp .cmp_loop
.cmp_diff:
sub al, bl
movsx rax, al ; Розширюємо результат до 64 біт зі знаком
ret
.cmp_equal:
xor rax, rax
ret
c2VjdGlvbiAuZGF0YQogICAgOyDQoNGP0LTQutC4INC00LvRjyDRgdC+0YDRgtGD0LLQsNC90L3RjyAo0LfQsNC60ZbQvdGH0YPRjtGC0YzRgdGPINC90YPQu9C10LwpCiAgICB3MSBkYiAiT3JhbmdlIiwgMAogICAgdzIgZGIgIkFwcGxlIiwgMAogICAgdzMgZGIgIkJhbmFuYSIsIDAKICAgIHc0IGRiICJBcHJpY290IiwgMAogICAgdzUgZGIgIlplYnJhIiwgMAogICAgCiAgICA7INCc0LDRgdC40LIg0LLQutCw0LfRltCy0L3QuNC60ZbQsiAo0LDQtNGA0LXRgSkg0L3QsCDRhtGWINGA0Y/QtNC60LgKICAgIDsg0JLQuNC60L7RgNC40YHRgtC+0LLRg9GU0LzQviBkcSAoZGVmaW5lIHF1YWR3b3JkKSwg0LHQviDQsNC00YDQtdGB0LggNjQt0LHRltGC0L3RlgogICAgcHRyX2FycmF5IGRxIHcxLCB3MiwgdzMsIHc0LCB3NQogICAgCiAgICA7INCe0LHRh9C40YHQu9C10L3QvdGPINC60ZbQu9GM0LrQvtGB0YLRliDQtdC70LXQvNC10L3RgtGW0LIKICAgIGFycl9sZW4gZXF1ICgkIC0gcHRyX2FycmF5KSAvIDgKCiAgICA7INCh0LjQvNCy0L7QuyDQvdC+0LLQvtCz0L4g0YDRj9C00LrQsCDQtNC70Y8g0LLQuNCy0L7QtNGDCiAgICBuZXdsaW5lIGRiIDB4QQoKc2VjdGlvbiAudGV4dAogICAgZ2xvYmFsIF9zdGFydAoKX3N0YXJ0OgogICAgOyAtLS0gMS4g0KHQvtGA0YLRg9Cy0LDQvdC90Y8gLS0tCiAgICA7INCf0LXRgNC10LTQsNGU0LzQviDQv9Cw0YDQsNC80LXRgtGA0Lgg0YfQtdGA0LXQtyDRgdGC0LXQujog0LDQtNGA0LXRgdGDINC80LDRgdC40LLRgyDRliDQtNC+0LLQttC40L3RgwogICAgcHVzaCBwdHJfYXJyYXkKICAgIHB1c2ggYXJyX2xlbgogICAgY2FsbCBidWJibGVfc29ydAogICAgYWRkIHJzcCwgMTYgICAgICA7INCe0YfQuNGJ0LDRlNC80L4g0YHRgtC10LogKDIg0LDRgNCz0YPQvNC10L3RgtC4ICogOCDQsdCw0LnRgikKCiAgICA7IC0tLSAyLiDQktC40LLRltC0INGA0LXQt9GD0LvRjNGC0LDRgtGDIC0tLQogICAgcHVzaCBwdHJfYXJyYXkKICAgIHB1c2ggYXJyX2xlbgogICAgY2FsbCBwcmludF9hcnJheQogICAgYWRkIHJzcCwgMTYgICAgICA7INCe0YfQuNGJ0LDRlNC80L4g0YHRgtC10LoKCiAgICA7IC0tLSAzLiDQktC40YXRltC0INC3INC/0YDQvtCz0YDQsNC80LggLS0tCiAgICBtb3YgcmF4LCA2MCAgICAgIDsgc3lzX2V4aXQKICAgIHhvciByZGksIHJkaSAgICAgOyBzdGF0dXMgMAogICAgc3lzY2FsbAoKOyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOyDQn9GA0L7RhtC10LTRg9GA0LAg0LLQuNCy0L7QtNGDIChQcmludCBBcnJheSkKOyDQn9Cw0YDQsNC80LXRgtGA0Lgg0LIg0YHRgtC10LrRgzogW3JicCsxNl0gPSBjb3VudCwgW3JicCsyNF0gPSBhcnJheSBwb2ludGVyCjsgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnByaW50X2FycmF5OgogICAgcHVzaCByYnAKICAgIG1vdiByYnAsIHJzcAogICAgCiAgICA7INCX0LHQtdGA0LXQttC10LzQviDRgNC10LPRltGB0YLRgNC4LCDRj9C60ZYg0LHRg9C00LXQvNC+INCy0LjQutC+0YDQuNGB0YLQvtCy0YPQstCw0YLQuCAoY2FsbGVlLXNhdmVkKQogICAgcHVzaCByYngKICAgIHB1c2ggcjEyCgogICAgbW92IHJjeCwgW3JicCArIDE2XSAgICAgOyDQmtGW0LvRjNC60ZbRgdGC0Ywg0YHQu9GW0LIKICAgIG1vdiByYngsIFtyYnAgKyAyNF0gICAgIDsg0JDQtNGA0LXRgdCwINC80LDRgdC40LLRgwogICAgeG9yIHIxMiwgcjEyICAgICAgICAgICAgOyDQhtC90LTQtdC60YEg0L/QviDQvNCw0YHQuNCy0YMgKDApCgoucF9sb29wOgogICAgcHVzaCByY3ggICAgICAgICAgICAgICAgOyDQl9Cx0LXRgNGW0LPQsNGU0LzQviDQu9GW0YfQuNC70YzQvdC40Log0YbQuNC60LvRgwogICAgCiAgICA7INCe0YLRgNC40LzRg9GU0LzQviDQstC60LDQt9GW0LLQvdC40Log0L3QsCDRgNGP0LTQvtC6OiByc2kgPSBhcnJheVtyMTJdCiAgICBtb3YgcnNpLCBbcmJ4ICsgcjEyKjhdCiAgICAKICAgIDsgLS0tINCg0LDRhdGD0ZTQvNC+INC00L7QstC20LjQvdGDINGA0Y/QtNC60LAgKHN0cmxlbikgLS0tCiAgICB4b3IgcmR4LCByZHggICAgICAgICAgICA7IFJEWCDQsdGD0LTQtSDQu9GW0YfQuNC70YzQvdC40LrQvtC8INC00L7QstC20LjQvdC4Ci5jYWxjX2xlbjoKICAgIGNtcCBieXRlIFtyc2kgKyByZHhdLCAwIDsg0KfQuCDQutGW0L3QtdGG0Ywg0YDRj9C00LrQsD8KICAgIGplIC5kb19wcmludAogICAgaW5jIHJkeAogICAgam1wIC5jYWxjX2xlbgoKLmRvX3ByaW50OgogICAgOyAtLS0g0JLQuNCy0L7QtNC40LzQviDRgdC70L7QstC+IC0tLQogICAgbW92IHJheCwgMSAgICAgICAgICAgICAgOyBzeXNfd3JpdGUKICAgIG1vdiByZGksIDEgICAgICAgICAgICAgIDsgc3Rkb3V0CiAgICA7IHJzaSDQstC20LUg0LzQsNGUINCw0LTRgNC10YHRgyDRgNGP0LTQutCwCiAgICA7IHJkeCDQstC20LUg0LzQsNGUINC00L7QstC20LjQvdGDCiAgICBzeXNjYWxsCgogICAgOyAtLS0g0JLQuNCy0L7QtNC40LzQviDQv9C10YDQtdC90L7RgSDRgNGP0LTQutCwIChcbikgLS0tCiAgICBtb3YgcmF4LCAxCiAgICBtb3YgcmRpLCAxCiAgICBtb3YgcnNpLCBuZXdsaW5lCiAgICBtb3YgcmR4LCAxCiAgICBzeXNjYWxsCgogICAgcG9wIHJjeCAgICAgICAgICAgICAgICAgOyDQktGW0LTQvdC+0LLQu9GO0ZTQvNC+INC70ZbRh9C40LvRjNC90LjQuiDRhtC40LrQu9GDCiAgICBpbmMgcjEyICAgICAgICAgICAgICAgICA7INCd0LDRgdGC0YPQv9C90LjQuSDQtdC70LXQvNC10L3RgiDQvNCw0YHQuNCy0YMKICAgIGRlYyByY3gKICAgIGpueiAucF9sb29wCgogICAgOyDQktGW0LTQvdC+0LLQu9GO0ZTQvNC+INGA0LXQs9GW0YHRgtGA0LgKICAgIHBvcCByMTIKICAgIHBvcCByYngKICAgIAogICAgbW92IHJzcCwgcmJwCiAgICBwb3AgcmJwCiAgICByZXQKCjsgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjsg0J/RgNC+0YbQtdC00YPRgNCwINGB0L7RgNGC0YPQstCw0L3QvdGPIChCdWJibGUgU29ydCkKOyDQn9Cw0YDQsNC80LXRgtGA0Lg6IFtyYnArMTZdID0gY291bnQsIFtyYnArMjRdID0gYXJyYXkgcG9pbnRlcgo7IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpidWJibGVfc29ydDoKICAgIHB1c2ggcmJwCiAgICBtb3YgcmJwLCByc3AKCiAgICBtb3YgcmN4LCBbcmJwICsgMTZdICAgICA7INCa0ZbQu9GM0LrRltGB0YLRjCDQtdC70LXQvNC10L3RgtGW0LIKICAgIGRlYyByY3ggICAgICAgICAgICAgICAgIDsgTi0xCiAgICBjbXAgcmN4LCAwCiAgICBqbGUgLmJzX2RvbmUKCiAgICBtb3YgcmJ4LCBbcmJwICsgMjRdICAgICA7INCQ0LTRgNC10YHQsCDQvNCw0YHQuNCy0YMKCi5ic19vdXRlcjoKICAgIHB1c2ggcmN4CiAgICBtb3YgcmR4LCByY3ggICAgICAgICAgICA7INCb0ZbRh9C40LvRjNC90LjQuiDQstC90YPRgtGA0ZbRiNC90YzQvtCz0L4g0YbQuNC60LvRgwogICAgeG9yIHJzaSwgcnNpICAgICAgICAgICAgOyDQhtC90LTQtdC60YEgKDApCgouYnNfaW5uZXI6CiAgICA7INCX0LDQstCw0L3RgtCw0LbRg9GU0LzQviDQtNCy0LAg0YHRg9GB0ZbQtNC90ZYg0LLQutCw0LfRltCy0L3QuNC60LgKICAgIG1vdiByZGksIFtyYnggKyByc2kqOF0gICAgIDsg0JLQutCw0LfRltCy0L3QuNC6IDEKICAgIG1vdiByYXgsIFtyYnggKyByc2kqOCArIDhdIDsg0JLQutCw0LfRltCy0L3QuNC6IDIKICAgIAogICAgOyDQl9Cx0LXRgNGW0LPQsNGU0LzQviDQutC+0L3RgtC10LrRgdGCINC/0LXRgNC10LQg0LLQuNC60LvQuNC60L7QvCDQv9C+0YDRltCy0L3Rj9C90L3RjwogICAgcHVzaCByc2kKICAgIHB1c2ggcmR4CiAgICBwdXNoIHJjeAogICAgcHVzaCByYngKICAgIHB1c2ggcmF4IDsg0JfQsdC10YDRltCz0LDRlNC80L4gUkFYLCDQsdC+INCy0ZbQvSDQt9C80ZbQvdC40YLRjNGB0Y8KICAgIAogICAgbW92IHJzaSwgcmF4IDsg0JTRgNGD0LPQuNC5INCw0YDQs9GD0LzQtdC90YIg0LTQu9GPIHN0cl9jb21wYXJlCiAgICBjYWxsIHN0cl9jb21wYXJlCiAgICA7INCg0LXQt9GD0LvRjNGC0LDRgiDQsiBSQVg6ID4wINGP0LrRidC+INGA0Y/QtNC+0LoxID4g0YDRj9C00L7QujIKCiAgICA7INCS0ZbQtNC90L7QstC70Y7RlNC80L4KICAgIHBvcCByOCAgOyDQptC1INCx0YPQsiDRgdGC0LDRgNC40LkgcmF4ICjQstC60LDQt9GW0LLQvdC40LogMiksINC30LDQsdC40YDQsNGU0LzQviDQsiByOCwg0YnQvtCxINC90LUg0LfQsNGC0LXRgNGC0Lgg0YDQtdC30YPQu9GM0YLQsNGCINC/0L7RgNGW0LLQvdGP0L3QvdGPCiAgICBwb3AgcmJ4CiAgICBwb3AgcmN4CiAgICBwb3AgcmR4CiAgICBwb3AgcnNpCgogICAgY21wIHJheCwgMAogICAgamxlIC5ic19ub3N3YXAgICAgICAgICAgOyDQr9C60YnQviDQv9C+0YDRj9C00L7QuiDQv9GA0LDQstC40LvRjNC90LjQuSwg0L/RgNC+0L/Rg9GB0LrQsNGU0LzQvgoKICAgIDsg0J7QsdC80ZbQvSAoU3dhcCkg0LLQutCw0LfRltCy0L3QuNC60ZbQsiDRgyDQvNCw0YHQuNCy0ZYKICAgIDsgcmRpID0gcHRyMSwgcjggPSBwdHIyICjQvNC4INCy0ZbQtNC90L7QstC40LvQuCDQudC+0LPQviDQt9GWINGB0YLQtdC60YMpCiAgICBtb3YgW3JieCArIHJzaSo4XSwgcjgKICAgIG1vdiBbcmJ4ICsgcnNpKjggKyA4XSwgcmRpCgouYnNfbm9zd2FwOgogICAgaW5jIHJzaQogICAgZGVjIHJkeAogICAgam56IC5ic19pbm5lcgoKICAgIHBvcCByY3gKICAgIGxvb3AgLmJzX291dGVyCgouYnNfZG9uZToKICAgIG1vdiByc3AsIHJicAogICAgcG9wIHJicAogICAgcmV0Cgo7IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo7INCf0L7RgNGW0LLQvdGP0L3QvdGPINGA0Y/QtNC60ZbQsiAo0LDQvdCw0LvQvtCzIHN0cmNtcCkKOyDQktGF0ZbQtDogUkRJID0gc3RyMSwgUlNJID0gc3RyMgo7INCS0LjRhdGW0LQ6IFJBWCA+IDAg0Y/QutGJ0L4gc3RyMSA+IHN0cjIsIDwgMCDRj9C60YnQviBzdHIxIDwgc3RyMgo7IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzdHJfY29tcGFyZToKICAgIHhvciByYXgsIHJheAouY21wX2xvb3A6CiAgICBtb3YgYWwsIGJ5dGUgW3JkaV0KICAgIG1vdiBibCwgYnl0ZSBbcnNpXQogICAgCiAgICBjbXAgYWwsIGJsCiAgICBqbmUgLmNtcF9kaWZmICAgICAgIDsg0JfQvdCw0LnRiNC70Lgg0YDRltC30L3QuNGG0Y4KICAgIAogICAgdGVzdCBhbCwgYWwgICAgICAgICA7INCn0Lgg0LrRltC90LXRhtGMINGA0Y/QtNC60LAgKDApPwogICAganogLmNtcF9lcXVhbCAgICAgICA7INCg0Y/QtNC60Lgg0ZbQtNC10L3RgtC40YfQvdGWCiAgICAKICAgIGluYyByZGkKICAgIGluYyByc2kKICAgIGptcCAuY21wX2xvb3AKCi5jbXBfZGlmZjoKICAgIHN1YiBhbCwgYmwKICAgIG1vdnN4IHJheCwgYWwgICAgICAgOyDQoNC+0LfRiNC40YDRjtGU0LzQviDRgNC10LfRg9C70YzRgtCw0YIg0LTQviA2NCDQsdGW0YIg0LfRliDQt9C90LDQutC+0LwKICAgIHJldAoKLmNtcF9lcXVhbDoKICAgIHhvciByYXgsIHJheAogICAgcmV0