Gistrec icon

ASM 1 v1

Gistrec | PRO | 09/25/18 04:38:24 AM UTC | 0 ⭐ | 12530 👁️ | Never ⏰ | []
ASM (NASM) |

0 B

|

None

|

0 👍

/

0 👎

.386
.MODEL FLAT, STDCALL
; прототипы внешних функций (процедур) описываются директивой EXTERN, 
; после знака @ указывается общая длина передаваемых параметров,
; после двоеточия указывается тип внешнего объекта – процедура
EXTERN  GetStdHandle@4: PROC
EXTERN  WriteConsoleA@20: PROC
EXTERN  CharToOemA@8: PROC
EXTERN  ReadConsoleA@20: PROC
EXTERN  ExitProcess@4: PROC; функция выхода из программы
EXTERN  lstrlenA@4: PROC; функция определения длины строки
EXTERN  wsprintfA: PROC; т.к. число параметров функции не фиксировано,
            ; используется соглашение, согласно которому очищает стек 
            ; вызывающая процедура
 
 
.DATA; сегмент данных
 
; выводимая строка, в конце добавлены
; управляющие символы: 13 – возврат каретки, 10 – переход на новую 
; строку, 0 – конец строки; с использованием директивы DB 
; резервируется массив байтов
WRITE_VALUE_STRING DB "Введите число в 16-ти ричной системе: ",13,10,0
 
 
;;;;; FMT DB "Число %d", 0; строка со списком форматов для функции wsprintfA
 
DIN DD ?; дескриптор ввода; директива DD резервирует память объемом
; 32 бита (4 байта), знак «?» используется для неинициализированных данных
DOUT DD ?; дескриптор вывода
 
FIRST_VALUE  DB 50 dup (?); Первое число в строковм виде
FIRST_LENGTH DD ? ; Длина первого числа
 
SECOND_VALUE DB 50 dup (?); Второе число
SECOND_LENGTH DD ? ; Длина второго числа
 
RESULT_VALUE DB 200 dup (?); Строка с результатом
RESULT_LENGTH DD ? ; Длина строки с результатом
 
LENS DD ? ; Буффер для длины строки (для ввода/вывода)
D_IN DD ? ; Дескриптор ввода
D_OUT DD ?; Дескриптор вывода
 
.CODE; сегмент кода 
 
 
MAIN PROC; описание процедуры
 
 
 
; 1. Сначала перекодируем строку STRN для DOS (т.к. она содержит русские буквы)
; Перемещаем в регистр EAX адрес строки STRN (OFFSET возвращает адрес)
MOV  EAX, OFFSET WRITE_VALUE_STRING;
 
; У функции CharToOemA@8 два параметра - откуда берем строку и куда кладем
; Адрес строки 
PUSH EAX; параметры функции помещаются в стек командой PUSH
PUSH EAX
CALL CharToOemA@8; вызов функции
 
 
; 2. Получаем дескриптов ввода и вывода функцией GetStdHandle
; Аргумент функции: -10 для ввода, -11 для вывода, -12 для сообщения об ошибки
; Функция возвращает дескриптор в регистр EAX
PUSH -10
CALL GetStdHandle@4
; Перемещаем регистр вывода в новую переменную D_IN
MOV D_IN, EAX
 
PUSH -11
CALL GetStdHandle@4
; Перемещаем регистр вывода в новую переменную D_OUT
MOV D_OUT, EAX 
 
; 3. Определяем длину строки WRITE_VALUE_STRING
; Аргумент функции: адрес строки. Возвращаемое значение: длина строки в регистре EAX
PUSH OFFSET WRITE_VALUE_STRING
CALL lstrlenA@4;
 
; Выводим строку WRITE_VALUE_STRING функцией WriteConsoleA
PUSH 0; 5-ый параметр всегда 0
PUSH OFFSET LENS; В переменную LENS запишется длина строки, которая была выведена
PUSH EAX; Длина строки, сколько хотим вывести
PUSH OFFSET WRITE_VALUE_STRING; Адрес строки
PUSH D_OUT; Регистр вывода
CALL WriteConsoleA@20
 
 
; 4. Вводим строку FIRST_VALUE
; FIRST_LENGTH больше на два, дополнительно введены
; 13 - возврат каретки и 10 - переход на новую строку
PUSH 0; 5-ый параметр всегда 0
PUSH OFFSET FIRST_LENGTH; Длина считанной строки строки
PUSH 50; Сколько символов хотим считать
PUSH OFFSET FIRST_VALUE; Куда читаем
PUSH D_IN; Регистр ввода
CALL ReadConsoleA@20
 
; TODO:
; Проверка на то, чтобы длина строки была больше 3
; И чтобы строка была меньше какого-то числа (избежать переполнение)
 
; 5. Еще раз выводим сообщение о необходимости ввести второе число
PUSH 0; 5-ый параметр всегда 0
PUSH OFFSET LENS; В переменную LENS запишется длина строки, которая была выведена
PUSH EAX; Длина строки, сколько хотим вывести
PUSH OFFSET WRITE_VALUE_STRING; Адрес строки
PUSH D_OUT; Регистр вывода
CALL WriteConsoleA@20
 
; 6. Вводим строку SECOND_VALUE
PUSH 0; 5-ый параметр всегда 0
PUSH OFFSET SECOND_LENGTH; Длина считанной строки строки
PUSH 50; Сколько символов хотим считать
PUSH OFFSET SECOND_VALUE; Куда читаем
PUSH D_IN; Регистр ввода
CALL ReadConsoleA@20
 
 
; TODO:
; Проверка на то, чтобы длина строки была больше 3
; И чтобы строка была меньше какого-то числа (избежать переполнение)
 
; TODO:
; Посимвольно переводим две строки в десятиричную систему счислению
 
; TODO:
; Перемножить два десятиричных числа MUL
; NOTE: Посмотреть что будет при большом числе (делит на два)
 
; TODO:
; Вывести полученное число
 
 
CALL ReadConsoleA@20 ; обратите внимание: LENS больше числа введенных
; символов на два, дополнительно введенные символы: 13 – возврат каретки и 
; 10 – переход на новую строку
; вывод полученной строки
PUSH 0
PUSH OFFSET LENS
PUSH LENS; длина вводимой строки
PUSH OFFSET BUF
PUSH DOUT
CALL WriteConsoleA@20
; вывод числа 123 в буфер BUF
PUSH 123
PUSH OFFSET FMT
PUSH OFFSET BUF
CALL wsprintfA
ADD ESP, 12; очистка стека от параметров (изменение регистра ESP 
; на 3*4 = 12 байтов)
; вывод строки с числом 123
PUSH 0
PUSH OFFSET LENS
PUSH EAX
PUSH OFFSET BUF
PUSH DOUT
CALL WriteConsoleA@20
; небольшая задержка
MOV ECX,03FFFFFFFH; помещение в регистр ECX – счетчик цикла –
; большого значения
L1: LOOP L1; цикл без тела
; выход из программы 
 
 
 
PUSH 0; параметр: код выхода
CALL ExitProcess@4
MAIN ENDP
END MAIN

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎