Загрузка данных
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