section .data
; Оголошуємо самі слова (рядки з нуль-термінатором)
w1 db "Orange", 0
w2 db "Apple", 0
w3 db "Banana", 0
w4 db "Apricot", 0
w5 db "Cherry", 0
; Масив вказівників (адрес) на ці слова. Сортувати будемо саме цей масив.
ptr_array dq w1, w2, w3, w4, w5
; Кількість слів
len equ ($ - ptr_array) / 8
section .text
global _start
_start:
; --- Передача параметрів через стек ---
push ptr_array ; [rbp + 24] Адреса масиву вказівників
push len ; [rbp + 16] Кількість слів
call bubble_sort ; Виклик процедури
add rsp, 16 ; Очищення стеку
; --- Вихід ---
mov rax, 60
xor rdi, rdi
syscall
; ---------------------------------------------
; Процедура Bubble Sort для рядків
; ---------------------------------------------
bubble_sort:
push rbp
mov rbp, rsp
mov rcx, [rbp + 16] ; RCX = кількість елементів (N)
dec rcx ; N-1 проходів
cmp rcx, 0
jle .done
mov rbx, [rbp + 24] ; RBX = адреса масиву вказівників
.outer_loop:
push rcx
mov rdx, rcx ; RDX = лічильник внутрішнього циклу
xor rsi, rsi ; RSI = індекс (0, 1, 2...)
.inner_loop:
; Отримуємо адреси двох сусідніх рядків
; [rbx + rsi*8] - адреса першого рядка
; [rbx + rsi*8 + 8] - адреса другого рядка
mov rdi, [rbx + rsi*8] ; Аргумент 1 для порівняння
mov rax, [rbx + rsi*8 + 8] ; Аргумент 2 (збережемо в RAX поки що)
; Зберігаємо регістри перед викликом порівняння (System V ABI convention)
push rsi
push rdx
push rcx
push rbx
push rax ; Кладемо адресу другого рядка в стек або передаємо через регістр
mov rsi, rax ; Аргумент 2 для порівняння
call str_compare
; Результат в RAX: <0 якщо str1 < str2, >0 якщо str1 > str2
pop rax ; Відновлюємо (це була адреса 2-го рядка, вона вже не треба, просто чистимо стек)
pop rbx
pop rcx
pop rdx
pop rsi
cmp rax, 0
jle .no_swap ; Якщо str1 <= str2, міняти не треба (алфавітний порядок)
; --- Обмін вказівників ---
; Міняємо місцями адреси в масиві ptr_array, а не самі букви
mov r8, [rbx + rsi*8] ; Завантажуємо вказівник 1
mov r9, [rbx + rsi*8 + 8] ; Завантажуємо вказівник 2
mov [rbx + rsi*8], r9 ; Записуємо 2 на місце 1
mov [rbx + rsi*8 + 8], r8 ; Записуємо 1 на місце 2
.no_swap:
inc rsi ; Наступна пара
dec rdx
jnz .inner_loop
pop rcx
loop .outer_loop
.done:
mov rsp, rbp
pop rbp
ret
; ---------------------------------------------
; Процедура порівняння рядків
(аналог
strcmp) ; Вхід: RDI = адреса рядка 1, RSI = адреса рядка 2
; Вихід: RAX > 0, якщо рядок 1 "більший" (далі за алфавітом)
; RAX < 0, якщо рядок 1 "менший"
; RAX = 0, якщо рівні
; ---------------------------------------------
str_compare:
xor rax, rax
.cmp_loop:
mov al, byte [rdi]
mov bl, byte [rsi]
cmp al, bl
jne .diff_found ; Якщо букви різні, визначимо хто більший
test al, al ; Чи це кінець рядка (0)?
jz .equal ; Якщо дійшли до кінця і всі рівні -> рядки рівні
inc rdi
inc rsi
jmp .cmp_loop
.diff_found:
sub al, bl ; Віднімаємо коди ASCII
movsx rax, al ; Розширюємо результат до 64 біт зі збереженням знаку
ret
.equal:
xor rax, rax
ret
c2VjdGlvbiAuZGF0YQogICAgOyDQntCz0L7Qu9C+0YjRg9GU0LzQviDRgdCw0LzRliDRgdC70L7QstCwICjRgNGP0LTQutC4INC3INC90YPQu9GMLdGC0LXRgNC80ZbQvdCw0YLQvtGA0L7QvCkKICAgIHcxIGRiICJPcmFuZ2UiLCAwCiAgICB3MiBkYiAiQXBwbGUiLCAwCiAgICB3MyBkYiAiQmFuYW5hIiwgMAogICAgdzQgZGIgIkFwcmljb3QiLCAwCiAgICB3NSBkYiAiQ2hlcnJ5IiwgMAoKICAgIDsg0JzQsNGB0LjQsiDQstC60LDQt9GW0LLQvdC40LrRltCyICjQsNC00YDQtdGBKSDQvdCwINGG0ZYg0YHQu9C+0LLQsC4g0KHQvtGA0YLRg9Cy0LDRgtC4INCx0YPQtNC10LzQviDRgdCw0LzQtSDRhtC10Lkg0LzQsNGB0LjQsi4KICAgIHB0cl9hcnJheSBkcSB3MSwgdzIsIHczLCB3NCwgdzUKICAgIAogICAgOyDQmtGW0LvRjNC60ZbRgdGC0Ywg0YHQu9GW0LIKICAgIGxlbiBlcXUgKCQgLSBwdHJfYXJyYXkpIC8gOAoKc2VjdGlvbiAudGV4dAogICAgZ2xvYmFsIF9zdGFydAoKX3N0YXJ0OgogICAgOyAtLS0g0J/QtdGA0LXQtNCw0YfQsCDQv9Cw0YDQsNC80LXRgtGA0ZbQsiDRh9C10YDQtdC3INGB0YLQtdC6IC0tLQogICAgcHVzaCBwdHJfYXJyYXkgICAgICA7IFtyYnAgKyAyNF0g0JDQtNGA0LXRgdCwINC80LDRgdC40LLRgyDQstC60LDQt9GW0LLQvdC40LrRltCyCiAgICBwdXNoIGxlbiAgICAgICAgICAgIDsgW3JicCArIDE2XSDQmtGW0LvRjNC60ZbRgdGC0Ywg0YHQu9GW0LIKCiAgICBjYWxsIGJ1YmJsZV9zb3J0ICAgIDsg0JLQuNC60LvQuNC6INC/0YDQvtGG0LXQtNGD0YDQuAoKICAgIGFkZCByc3AsIDE2ICAgICAgICAgOyDQntGH0LjRidC10L3QvdGPINGB0YLQtdC60YMKCiAgICA7IC0tLSDQktC40YXRltC0IC0tLQogICAgbW92IHJheCwgNjAKICAgIHhvciByZGksIHJkaQogICAgc3lzY2FsbAoKOyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOyDQn9GA0L7RhtC10LTRg9GA0LAgQnViYmxlIFNvcnQg0LTQu9GPINGA0Y/QtNC60ZbQsgo7IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpidWJibGVfc29ydDoKICAgIHB1c2ggcmJwCiAgICBtb3YgcmJwLCByc3AKCiAgICBtb3YgcmN4LCBbcmJwICsgMTZdIDsgUkNYID0g0LrRltC70YzQutGW0YHRgtGMINC10LvQtdC80LXQvdGC0ZbQsiAoTikKICAgIGRlYyByY3ggICAgICAgICAgICAgOyBOLTEg0L/RgNC+0YXQvtC00ZbQsgogICAgY21wIHJjeCwgMAogICAgamxlIC5kb25lCgogICAgbW92IHJieCwgW3JicCArIDI0XSA7IFJCWCA9INCw0LTRgNC10YHQsCDQvNCw0YHQuNCy0YMg0LLQutCw0LfRltCy0L3QuNC60ZbQsgoKLm91dGVyX2xvb3A6CiAgICBwdXNoIHJjeAogICAgbW92IHJkeCwgcmN4ICAgICAgICA7IFJEWCA9INC70ZbRh9C40LvRjNC90LjQuiDQstC90YPRgtGA0ZbRiNC90YzQvtCz0L4g0YbQuNC60LvRgwogICAgeG9yIHJzaSwgcnNpICAgICAgICA7IFJTSSA9INGW0L3QtNC10LrRgSAoMCwgMSwgMi4uLikKCi5pbm5lcl9sb29wOgogICAgOyDQntGC0YDQuNC80YPRlNC80L4g0LDQtNGA0LXRgdC4INC00LLQvtGFINGB0YPRgdGW0LTQvdGW0YUg0YDRj9C00LrRltCyCiAgICA7IFtyYnggKyByc2kqOF0gICAgIC0g0LDQtNGA0LXRgdCwINC/0LXRgNGI0L7Qs9C+INGA0Y/QtNC60LAKICAgIDsgW3JieCArIHJzaSo4ICsgOF0gLSDQsNC00YDQtdGB0LAg0LTRgNGD0LPQvtCz0L4g0YDRj9C00LrQsAogICAgbW92IHJkaSwgW3JieCArIHJzaSo4XSAgICAgOyDQkNGA0LPRg9C80LXQvdGCIDEg0LTQu9GPINC/0L7RgNGW0LLQvdGP0L3QvdGPCiAgICBtb3YgcmF4LCBbcmJ4ICsgcnNpKjggKyA4XSA7INCQ0YDQs9GD0LzQtdC90YIgMiAo0LfQsdC10YDQtdC20LXQvNC+INCyIFJBWCDQv9C+0LrQuCDRidC+KQogICAgCiAgICA7INCX0LHQtdGA0ZbQs9Cw0ZTQvNC+INGA0LXQs9GW0YHRgtGA0Lgg0L/QtdGA0LXQtCDQstC40LrQu9C40LrQvtC8INC/0L7RgNGW0LLQvdGP0L3QvdGPIChTeXN0ZW0gViBBQkkgY29udmVudGlvbikKICAgIHB1c2ggcnNpCiAgICBwdXNoIHJkeAogICAgcHVzaCByY3gKICAgIHB1c2ggcmJ4CiAgICBwdXNoIHJheCA7INCa0LvQsNC00LXQvNC+INCw0LTRgNC10YHRgyDQtNGA0YPQs9C+0LPQviDRgNGP0LTQutCwINCyINGB0YLQtdC6INCw0LHQviDQv9C10YDQtdC00LDRlNC80L4g0YfQtdGA0LXQtyDRgNC10LPRltGB0YLRgAogICAgCiAgICBtb3YgcnNpLCByYXggOyDQkNGA0LPRg9C80LXQvdGCIDIg0LTQu9GPINC/0L7RgNGW0LLQvdGP0L3QvdGPCiAgICBjYWxsIHN0cl9jb21wYXJlCiAgICA7INCg0LXQt9GD0LvRjNGC0LDRgiDQsiBSQVg6IDwwINGP0LrRidC+IHN0cjEgPCBzdHIyLCA+MCDRj9C60YnQviBzdHIxID4gc3RyMgoKICAgIHBvcCByYXggOyDQktGW0LTQvdC+0LLQu9GO0ZTQvNC+ICjRhtC1INCx0YPQu9CwINCw0LTRgNC10YHQsCAyLdCz0L4g0YDRj9C00LrQsCwg0LLQvtC90LAg0LLQttC1INC90LUg0YLRgNC10LHQsCwg0L/RgNC+0YHRgtC+INGH0LjRgdGC0LjQvNC+INGB0YLQtdC6KQogICAgcG9wIHJieAogICAgcG9wIHJjeAogICAgcG9wIHJkeAogICAgcG9wIHJzaQoKICAgIGNtcCByYXgsIDAKICAgIGpsZSAubm9fc3dhcCAgICAgICA7INCv0LrRidC+IHN0cjEgPD0gc3RyMiwg0LzRltC90Y/RgtC4INC90LUg0YLRgNC10LHQsCAo0LDQu9GE0LDQstGW0YLQvdC40Lkg0L/QvtGA0Y/QtNC+0LopCgogICAgOyAtLS0g0J7QsdC80ZbQvSDQstC60LDQt9GW0LLQvdC40LrRltCyIC0tLQogICAgOyDQnNGW0L3Rj9GU0LzQviDQvNGW0YHRhtGP0LzQuCDQsNC00YDQtdGB0Lgg0LIg0LzQsNGB0LjQstGWIHB0cl9hcnJheSwg0LAg0L3QtSDRgdCw0LzRliDQsdGD0LrQstC4CiAgICBtb3YgcjgsIFtyYnggKyByc2kqOF0gICAgICAgOyDQl9Cw0LLQsNC90YLQsNC20YPRlNC80L4g0LLQutCw0LfRltCy0L3QuNC6IDEKICAgIG1vdiByOSwgW3JieCArIHJzaSo4ICsgOF0gICA7INCX0LDQstCw0L3RgtCw0LbRg9GU0LzQviDQstC60LDQt9GW0LLQvdC40LogMgogICAgbW92IFtyYnggKyByc2kqOF0sIHI5ICAgICAgIDsg0JfQsNC/0LjRgdGD0ZTQvNC+IDIg0L3QsCDQvNGW0YHRhtC1IDEKICAgIG1vdiBbcmJ4ICsgcnNpKjggKyA4XSwgcjggICA7INCX0LDQv9C40YHRg9GU0LzQviAxINC90LAg0LzRltGB0YbQtSAyCgoubm9fc3dhcDoKICAgIGluYyByc2kgICAgICAgICAgICAgOyDQndCw0YHRgtGD0L/QvdCwINC/0LDRgNCwCiAgICBkZWMgcmR4CiAgICBqbnogLmlubmVyX2xvb3AKCiAgICBwb3AgcmN4CiAgICBsb29wIC5vdXRlcl9sb29wCgouZG9uZToKICAgIG1vdiByc3AsIHJicAogICAgcG9wIHJicAogICAgcmV0Cgo7IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo7INCf0YDQvtGG0LXQtNGD0YDQsCDQv9C+0YDRltCy0L3Rj9C90L3RjyDRgNGP0LTQutGW0LIgKNCw0L3QsNC70L7QsyBzdHJjbXApCjsg0JLRhdGW0LQ6IFJESSA9INCw0LTRgNC10YHQsCDRgNGP0LTQutCwIDEsIFJTSSA9INCw0LTRgNC10YHQsCDRgNGP0LTQutCwIDIKOyDQktC40YXRltC0OiBSQVggPiAwLCDRj9C60YnQviDRgNGP0LTQvtC6IDEgItCx0ZbQu9GM0YjQuNC5IiAo0LTQsNC70ZYg0LfQsCDQsNC70YTQsNCy0ZbRgtC+0LwpCjsgICAgICAgIFJBWCA8IDAsINGP0LrRidC+INGA0Y/QtNC+0LogMSAi0LzQtdC90YjQuNC5Igo7ICAgICAgICBSQVggPSAwLCDRj9C60YnQviDRgNGW0LLQvdGWCjsgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnN0cl9jb21wYXJlOgogICAgeG9yIHJheCwgcmF4Ci5jbXBfbG9vcDoKICAgIG1vdiBhbCwgYnl0ZSBbcmRpXQogICAgbW92IGJsLCBieXRlIFtyc2ldCiAgICAKICAgIGNtcCBhbCwgYmwKICAgIGpuZSAuZGlmZl9mb3VuZCAgICAgOyDQr9C60YnQviDQsdGD0LrQstC4INGA0ZbQt9C90ZYsINCy0LjQt9C90LDRh9C40LzQviDRhdGC0L4g0LHRltC70YzRiNC40LkKICAgIAogICAgdGVzdCBhbCwgYWwgICAgICAgICA7INCn0Lgg0YbQtSDQutGW0L3QtdGG0Ywg0YDRj9C00LrQsCAoMCk/CiAgICBqeiAuZXF1YWwgICAgICAgICAgIDsg0K/QutGJ0L4g0LTRltC50YjQu9C4INC00L4g0LrRltC90YbRjyDRliDQstGB0ZYg0YDRltCy0L3RliAtPiDRgNGP0LTQutC4INGA0ZbQstC90ZYKICAgIAogICAgaW5jIHJkaQogICAgaW5jIHJzaQogICAgam1wIC5jbXBfbG9vcAoKLmRpZmZfZm91bmQ6CiAgICBzdWIgYWwsIGJsICAgICAgICAgIDsg0JLRltC00L3RltC80LDRlNC80L4g0LrQvtC00LggQVNDSUkKICAgIG1vdnN4IHJheCwgYWwgICAgICAgOyDQoNC+0LfRiNC40YDRjtGU0LzQviDRgNC10LfRg9C70YzRgtCw0YIg0LTQviA2NCDQsdGW0YIg0LfRliDQt9Cx0LXRgNC10LbQtdC90L3Rj9C8INC30L3QsNC60YMKICAgIHJldAoKLmVxdWFsOgogICAgeG9yIHJheCwgcmF4CiAgICByZXQ=