Online Compiler Nasm

section .bss X resd 12 ; числители Y resd 12 ; знаменатели N resd 1 sum_temp resd 1 num_res resd 1 den_res resd 1 section .text global main extern io_get_dec, io_print_dec, io_print_char main: ; Ввод N call io_get_dec mov [N], eax cmp eax, 1 jl finish cmp eax, 12 jg finish xor ecx, ecx input_loop: cmp ecx, [N] jge compute_lcm call io_get_dec mov [X + ecx*4], eax call io_get_dec cmp eax, 0 je finish ; запрещаем нулевой знаменатель mov [Y + ecx*4], eax inc ecx jmp input_loop ;----------------------- ; Вычисляем общий знаменатель через LCM compute_lcm: mov esi, 1 ; общий знаменатель xor ecx, ecx lcm_loop: cmp ecx, [N] jge sum_fraction mov eax, esi mov ebx, [Y + ecx*4] call lcm mov esi, eax inc ecx jmp lcm_loop ;----------------------- ; Вычисляем сумму дробей sum_fraction: xor eax, eax mov [sum_temp], eax xor ecx, ecx sum_loop: cmp ecx, [N] jge simplify_fraction mov eax, esi mov ebx, [Y + ecx*4] cmp ebx, 0 je finish xor edx, edx div ebx ; общий/Yi mov ebx, eax mov eax, [X + ecx*4] imul eax, ebx xor edx, edx ; безопасно перед сложением add eax, [sum_temp] mov [sum_temp], eax inc ecx jmp sum_loop ;----------------------- ; Упрощение дроби simplify_fraction: mov eax, [sum_temp] mov ebx, esi call gcd ; gcd(S, общий) mov ecx, eax ; сохранить gcd mov eax, [sum_temp] xor edx, edx div ecx ; числитель / gcd mov [num_res], eax mov eax, esi xor edx, edx div ecx ; знаменатель / gcd mov [den_res], eax mov eax, [num_res] call io_print_dec mov eax, '/' call io_print_char mov eax, [den_res] call io_print_dec finish: ret ;----------------------- ; Функция gcd(a,b) gcd: ; Вход: eax = a, ebx = b cmp ebx, 0 je gcd_done gcd_loop: xor edx, edx div ebx mov eax, ebx mov ebx, edx cmp ebx, 0 jne gcd_loop gcd_done: ret ;----------------------- ; Функция lcm(a,b) = a*b / gcd(a,b) lcm: push eax ; сохраняем a push ebx ; сохраняем b call gcd mov ecx, eax ; сохраняем gcd pop ebx ; восстанавливаем b pop eax ; восстанавливаем a imul eax, ebx ; a*b xor edx, edx div ecx ; / gcd ret
1) Этот код на NASM32 вычисляет сумму дробей. Сначала программа считывает количество дробей N, затем числители и знаменатели каждой дроби. После этого находится общий знаменатель (НОК всех знаменателей), числители приводятся к общему знаменателю и суммируются. В конце полученная дробь упрощается с помощью НОД и выводится на экран.

2) Подсказки:
- Обрати внимание, что функция `gcd` ожидает входные значения в регистрах `eax` и `ebx`, но внутри цикла `gcd_loop` используется деление `div ebx`, которое изменяет `eax` и `edx`. Убедись, что перед вызовом `gcd` в других частях кода регистры содержат корректные значения.
- При вычислении НОК в функции `lcm` используется умножение `imul eax, ebx`, которое может вызвать переполнение, если произведение чисел превысит 32 бита. Подумай, как можно обработать эту ситуацию или ограничить входные данные.