Skip to content

Instantly share code, notes, and snippets.

@PashokSy
Created January 15, 2020 19:21
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/0b7468f6f70768c36e8c0a68391341aa to your computer and use it in GitHub Desktop.
Save PashokSy/0b7468f6f70768c36e8c0a68391341aa to your computer and use it in GitHub Desktop.
;* СОЗДАНИЕ СЕГМЕНТА СТЭКА *
STACKSEG SEGMENT PARA "STACK"
DW 32 DUP(0)
STACKSEG ENDS
;* СОЗДАНИЕ СЕГМЕНТА ДАННЫХ *
DSEG SEGMENT PARA PUBLIC "DATA"
MES1 DB 0DH,"START ARRAY - $"
MES2 DB 0DH,"ENTER YOUR NUMBER FOR SEARCH:$"
MES3 DB 0DH,"ENTER YOUR ARRAY IN LINE (16 ELEMS, SQUARE ARRAY ONLY)$"
MES4 DB 0DH,"COORDINATES FOUND: $"
MES5 DB "( $"
MES6 DB " ; $"
MES7 DB " ) $"
MES8 DB " $"
N EQU 16
SRCH DW ?
I DW 0
J DW 0
MAS DW 17 DUP (?)
TMP DW ?
DSEG ENDS
;--------------------------------------------------------------------------
INCLUDE MACROSI.ASM
;* СОЗДАНИЕ СЕГМЕНТА КОДА *
CSEG SEGMENT PARA PUBLIC "CODE"
;* НАЧАЛО ОСНОВНОЙ ПРОЦЕДУРЫ
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG, SS: STACKSEG
MAGIC DSEG
; ПОЛУЧИТЬ ПОИСКОВЫЙ
PRINTF MES2 ; ПОПРОСИТЬ ВВЕСТИ ПОИСКОВЫЙ
NEWLINE ; ПЕРЕВЕСТИ КАРЕТКУ
INPUT_POISKOVIY SRCH ; ПОЛУЧИТЬ ОТ ПОЛЬЗОВАТЕЛЯ ПОИСКОВЫЙ
NEWLINE ; ПЕРЕВЕСТИ КАРЕТКУ
;*
; ПОЛУЧИТЬ МАССИВ ОТ ПОЛЬЗОВАТЕЛЯ
PRINTF MES3 ; ПОПРОСИТЬ ВВЕСТИ МАССИВ
NEWLINE ; ПЕРЕВЕСТИ КАРЕТКУ
INPUT MAS,N ; ЗАПИСАТЬ МАССИВ В ПЕРЕМЕННУЮ MAS
NEWLINE ; ПЕРЕВЕСТИ КАРЕТКУ
;*
; НАЙТИ КООРДИНАТЫ ВХОЖДЕНИЯ
PRINTF MES4 ; "ENTRY FOUND"
CALL FIND_COORDINATES ;НАЙТИ ВХОЖДЕНИЯ И ВЫВЕСТИ ИХ НА ЭКРАН
NEWLINE ; ПЕРЕВЕСТИ КАРЕТКУ
;*
RET ;ВОЗВРАЩАЕМ УПРАВЛЕНИЕ ВЫЗЫВАЮЩЕЙ ПРОЦЕДУРЕ
MAIN ENDP
;* КОНЕЦ ОСНОВНОЙ ПРОЦЕДУРЫ
;--------------------------------------------------------------------------
FIND_COORDINATES PROC
MOV I,0 ; НАЧАТЬ С ПЕРВОГО ЭЛЕМЕНТА
MOV J,0
MOV CX,16 ; 16 ЭЛЕМЕНТОВ В МАССИВЕ
FORLOOP:
; ПРЕОБРАЗОВАТЬ 'I'
MOV BX,I
MOV AX,8 ; (4*2) 4 ДЛИНА РЯДКА, 2 ИЗ-ЗА DW
MUL BX
MOV BX,AX
; ПРЕОБРАЗОВАТЬ 'J'
MOV SI,J
SHL SI,1
MOV AX,MAS[BX+SI] ; ВЗЯТЬ ЭЛЕМЕНТ МАССИВА ПО АДРЕСУ
MOV BX,SRCH
CMP J,4
JNE CONTINUE_LINE
MOV J,0
ADD I,1
CONTINUE_LINE:
CMP AX,BX ; СРАВНИТЬ С ПОИСКОВЫМ
JNE NOT_PRINT_COORD ; ЕСЛИ НЕ СОВПАЛИ ПЕРЕПРЫГУНТЬ ВЫВОД КООРДИНАТЫ НА ЭКРАН
MOV TMP,CX ; 'OUTPUT_PROC' ЗАТИРАЕТ 'CX'
;ВЫВОД КООРДИНАТЫ НА ЭКРАН
NEWLINE
PRINTF MES5 ; "( "
MOV AX,I ; 'OUTPUT_PROC' РАБОТАЕТ С 'AX'
INC AX ; НЕ ПРОГРАММИСТСТСТСКАЯ КООРДИНАТА
CALL OUTPUT_PROC ; ВЫВОДИТ ЦИФРУ
PRINTF MES6 ; " ; "
MOV AX,J ; 'OUTPUT_PROC' РАБОТАЕТ С 'AX'
INC AX ; НЕ ПРОГРАММИСТСТСТСКАЯ КООРДИНАТА
CALL OUTPUT_PROC ; ВЫВОДИТ ЦИФРУ
PRINTF MES7 ; " )"
;*
MOV CX,TMP ; ВОЗВРАЩАЕТСЯ СЧЕТЧИК
NOT_PRINT_COORD:
ADD J,1
LOOP FORLOOP
RET
FIND_COORDINATES ENDP
;--------------------------------------------------------------------------
OUTPUT_PROC PROC
OUTPUT AX
RET
OUTPUT_PROC ENDP
;--------------------------------------------------------------------------
CSEG ENDS ; КОНЕЦ СЕГМЕНТА КОДА
END MAIN ; ВЫХОД ИЗ ПРОГРАММЫ
MAGIC MACRO DSEG
;* MAGIC * (РАЗМЕЩЕНИЕ ПРОГРАММЫ В ПАМЯТИ?)
PUSH DS
MOV AX, 0
PUSH AX
MOV AX, DSEG ; *ИНИЦИАЛИЗАЦИЯ СЕГМЕНТНОГО
MOV DS, AX ; РЕГИСРА 'DS'*
;* MAGIC END'S *
ENDM
PRINTF MACRO STRING
MOV AH,9 ; Функция вывода строки
LEA DX,STRING ; Загружаем адрес строки
INT 21H ; Вызов прерывания DOS
ENDM
NEWLINE MACRO
MOV AL,0AH
INT 29H
ENDM
INPUT_POISKOVIY MACRO SRCH
MOV AH,01H ; СЧИТАТЬ СИМВОЛ В РЕГИСТР 'AL'
INT 21H
SUB AL,30H
XOR AH,AH ; ПОЧИСТИТЬ 'AX' ОТ '01H'
MOV SRCH,AX ; ЗАПОМНИТЬ ПОИСКОВЫЙ
ENDM
INPUT MACRO MAS,N
MOV SI,0
MOV CX,N
;START:
MOV AH,1H ;ВВЕСТИ СИМВОЛ ИЗ КОНСОЛИ
INT 21H
SUB AL,30H ;ПРЕОБРАЗОВАТЬ ЕГО
XOR AH,AH ;УБРАТЬ ИНСТРУКЦИЮ ИЗ ПОЛУРЕГИСТРА
MOV MAS[SI],AX ;ЗАПИСАТЬ ВВЕДЕННОЕ В МАССИВ
ADD SI,2
LOOP $-15 ;START:
ENDM
OUTPUT_ARRAY MACRO MAS
MOV CX,N ; КОЛ-ВО ЭЛЕМЕНТОВ МАССИВА В СЧЕТЧИК
MOV SI,0 ; НАЧИНАЕТЬСЯ С НУЛЕВОГО
;$-14
MOV DX,MAS[SI] ; ЗАКЛАДЫВАЕТЬСЯ ЭЛЕМЕНТ МАСИВА
ADD DL,'0' ; ПРЕОБРАЗОВЫВАЕТСЯ В ASCII
MOV AH,02H ; ВЫВОДИТЬСЯ НА ЭКРАН
INT 21H
ADD SI,2 ; ПЕРЕХОД К СЛЕДУЮЩЕМУ ЭЛЕМЕНТУ
LOOP $-14
ENDM
ARRAY_SUM MACRO MAS,N,TMP
XOR DX,DX
XOR AX,AX ; ОБНУЛЯЕМ 'AX'
MOV CX,N ; КОЛ-ВО ЭЛЕМЕНТОВ МАССИВА В СЧЕТЧИК
MOV SI,0 ; НАЧИНАЕТЬСЯ С НУЛЕВОГО
;$-9
MOV DX,MAS[SI] ; ЗАКЛАДЫВАЕТЬСЯ ЭЛЕМЕНТ МАСИВА
ADD AX,DX ; СУММИРУЮТЬСЯ ЭЛЕМЕНТЫ
ADD SI,2 ; ПЕРЕХОД К СЛЕДУЮЩЕМУ ЭЛЕМЕНТУ
LOOP $-9
MOV TMP,AX
ENDM
OUTPUT MACRO NUMBER
MOV AX,NUMBER
MOV BX,AX ; РАЗМЕЩЕНИЕ ЧИСЛА В РЕГИСТРЕ AX
OR BX,BX ; *ЕСЛИ ЧИЛО ПОЛОЖИТЕЛЬНОЕ
JNS $+8 ; ПЕРЕЙТИ В M1.
MOV AL,"-" ; ИНЧЕ РАЗМЕСТИТ В РЕЗУЛЬТАТЕ СИМВОЛ МИНУСА.
INT 29H ; ВЫВЕСТИ МИНУС НА ЭКРАН*
NEG BX ; ИЗМЕНИТЬ СТАРШИЙ БИТ ЧИСЛА("УБРАТЬ МИНУС")
;$+8: ; ТОЧКА ПРЕХОДА ЕСЛИ ЧИСЛО ПОЗИТИВНОЕ
MOV AX,BX ; ОБНОВИТЬ ЧИСЛО В РЕГИСТРЕ 'AX'(ИЗ-ЗА "NEG BX")
XOR CX,CX ; ОБНУЛИТЬ РЕГИСТР СЧЕТЧИКА
MOV BX,10 ; ДЛЯ РАЗДЕЛЕНИЯ ЧИСЛА НА РАЗРЯДЫ
;$-11: ; НАЧАЛО ЦИКЛА "РАЗМЕЩЕНИЕ ЧИСЛА В СТЕКЕ"
XOR DX,DX ; ОБНУЛЕНИЕ 'DX'
DIV BX ; ДЕЛЕНИЕ 'AX' НА 'BX'(ОТДЕЛЕНИЕ РАЗРЯДА)
ADD DL,"0" ; DECIMAL TO ASCII
PUSH DX ; РАЗМЕЩЕНИЕ РЕЗУЛЬТАТА В СТЕКЕ
INC CX ; УВЕЛИЧЕНИЕ СЧЕТЧИКА
TEST AX,AX ; *ЕСЛИ ЕЩЕ ОСТАЛИСЬ ЦИФРЫ В ЧИСЛЕ
JNZ $-11 ; ПОВТОРИТЬ "РАЗМЕЩЕНИЕ В СТЕКЕ"
;$-3: ; НАЧАЛО ЦИКЛА ВЫВОДА ЧИСЛА ИЗ СТЕК НА ЭКРАН
POP AX ; ДОСТАТЬ ВЕРХНЮЮ ЦИФРУ ИЗ СТЭКА
INT 29H ; ВЫВЕСТИ ЕЁ НА ЭКРАН
LOOP $-3 ; ПОВТОРИТЬ 'M3' ПОКА СЧЕТЧИК НЕ '0'
ENDM
ARRAY_MAX MACRO MAS,TMP
MOV AX,MAS[0] ;ПЕРВЫЙ ЭЛЕМЕНТ ПОМЕЩАЕТСЯ В 'AX'
MOV TMP,AX ;СЧИТАЕМ ЕГО МАКСИМАЛЬНЫМ И ЗАПОМИНАЕМ
MOV CX,N ; КОЛ-ВО ЭЛЕМЕНТОВ МАССИВА В СЧЕТЧИК
DEC CX ; ТАК КАК ПЕРВЫЙ УЖЕ ЭЛЕМЕНТ УЖЕ ПРОЙДЕН
MOV SI,2 ;ОДИН ЭЛЕМЕНТ ЯЧЕЙКИ ЗАНИМАЕТ ДВА БИТА
;$-23:
MOV AX,MAS[SI] ;СЛЕДУЮЩИЙ ЕЛЕМЕНТ ЗАКЛАДЫВАЕТСЯ В 'AX'
CMP TMP,AX ;СРАВНИВАЕТСЯ С ПРЕДПОЛАГАЕМЫМ МАКСИВАЛЬНЫМ
JL $+4 ;ЕСЛИ НОВЫЙ ЭЛЕМЕНТ БОЛЬШЕ*
JMP $+9 ;ИНЧЕ-
;$+4:
MOV AX,MAS[SI] ; "НА ВСЯКИЙ"
MOV TMP,AX ;*СЧИТАЕМ ЕГО МАКСИМАЛЬНЫМ
;$+9
ADD SI,2 ;-ПЕРЕХОДИМ К СЛЕДУЮЩЕМУ ЭЛЕМЕНТУ
LOOP $-22
ENDM
ARRAY_SORT MACRO MAS,N
XOR CX,CX ;ОЧИСТКА СЧЕТЧИКА
;$-39:
MOV CX,N ; КОЛ-ВО ЭЛЕМЕНТОВ МАССИВА В СЧЕТЧИК
DEC CX ; ЧТО БЫ ИСПОЛЬЗОВАТЬ КАК АДРЕС (ОТ 0 ДО 8)
SHL CX,1 ; ТАК КАК ХРАНИТЬСЯ СЛОВО. (СДВИГ БИТА ВЛЕВО/УМНОЖЕНИЕ НА 2)
;$-13: $-35
MOV BX,CX ;ДЛЯ ИСПОЛЬЗОВАНИЯ В ИНДЕКСАЦИИ
MOV AX,MAS[BX] ; ЗАПИСАТЬ В 'AL' ТЕКУЩИЙ ЭЛЕМЕНТ МАССИВА
CMP AX,MAS[BX-2] ; СРАВНЕНИЕ ТЕКУЩЕГО ЭЛЕМЕНТА массива с предыдущим
JL $+7 ; ЕСЛИ "СТАРШИЙ" ЭЛМЕНТ БОЛЬШЕ ПЕРЕХОДИМ В 'EXCHANGE'
DEC CX
LOOP $-13 ; ИНЧЕ ПРОДОЛЖИТЬ ПРОХОД ПО МАССИВУ
JMP $+22 ; ЕСЛИ ЦИКЛ ЗАКОНЧЕН НА ВЫХОД ИЗ ПРОЦЕДУРЫ
;$+7: ;ПОМЕНЯТЬ ЭЛЕМЕНТЫ МЕСТАМИ ЕСЛИ УСЛОВИЕ ВЫПОЛНЕНО
MOV DX,MAS[BX] ; ЗАПОМНИТЬ ТЕКУЩИЙ ЭЛЕМЕНТ
MOV AX,MAS[BX-2] ;ЗАПОМНИТЬ "МЛАДШИЙ ЭЛЕМЕНТ"
MOV MAS[BX],AX ;ПОММЕНЯТЬ ЕГО МЕСТАМИ С "СТАРШИМ"
MOV MAS[BX-2],DX ;-//-
JMP $-39
JMP $-35
;$+22:
XOR DX,DX ; НА ВСЯКИЙ ИЗБАВИТСЯ ОТ МУСОРА В 'DX'
ENDM
PRINT_COORD MACRO I,J,MES5,MES6,MES7
;ВЫВОД КООРДИНАТЫ НА ЭКРАН
NEWLINE
PRINTF MES5 ; "( "
MOV AX,I ; 'OUTPUT_PROC' РАБОТАЕТ С 'AX'
INC AX ; НЕ ПРОГРАММИСТСТСТСКАЯ КООРДИНАТА
OUTPUT AX ; ВЫВОДИТ ЦИФРУ
PRINTF MES6 ; " ; "
MOV AX,J ; 'OUTPUT_PROC' РАБОТАЕТ С 'AX'
INC AX ; НЕ ПРОГРАММИСТСТСТСКАЯ КООРДИНАТА
OUTPUT AX ; ВЫВОДИТ ЦИФРУ
PRINTF MES7 ; " )"
;*
MOV CX,TMP ; ВОЗВРАЩАЕТСЯ СЧЕТЧИК
ENDM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment