Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лабы / 10_zad

.txt
Скачиваний:
70
Добавлен:
18.04.2022
Размер:
9.83 Кб
Скачать
locals ;Турбо Ассемблер использует двух символьный код, присоединяе-
мый к идентификаторам в виде префикса и определяющий, что иденти-
фикатор в процедуре имеет локальную область действия. Это префикс
локального идентификатора обозначается как @@. Для разрешения
идентификаторов, имеющих локальную область действия, можно ис-
пользовать директиву LOCALS (кароче для того чтобы юзать метки @@)
DOSSEG ;Директива DOSSEG приводит к тому, что сегменты в программе
Ассемблера будут сгруппированы в соответствии с соглашениями по
упорядочиванию сегментов фирмы Microsoft. В данным момент вам не
следует вникать в смысл того, что это означает. Запомните просто,
что почти все автономные программы на Ассемблере будут прекрасно
работать, если вы начнете их с директивы DOSSEG :))))
//shift
в si - индекс, адрес строки. Начиная с этого адреса ищем конец строки. Дойдя, мы увеличиваем строку на 6 байт (number - 6 букв), переставляем посимвольно, пока не дойдем до слова. Вставляем на его место слово number

.model small
.stack 100h
.data
len db 200 ;длина строки
res db 0 ;резервный байт (для чтения)
string db 200 dup('$') ;сама строка
number db 'number$' ;строка 'number' с '$' на конце - определяет конец строки

.code
;процедура сдвига строки на 6 байтов вправо (для того чтобы вставить на это место 'number')
;в si - адрес строки с нужного места
shift proc near ;proc - для описания процедуры, процедуры near содержат ближний возврат управления
cld ;очистка флага направления DF (он контролирует поведение команд обработки строк)
mov di, si ;регистр SI – является индексом источника и применяется для некоторых операций над строками; регистр DI – является индексом назначения и применяется так же для строковых операций
xor cx, cx ; cx - счетчик циклов
@@1:
mov bl, byte ptr [si] ;в bl записываем символы из si(??)
cmp bl, '$' ;дошли до $, переходим к @@2
je @@2
inc cx ;увеличиваем на 1 счетчик циклов
inc si ;увеличиваем на 1 адрес строки
jmp @@1
@@2:
inc cx ;увеличиваем на 1 счетчик циклов
mov di, si
add di, 6 ;в di - адрес строки с нужного места, т.е. добавляем 6 байт
@@3:
mov bl, byte ptr [si] ;записываем конкретный байт из si в di через bl(??)
mov byte ptr [di], bl
dec si ;уменьшаем всех на 1
dec di
loop @@3 ;уменьшаем значение цикла на 1, если не равно 0, то продолжаем цикл, если = 0, то выходим из цикла,
продолжаем программу (типа пока у нас все байты из si не перепишутся в di(??)
ret ;возврат из процедуры
shift endp ;завершаем shift shift сдвигает

;процедура копирования 'number' в строку
;в di - адрес строки с нужного места
copy proc near
cld ;очистка флага направления DF
lea si, number
mov cx, 6
rep movsb ;rep - повторить операцию, movsb копирует один байт из ячейки памяти по
ret ;возврат из процедуры
copy endp ;завершаем copy copy вставляет

;поиск числа
;в si - адрес строки с нужного места
find proc near определить, что символ не пробел и не конец строки. В противном случае возвращаем указатель и запускаем find заново
mov di, si
mov bl, 1
@@start:
mov ah, byte ptr[si]
cmp ah, 13 ;если в ah 13(??) переход к @@4
je @@4
cmp ah, ' ' ;если в ah пусто переход к @@1
je @@1
jmp @@3 ;переход к @@3
@@1:
cmp bl, 1 ;если в bl 1 переход к @@2
je @@2
mov bl, 1 ;в bl записываем 1
inc si ;si aka адрес строки с нужного места прибавляем 1
mov di, si ;в di записываем то что в si
jmp @@3 ;переход к @@3
@@2: текущий указатель на конец слова
mov ax, di ;в регистр ax то что в di
ret ;возврат из процедуры
@@4: мы не прошли слово, но первый символ - конец строки, значит, строка кончилась
cmp bl, 1 ;если в bl 1 переход к @@2
je @@2
mov ax, 0 ;в регистр ax 0
ret ;возврат из процедуры
@@3:
mov ah, byte ptr[si]
cmp ah, '0' ;если в ah < '0' переход к @@5
jl @@5 ;инструкция JL выполняет короткий переход, если первый операнд МЕНЬШЕ второго операнда при выполнении операции сравнения с помощью команды CMP
cmp ah, '9' ;если ah > '9' переход к @@5
jg @@5 ;инструкция JG выполняет короткий переход, если первый операнд БОЛЬШЕ второго операнда при выполнении операции сравнения с помощью команды CMP
inc si ;si +1
jmp @@start ;переход к start
@@5:
mov bl, 0 ;в bl 0
inc si ;si +1
jmp @@start ;переход к start
find endp ;закончили find

;переход на новую линию (для вывода)
newline proc near
mov dl,10
mov ah,2
int 21h
ret
newline endp

;ввод строки
input proc near
mov ah, 0Ah
int 21h
ret
input endp

;вывод строки
output proc near
mov ah, 9
int 21h
ret
output endp

;основной алгоритм
do proc near
;в si - адрес строки
lea si, string
@@1:
push si
;вызываем функцию find - ищем первую позицию числа
call find
pop si ;команда POP копирует содержимое ячейки памяти по адресу SS:SP в операнд и увеличивает значение регистра стека на размер операнда
;сравниваем ax с 0 (ax - возвращаемое значение функции find)
;если ноль - завершаем операцию
cmp ax, 0
je @@2
;иначе:
mov si, di
;сдвигаем строку с позиции ax на 6 символов вправо (с помощью функции shift)
push di
call shift
pop di
;копируем 'number' в нужную часть строки
call copy
;в si - адрес строки
lea si, string
;начинаем сначала (ищем цифру, увеличиваем на 6 символов, вставляем 'number')
jmp @@1
@@2:
ret
do endp

;главная функция (точка входа)
start proc near
mov ax, @data
mov ds, ax
mov es, ax
xor ax, ax
;ввод строки
mov dx, offset len
call input
;основной алгоритм
call do
;переход на новую строку
call newline
;вывод полученной строки
mov dx, offset string
call output
;ожидание ввода символа
mov ah, 0
int 16h
;завершение программы
mov ah, 4Ch
mov al, 0
int 21h
start endp
end start

//10
find ищет слова, состаящие из цифр
shift вставляет number
//11 shift стирает
//в 11 - не сдвигается, а перезаписывается.
12:
shift - исходя из длины слова мы совершаем смещение и на это место вставляем number
Соседние файлы в папке лабы
  • #
    18.04.20229.83 Кб7010_zad.txt
  • #
    18.04.20222.12 Кб685.asm
  • #
    18.04.2022656 б505.obj
  • #
    18.04.20227.34 Кб797.asm
  • #
    18.04.2022855 б697.obj
  • #
    18.04.20225.73 Кб509.asm