Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .386 ; Ассемблерная директива, предписывающая использовать набор операций для; процессора 80386
- .MODEL FLAT, STDCALL ; Ассемблерная директива, определяющая модель памяти программы (модель управления стеком)
- ; Прототипы внешних процедур (После @ — общая длина передаваемых параметров,
- ; после : — тип внешнего объекта "Процедура")
- EXTERN GetStdHandle@4: PROC ; Функция определения дескриптора
- EXTERN WriteConsoleA@20: PROC ; Функция вывода текста
- EXTERN CharToOemA@8: PROC ; Функция перекодировки
- EXTERN ReadConsoleA@20: PROC ; Функция ввода
- EXTERN ExitProcess@4: PROC ; Функция выхода из программы
- EXTERN lstrlenA@4: PROC ; Функция определения длины строки
- .DATA
- DIN DD ? ; Объявление переменной DIN для хранения ввода
- DOUT DD ? ; Объявление переменной DOUT для хранения вывода
- STRN1 DB "Введите первое восьмеричное число: ", 13, 10, 0 ; Строка приглашения для ввода первого числа
- STRN2 DB "Введите второе восьмеричное число: ", 13, 10, 0 ; Строка приглашения для ввода второго числа
- STRN3 DB "Результат умножения в десятичной системе: ", 13, 10, 0 ; Строка для вывода результата
- BUF DB 200 DUP (?) ; Буфер для хранения введенных данных
- LENS DD ? ; Переменная для хранения длины ввода
- FlagA DD 0 ; Флаг для первого числа
- FlagB DD 0 ; Флаг для второго числа
- Two DD 2 ; Константа для преобразования из восьмеричной в десятичную систему (степ. двойки)
- Ten DD 10 ; Константа для десятичной системы
- NumA DD ? ; Переменная для хранения первого числа
- NumB DD ? ; Переменная для хранения второго числа
- .CODE
- MAIN PROC ; Начало описания процедуры с именем MAIN
- ; Перекодируем строку STRN1
- PUSH OFFSET STRN1 ; Параметры функции помещаются в стек командой PUSH, OFFSET — операция,
- ;возвращающая адрес (смещения)
- CALL CharToOemA@8 ; Преобразование строки приглашения в ANSI
- PUSH -10 ; STD_INPUT_HANDLE (константа вывода)
- CALL GetStdHandle@4 ; Получение дескриптора стандартного ввода
- MOV DIN, EAX ; Сохранение дескриптора в переменной DIN
- PUSH OFFSET STRN1
- CALL lstrlenA@4 ; Получение длины строки приглашения
- PUSH 0
- PUSH OFFSET LENS
- PUSH EAX
- PUSH OFFSET STRN1
- PUSH DIN
- CALL WriteConsoleA@20 ; Вывод приглашения для ввода первого числа в консоль
- PUSH 0
- PUSH OFFSET LENS
- PUSH 200
- PUSH OFFSET BUF
- PUSH OFFSET LENS
- PUSH OFFSET DIN
- CALL ReadConsoleA@20 ; Чтение ввода пользователя в буфер
- XOR EAX, EAX ; Обнуление регистра EAX
- XOR EBX, EBX ; Обнуление регистра EBX
- XOR ECX, ECX ; Обнуление регистра ECX
- MOV ECX, 200 ; Установка счетчика на 200 (максимальная длина ввода)
- LEA ESI, [BUF] ; Загрузка адреса буфера в регистр ESI
- Convert1Loop:
- MOV AL, [ESI] ; Загрузка байта из буфера в AL
- CMP AL, 0 ; Сравнение с нулем (конец строки)
- JE Convert1Done ; Если конец строки, завершить цикл
- SUB AL, '0' ; Преобразование символа в число
- MUL Two ; Умножение текущего результата на 2
- ADD BX, AX ; Прибавление нового значения к результату
- INC ESI ; Переход к следующему символу в буфере
- JMP Convert1Loop ; Переход в начало цикла
- Convert1Done:
- MOVZX EAX, BX ; Загрузка результата в EAX
- MOV NumA, EAX ; Сохранение результата в переменной NumA
- PUSH OFFSET STRN2
- CALL CharToOemA@8 ; Преобразование строки приглашения в ANSI
- PUSH -10 ; STD_INPUT_HANDLE
- CALL GetStdHandle@4 ; Получение дескриптора стандартного ввода
- MOV DIN, EAX ; Сохранение дескриптора в переменной DIN
- PUSH OFFSET STRN2
- CALL lstrlenA@4 ; Получение длины строки приглашения
- PUSH 0
- PUSH OFFSET LENS
- PUSH EAX
- PUSH OFFSET STRN2
- PUSH DIN
- CALL WriteConsoleA@20 ; Вывод приглашения для ввода второго числа в консоль
- PUSH 0
- PUSH OFFSET LENS
- PUSH 200
- PUSH OFFSET BUF
- PUSH OFFSET LENS
- PUSH OFFSET DIN
- CALL ReadFile@20 ; Чтение ввода пользователя в буфер
- XOR EAX, EAX ; Обнуление регистра EAX
- XOR EBX, EBX ; Обнуление регистра EBX
- XOR ECX, ECX ; Обнуление регистра ECX
- MOV ECX, 200 ; Установка счетчика на 200 (максимальная длина ввода)
- LEA ESI, [BUF] ; Загрузка адреса буфера в регистр ESI
- Convert2Loop:
- MOV AL, [ESI] ; Загрузка байта из буфера в AL
- CMP AL, 0 ; Сравнение с нулем (конец строки)
- JE Convert2Done ; Если конец строки, завершить цикл
- SUB AL, '0' ; Преобразование символа в число
- MUL Two ; Умножение текущего результата на 2
- ADD BX, AX ; Прибавление нового значения к результату
- INC ESI ; Переход к следующему символу в буфере
- JMP Convert2Loop ; Переход в начало цикла
- Convert2Done:
- MOVZX EAX, BX ; Загрузка результата в EAX
- MOV NumB, EAX ; Сохранение результата в переменной NumB
- MOV EAX, NumA ; Загрузка первого числа в EAX
- MOV EBX, NumB ; Загрузка второго числа в EBX
- MUL EBX ; Умножение чисел, результат в EDX:EAX
- XOR EDI, EDI ; Обнуление регистра EDI (для подсчета длины результата)
- MOV ESI, OFFSET BUF ; Загрузка адреса буфера в ESI
- .WHILE EAX >= Ten ; Цикл, пока результат больше или равен 10
- DIV Ten ; Деление на 10, остаток в EDX
- ADD EDX, '0' ; Преобразование остатка в символ и добавление к результату
- PUSH EDX ; Запись символа в стек
- ADD EDI, 1 ; Увеличение счетчика длины
- XOR EDX, EDX ; Обнуление регистра EDX
- .ENDW
- ADD EAX, '0' ; Преобразование оставшегося значения в символ
- PUSH EAX ; Запись символа в стек
- ADD EDI, 1 ; Увеличение счетчика длины
- CMP FlagA, 0 ; Проверка флага для первого числа
- JE Continue2 ; Если флаг сброшен, переход к метке Continue2
- CMP FlagB, 1 ; Проверка флага для второго числа
- JE Continue4 ; Если флаг установлен, переход к метке Continue4
- JNE Continue3 ; Если флаг сброшен, переход к метке Continue3
- Continue2:
- CMP FlagB, 0 ; Проверка флага для второго числа
- JE Continue4 ; Если флаг сброшен, переход к метке Continue4
- JNE Continue3 ; Если флаг установлен, переход к метке Continue3
- Continue3:
- PUSH '-' ; Помещение знака минус в стек
- ADD EDI, 1 ; Увеличение счетчика длины
- Continue4:
- MOV ECX, EDI ; Загрузка длины результата в ECX
- Convertc_c:
- POP [ESI] ; Извлечение символа из стека и запись в буфер
- INC ESI ; Переход к следующему символу в буфере
- LOOP Convertc_c ; Повторение, пока ECX не достигнет 0
- PUSH OFFSET STRN3
- CALL CharToOemA@8 ; Преобразование строки результата в ANSI
- PUSH OFFSET STRN3
- CALL lstrlenA@4 ; Получение длины строки результата
- PUSH 0
- PUSH OFFSET LENS
- PUSH ECX
- PUSH OFFSET STRN3
- PUSH DOUT
- CALL WriteConsoleA@20 ; Вывод строки результата в консоль
- MOV ECX, 06FFFFFFFH ; Инициализация счетчика для задержки (просто ожидание)
- L1:
- LOOP L1 ; Петля ожидания
- PUSH 0
- CALL ExitProcess@4 ; Завершение программы
- MAIN ENDP
- END MAIN
Advertisement
Advertisement