Online Compiler Nasm

extern io_get_dec, io_print_dec, io_print_string, io_print_char section .bss n resd 1 a resd 1 b resd 1 section .data num dd 1 den dd 1 section .text global main main: call io_get_dec mov [n], eax .beg: mov ecx, dword[n] cmp ecx, 0 je .done call io_get_dec mov [a], eax call io_get_dec mov [b], eax mov eax, dword[a] mov edi, dword[den] mul edi; eax = a * den mov esi, eax; esi = a * den mov eax, [b] mov edi, dword[num] mul edi; eax = b * num add esi, eax; esi = a * den + b * num mov eax, dword[b] mov ebx, dword[den] mul ebx; eax = b * den mov ebx, eax; ebx = b * den push esi push ebx call gcd add esp, 8 mov edi, eax; edi = gcd mov eax, esi; eax = a * den + b * num xor edx, edx idiv edi; eax = (a * den + b * num) / gcd mov [num], eax; num = (a * den + b * num) / gcd mov eax, ebx; eax = b * den xor edx, edx idiv edi; eax = (b * den) / gcd mov [den], eax; den = (b * den) / gcd dec dword[n] jmp .beg .done: mov eax, [num] call io_print_dec mov eax, ' ' call io_print_char mov eax, [den] call io_print_dec xor eax, eax ret gcd: push ebp mov ebp, esp push ebx mov eax, dword[ebp + 8] mov ebx, dword[ebp + 12] cmp eax, ebx cmovl eax, dword[ebp + 12] cmovl ebx, dword[ebp + 8] .beg: cmp ebx, 0 je .zero xor edx, edx idiv ebx; eax = a / b, edx = a % b cmp edx, 0 je .done mov eax, ebx mov ebx, edx jmp .beg .zero: mov ebx, eax .done: mov eax, ebx pop ebx leave ret
1) Этот код считывает число `n`, затем для каждой из `n` пар чисел `(a, b)` вычисляет сумму дробей `a/den + b/num`, приводя её к общему знаменателю и сокращая результат. В конце программа выводит итоговую дробь `num/den`.

2) Обрати внимание, что начальные значения `num` и `den` установлены в 1, что соответствует начальной дроби `1/1`.  
   В функции `gcd` для нахождения наибольшего общего делителя используется алгоритм Евклида, но учти, что в начале функции происходит сортировка аргументов, чтобы `eax >= ebx`.