Загрузка данных


section .data
    a dd 5          ; Исходное число a
    b dd 10         ; Исходное число b
    msg_result db "Result: ", 0 ; Текст перед числом (необязательно, для красоты)

section .bss
    ; Резервируем 12 байт под строку: 
    ; максимум 10 цифр для 32-битного числа + 1 байт под перенос строки (\n) + запас
    num_str resb 12 

section .text
    global _start

_start:
    ; ==========================================
    ; 1. Загружаем исходные значения
    ; ==========================================
    mov eax, [a]    ; EAX = a
    mov ebx, [b]    ; EBX = b

    ; ==========================================
    ; 2. Вычисляем утроенное произведение (3 * a * b)
    ; ==========================================
    mov ecx, eax    ; ECX = a (сохраняем исходное a)
    imul ecx, ebx   ; ECX = a * b
    imul ecx, 3     ; ECX = (a * b) * 3  <-- Здесь лежит наш результат!

    ; ==========================================
    ; 3. Сравниваем и записываем в наименьшее
    ; ==========================================
    cmp eax, ebx    ; Сравниваем исходные a и b
    jle save_to_a   ; Если a <= b, переходим к save_to_a

    mov [b], ecx    ; Иначе (b < a), записываем результат в b
    jmp prepare_print ; Переходим к подготовке вывода

save_to_a:
    mov [a], ecx    ; Записываем результат в a

prepare_print:
    ; Теперь результат гарантированно лежит в ECX.
    ; Переносим его в EAX, так как инструкция деления (div) работает с EAX.
    mov eax, ecx    

    ; ==========================================
    ; 4. Преобразование числа в строку (Алгоритм деления на 10)
    ; ==========================================
    ; Мы будем заполнять буфер num_str с конца, чтобы цифры встали в правильном порядке
    
    mov edi, num_str + 11  ; Указатель на самый конец нашего буфера
    mov byte [edi], 10     ; Записываем символ переноса строки '\n' (ASCII 10)
    dec edi                ; Сдвигаем указатель на 1 байт назад

.convert_loop:
    xor edx, edx           ; Очищаем EDX перед делением (обязательно для div!)
    mov ebx, 10            ; Делитель = 10
    div ebx                ; Делим EDX:EAX на 10. 
                           ; Частное остается в EAX, остаток (цифра) попадает в EDX
    
    add dl, '0'            ; Превращаем числовую цифру (0-9) в ASCII-символ ('0'-'9')
    mov [edi], dl          ; Записываем символ в буфер
    dec edi                ; Сдвигаем указатель назад для следующей цифры
    
    test eax, eax          ; Проверяем, стало ли частное (EAX) равным 0
    jnz .convert_loop      ; Если нет, повторяем цикл

    ; Цикл закончился. Теперь EDI указывает на байт ПЕРЕД первой цифрой нашего числа.
    inc edi                ; Сдвигаем EDI на 1 вперед, чтобы он указывал ровно на первую цифру

    ; ==========================================
    ; 5. Вывод строки на экран (sys_write)
    ; ==========================================
    ; Нам нужно знать адрес начала строки (он в EDI) и её длину.
    ; Длина = (конец буфера) - (текущий указатель EDI)
    
    mov edx, num_str + 11  ; Адрес конца буфера (где лежит '\n')
    sub edx, edi           ; Вычисляем длину строки: (конец - начало)
    ; Теперь в EDX лежит длина, а в EDI лежит адрес начала строки

    mov eax, 4             ; sys_write
    mov ebx, 1             ; файловый дескриптор 1 (stdout, экран)
    mov ecx, edi           ; адрес строки для вывода
    ; edx уже содержит длину
    int 0x80               ; Вызов ядра

    ; ==========================================
    ; 6. Завершение программы
    ; ==========================================
exit:
    mov eax, 1             ; sys_exit
    xor ebx, ebx           ; код возврата 0
    int 0x80