Online Compiler Nasm

extern io_get_dec extern io_print_dec extern io_print_char section .text global main compar: push ebp mov ebp, esp push ebx push esi push edi mov esi, [ebp + 8] mov edi, [ebp + 12] mov eax, [esi] mul dword [edi + 4] mov ebx, eax mov ecx, edx mov eax, [edi] mul dword [esi + 4] cmp ecx, edx ja .greater jb .less cmp ebx, eax ja .greater jb .less mov eax, [esi] cmp eax, [edi] ja .greater jb .less xor eax, eax jmp .exit .greater: mov eax, 1 jmp .exit .less: mov eax, -1 .exit: pop edi pop esi pop ebx mov esp, ebp pop ebp ret quicksort: push ebp mov ebp, esp sub esp, 16 push ebx push esi push edi mov esi, [ebp + 12] mov edi, [ebp + 16] cmp esi, edi jge .qs_exit mov eax, esi add eax, edi shr eax, 1 shl eax, 3 add eax, [ebp + 8] mov ecx, [eax] mov edx, [eax + 4] mov [ebp - 12], ecx mov [ebp - 16], edx mov [ebp - 4], esi mov [ebp - 8], edi .partition_loop: mov eax, [ebp - 4] shl eax, 3 add eax, [ebp + 8] lea edx, [ebp - 12] push edx push eax call compar add esp, 8 cmp eax, 0 jge .skip_i inc dword [ebp - 4] jmp .partition_loop .skip_i: mov eax, [ebp - 8] shl eax, 3 add eax, [ebp + 8] lea edx, [ebp - 12] push edx push eax call compar add esp, 8 cmp eax, 0 jle .skip_j dec dword [ebp - 8] jmp .skip_i .skip_j: mov eax, [ebp - 4] cmp eax, [ebp - 8] jg .partition_end mov ecx, [ebp - 4] shl ecx, 3 add ecx, [ebp + 8] mov edx, [ebp - 8] shl edx, 3 add edx, [ebp + 8] mov eax, [ecx] mov ebx, [edx] mov [ecx], ebx mov [edx], eax mov eax, [ecx + 4] mov ebx, [edx + 4] mov [ecx + 4], ebx mov [edx + 4], eax inc dword [ebp - 4] dec dword [ebp - 8] jmp .partition_loop .partition_end: mov eax, [ebp - 8] push eax push dword [ebp + 12] push dword [ebp + 8] call quicksort add esp, 12 push dword [ebp + 16] mov eax, [ebp - 4] push eax push dword [ebp + 8] call quicksort add esp, 12 .qs_exit: pop edi pop esi pop ebx mov esp, ebp pop ebp ret read_and_sort: push ebp mov ebp, esp sub esp, 8 call io_get_dec test eax, eax jz .stop_recursion mov [ebp - 4], eax call io_get_dec test eax, eax jnz .has_denominator mov eax, 1 .has_denominator: mov [ebp - 8], eax mov eax, [ebp + 8] inc eax push eax call read_and_sort jmp .exit .stop_recursion: mov ecx, [ebp + 8] test ecx, ecx jz .exit mov eax, ecx dec eax push eax push 0 push esp call quicksort add esp, 12 mov esi, esp xor edi, edi .print_loop: cmp edi, ecx jae .exit mov eax, [esi + edi*8] call io_print_dec mov eax, [esi + edi*8 + 4] cmp eax, 1 je .skip_den push eax mov eax, 47 call io_print_char pop eax call io_print_dec .skip_den: mov eax, ecx dec eax cmp edi, eax je .print_dot mov eax, 44 call io_print_char jmp .next_print .print_dot: mov eax, 46 call io_print_char .next_print: inc edi jmp .print_loop .exit: mov esp, ebp pop ebp ret main: push ebp mov ebp, esp push 0 call read_and_sort add esp, 4 mov esp, ebp pop ebp xor eax, eax ret
Этот код реализует сортировку дробей, введённых пользователем. Программа читает пары чисел (числитель и знаменатель), пока не встретит ноль в числителе, затем сортирует их и выводит в порядке возрастания.

Функция `compar` сравнивает две дроби, представленные как пары 32-битных целых чисел. Она вычисляет перекрёстное произведение для сравнения, обрабатывая случай равенства произведений сравнением числителей.

Функция `quicksort` реализует быструю сортировку массива дробей. Она выбирает опорный элемент, разбивает массив на части и рекурсивно сортирует их.

Функция `read_and_sort` сначала рекурсивно читает дроби, сохраняя их в стеке. Когда встречается ноль, она вызывает `quicksort` для накопленных данных, затем выводит отсортированные дроби, пропуская знаменатель, равный 1, и разделяя элементы запятыми, а последний — точкой.

- В функции `read_and_sort` после вызова `quicksort` используется `mov esi, esp`, но стек в этот момент содержит не только данные дробей, но и локальные переменные и адреса возврата. Убедитесь, что `esi` указывает на начало массива дробей, а не на другие данные стека.
- В функции `compar` при вычислении перекрёстного произведения используется `mul`, который умножает `eax` на операнд и помещает результат в `edx:eax`. Проверьте, что порядок умножения и сравнения соответствует сравнению дробей a/b и c/d: a*d сравнивается с c*b.