Skip to content

Instantly share code, notes, and snippets.

@PashokSy
Created January 14, 2020 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PashokSy/255a7598a9dcf7f0c724dfe99efe6c14 to your computer and use it in GitHub Desktop.
Save PashokSy/255a7598a9dcf7f0c724dfe99efe6c14 to your computer and use it in GitHub Desktop.
;* СОЗДАНИЕ СЕГМЕНТА СТЭКА *
STACKSEG SEGMENT PARA "STACK"
DW 32 DUP(0)
STACKSEG ENDS
;* СОЗДАНИЕ СЕГМЕНТА ДАННЫХ *
DSEG SEGMENT PARA PUBLIC "DATA"
NUM DW 0
FL DB 0 ; ФЛАГ НЕГАТИВНОГО(1)/ПОЗИТИВНОГО(0) ЧИСЛА
DUMP DB 5, ?, 4 DUP('?') ; СТРУКТКРА ДАННЫХ ДЛЯ ХРАНЕНИЯ ВВОДА
ERRCD DB 0 ; ФЛАГ ОШИБКИ
; 0 - ОШИБОК НЕТ
; 1 - ОШИБКА
ERRTXT DB '*ERROR*'
DB ' - YOU NEED TO ENTER THE NUMBER$'
MSGTXT DB 'ENTER YOU NUMBER:$'
MSG2TXT DB 'ANSWER: $'
DSEG ENDS
;--------------------------------------------------------------------------
INCLUDE MAKROSI.ASM
;--------------------------------------------------------------------------
;* СОЗДАНИЕ СЕГМЕНТА КОДА *
CSEG SEGMENT PARA PUBLIC "CODE"
;* НАЧАЛО ОСНОВНОЙ ПРОЦЕДУРЫ
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG, SS: STACKSEG
MAGIC DSEG
PRINTF MSGTXT ; ПОПРОСИТЬ ВВЕСТИ ЧИСЛО
INPUT DUMP,ERRCD,NUM,FL
NEWLINE
CMP ERRCD,1 ;ПРОВЕРИТЬ ОШИБКИ ВВОДА
JNE NO_ERRORS ;ЕСЛИ ОШИБОК НЕТ -
PRINTF ERRTXT ;ИНЧЕ ВЫВЕСТИ СООБЩЕНИЕ ОБ ОШИБКЕ
MOV AX,4C00H
INT 21H
NO_ERRORS: ;ПРОПУСТИТЬ
MULTIPLY NUM,3
PRINTF MSG2TXT
OUTPUT NUM
RET ;ВОЗВРАЩАЕМ УПРАВЛЕНИЕ ВЫЗЫВАЮЩЕЙ ПРОЦЕДУРЕ
MAIN ENDP
;* КОНЕЦ ОСНОВНОЙ ПРОЦЕДУРЫ
CSEG ENDS ; КОНЕЦ СЕГМЕНТА КОДА
END MAIN ; ВЫХОД ИЗ ПРОГРАММЫ
;┌──────────────┐
;│ Макрос magic │
;└──────────────┘
MAGIC MACRO DSEG
PUSH DS
MOV AX,0
PUSH AX
MOV AX,DSEG
MOV DS,AX
ENDM
;┌──────────────────────────────────────┐
;│ Макрос вывода на экран строки stirng │
;└──────────────────────────────────────┘
PRINTF MACRO STRING
MOV AH,9 ; Функция вывода строки
LEA DX,STRING ; Загружаем адрес строки
INT 21H ; Вызов прерывания DOS
MOV AL,0AH
INT 29H
ENDM
NEWLINE MACRO
MOV AL,0AH
INT 29H
MOV AL,0DH
INT 29H
ENDM
;┌─────────────────────────────────┐
;│ Макрос ВВОДА ЧИСЛА В ПЕРЕМЕННУЮ │
;└─────────────────────────────────┘
INPUT MACRO DUMP,ERRCD,NUM,FL
MOV ERRCD,0 ; ОБНУЛЕНИЕ КОДА ОШИБКИ
;* ВВОД ДАННЫХ С КЛАВИТУРЫ *
LEA DX,DUMP ; РАЗМЕЩЕНИЕ В 'DX' СТРУКТУРЫ 'DUMP'
MOV AH,10 ; КОД '10' ПРЕРЫВНИЯ 21..
INT 21H ; ..ОТВЕЧАЕТ ЗА ВВОД ДАННЫХ С КЛАВИАТУРЫ
;* ВВЕДЕННЫЕ ДАННЫЕ С КЛАВИАТУРЫ ПОМЕЩЕННЫ В 'DUMP'(DUMP+2)
;* ОПРЕДЕЛЕНИЕ КОЛ-ВА ВВЕДЕНЫХ СИМОВЛОВ
LEA SI,DUMP+1 ; РАЗМЕЩЕНИЕ В 'SI' АДРЕСА С КОЛ-ВОМ ВВЕДЕНЫХ ЗНАКОВ
XOR CX,CX ; ОБНУЛЕНИЕ СЧЕТЧИКА
MOV CL,[SI] ; "УСТАНОВКА" СЧЕТЧИКА
CMP CX,0 ; *ЕСЛИ НИЧЕГО НЕ ВВЕДЕНО
JE SOME_ERR ; ВЫВЕСТИ КОД ОШИБКИ
;* ОПРЕДЕЛЕНИЕ ПОЗИТИВНОСТИ ЧИСЛА
; MOV FL,0 ; ДЛЯ СБРОСА ФЛАГА ПОЗ/НЕГ ЧИСЛА
INC SI ; *ПЕРЕХОД С КОЛ-ВА ВВЕДЕНЫХ СИМВОЛОВ
; НА ПЕРВЫЙ ВВЕДЕННЫЙ СИМВОЛ.
MOV AL,[SI] ; РАЗМЕЩЕНИЕ ЕГО В РЕГИСТР ДЛЯ ОБРАБОТКИ.
CMP AL,'-' ; ПРОВЕРКА МИНУС ЛИ ЭТО.
JNE NO_MINUS ; ЕСЛИ МИНУСА НЕТ - ПЕРЕХОД*
MOV FL,1 ; УСТАНОКА ФЛАГА НЕГАТИВНОГО ЧИСЛА
DEC CL ; УЧЕСТЬ МИНУС В КОЛ-ВЕ ВВЕДЕННЫХ СИМВОЛОВ
CMP CX,0 ; *ЕСЛИ КРОМЕ МИНУСА НИЧЕГО НЕ ВВЕДЕНО
JE SOME_ERR ; ВЫЙТИ ИЗ ПРОГРАММЫ*
INC SI ; ПЕРЕЙТИ К СЛЕДУЮЩЕМУ РАЗРЯДУ ЧИСЛА
NO_MINUS: ;* НАЧАЛО РАБОТЫ С ЧИСЛОМ
XOR AX,AX ; ОЧИСТКА 'AX'
XOR DI,DI ; ОЧИСТКА 'DI'
MOV DI,10 ; ДЛЯ РАЗДЕЛЕНИЯ ЧИСЛА НА РАЗРЯДЫ
DEC SI ; ВОЗВРАЩАЕМСЯ К РАБОЧЕМУ СИМВОЛУ
FOR_LOOP: ; НАЧАЛО ЦИКЛА ПРОХОДА ПО ЧИСЛУ(ПОРАЗРЯДНО)
INC SI ; ПЕРЕХОД К ПЕРВОМУ СИМВОЛУ
XOR BX,BX ; ОБНУЛЕНИЕ 'BX'
MOV BL,[SI] ; РАЗМЕЩЕНИЕ ЧИСЛА В РЕГИСТР
SUB BL,'0' ; ПРЕОБРАЗОВАНИЕ ASCII TO DEC
CMP BL,9 ; *ЕСЛИ ВВЕДЕНА НЕ ЦИФРА
JA SOME_ERR ; ВЫЙТИ ИЗ ПРОГРАММЫ*
MUL DI ; *УМНОЖАЕМ 'AX' НА 10 ДЛЯ ДОБАВЛЕНИЯ МЕСТА
; ПОД НОВЫЙ СИМВОЛ* (1 -> 10 + 'BX' = 11)
ADD AX,BX ; ПРИБАВЛЯЕМ К ЧИСЛУ В 'AX' ПОЛУЧЕННУЮ ЦИФРУ
LOOP FOR_LOOP ; "КОНЕЦ" ЦИКЛА ПРОХОДА ПО ЧИСЛУ
CMP FL,1 ; *ЕСЛИ ЧИСЛО НЕ ОТРИЦАТЕЛЬНОЕ
JNE NOT_NEG ; НИЧЕГО НЕ ДЕЛАЕМ.
NEG AX ; ИНЧЕ - ДЕЛАЕМ ЕГО НЕГАТИВНЫМ.
NOT_NEG:
CMP ERRCD,0 ; *ЕСЛИ ОШИБОК НЕТ
JE EXIT ; НА ВЫХОД ИЗ ПРОЦЕДУРЫ*
SOME_ERR:
MOV ERRCD,1 ; ПОДНЯТЬ ФЛАГ ОШИБКИ - 1
EXIT:
MOV NUM,AX
ENDM
;┌─────────────────────────────────┐
;│ Макрос ВЫВОДА ЧИСЛА НА ЭКРАН │
;└─────────────────────────────────┘
OUTPUT MACRO NUM
MOV BX,NUM ; РАЗМЕЩЕНИЕ ЧИСЛА В РЕГИСТРЕ BX
OR BX,BX ; *ЕСЛИ ЧИЛО ПОЛОЖИТЕЛЬНОЕ
JNS M1 ; ПЕРЕЙТИ В M1.
MOV AL,"-" ; ИНЧЕ РАЗМЕСТИТ В РЕЗУЛЬТАТЕ СИМВОЛ МИНУСА.
INT 29H ; ВЫВЕСТИ МИНУС НА ЭКРАН*
NEG BX ; ИЗМЕНИТЬ СТАРШИЙ БИТ ЧИСЛА("УБРАТЬ МИНУС")
M1: ; ТОЧКА ПРЕХОДА ЕСЛИ ЧИСЛО ПОЗИТИВНОЕ
MOV AX,BX ; ОБНОВИТЬ ЧИСЛО В РЕГИСТРЕ 'AX'(ИЗ-ЗА "NEG BX")
XOR CX,CX ; ОБНУЛИТЬ РЕГИСТР СЧЕТЧИКА
MOV BX,10 ; ДЛЯ РАЗДЕЛЕНИЯ ЧИСЛА НА РАЗРЯДЫ
M2: ; НАЧАЛО ЦИКЛА "РАЗМЕЩЕНИЕ ЧИСЛА В СТЕКЕ"
XOR DX,DX ; ОБНУЛЕНИЕ 'DX'
DIV BX ; ДЕЛЕНИЕ 'AX' НА 'BX'(ОТДЕЛЕНИЕ РАЗРЯДА)
ADD DL,"0" ; DECIMAL TO ASCII
PUSH DX ; РАЗМЕЩЕНИЕ РЕЗУЛЬТАТА В СТЕКЕ
INC CX ; УВЕЛИЧЕНИЕ СЧЕТЧИКА
TEST AX,AX ; *ЕСЛИ ЕЩЕ ОСТАЛИСЬ ЦИФРЫ В ЧИСЛЕ
JNZ M2 ; ПОВТОРИТЬ "РАЗМЕЩЕНИЕ В СТЕКЕ"
M3: ; НАЧАЛО ЦИКЛА ВЫВОДА ЧИСЛА ИЗ СТЕК НА ЭКРАН
POP AX ; ДОСТАТЬ ВЕРХНЮЮ ЦИФРУ ИЗ СТЭКА
INT 29H ; ВЫВЕСТИ ЕЁ НА ЭКРАН
LOOP M3 ; ПОВТОРИТЬ 'M3' ПОКА СЧЕТЧИК НЕ '0'
ENDM
;┌──────────────────┐
;│ Макрос УМНОЖЕНИЯ │
;└──────────────────┘
MULTIPLY MACRO NUM1,NUM2
MOV AX,NUM1
MOV BX,NUM2
MUL BX
MOV NUM1,AX
ENDM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment