Пример выполнения работы

Разработать подпрограмму, которая удаляет, начиная с задан­ной позиции строки, указанное число символов. Разработать про­грамму, которая вводит с клавиатуры строку, вводит позицию и длину удаляемой части строки и удаляет эту часть.

Текст программы:


locals __

model small

stack 100h

dataseg

MESS1 db 0dh,0ah,0dh,0ah,"Введите строку:",0dh,0ah,"$"

MESS2 db 0dh,0ah,"Введите позицию: $"

MESS3 db 0dh,0ah,"Введите число удаляемых символов: $"

MESS4 db 0dh,0ah,0dh,0ah,"Строка после удаления:",0dh,0ah,"$"

S_BUFLEN db 80; Макс. длина строки

S_FACTLEN db?; Длина фактически введенной строки

S_INPBUF db 80 dup (?); Введенная строка

N_BUFLEN db 3; Макс. длина числа при вводе

N_FACTLEN db?; Фактическая длина

N_INPBUF db 3 dup (?); Строка представления числа

POSDEL dw?; Позиция, начиная с которой удаляем

LENDEL dw?; Сколько символов удалить

codeseg

startupcode

; Ввод строки

MLOOP: lea DX, MESS1

mov AH, 09h

int 21h;Приглашение к вводу строки

lea DX, S_BUFLEN

mov AH, 0Ah

int 21h;Ввод строки

mov BL, S_FACTLEN

cmp BL, 0;Строка пустая?

jne LLL0;Нет - продолжать

jmp QUIT;Закончить работу

LLL0: mov BH, 0;Дополнить длину до слова

add BX, 2; и получить адрес позиции

add BX, DX; сразу после конца строки

mov byte ptr[BX],0;Записать признак конца строки

; Ввод позиции удаления

LLL1: lea DX, MESS2;Приглашение

mov AH, 09h; к вводу

int 21h; позиции удаления

lea DX, N_BUFLEN

mov AH, 0Ah

int 21h;Ввод строки числа

lea BX, N_INPBUF;Адрес строки представления числа

mov CL, N_FACTLEN;Длина этой строки

call VAL;Перевод в целое число

jc LLL1;Ошибка? - повторить ввод

cmp AL, 0;Ноль?

je LLL1;Повторить ввод

cmp AL, S_FACTLEN;Превышает длину строки?

jg LLL1;Повторить ввод

mov POSDEL, AX;Запомнить позицию удаления

; Ввод длины удаляемой части

LLL2: lea DX, MESS3;Приглашение

mov AH, 09h; к вводу

int 21h; числа удаляемых

lea DX, N_BUFLEN

mov AH, 0Ah

int 21h;Ввод строки числа удаляемых

lea BX, N_INPBUF;Адрес строки представления числа

mov CL, N_FACTLEN;Длина этой строки

call VAL;Перевод в целое число

jc LLL2;Ошибка? - повторить ввод

mov LENDEL, AX;Запомнить число удаляемых

add AX, POSDEL;Подсчитать, не выходит ли

dec AX; удаляемая часть

cmp AL, S_FACTLEN; за конец строки?

jg LLL2;Если да - повторить ввод

; Занесение параметров в стек и вызов п/п удаления

lea AX, S_INPBUF

push AX;1-й параметр - адрес строки

push POSDEL;2-й параметр - позиция удаления

push LENDEL;3-й параметр - число удаляемых

call DELSUBS;Вызов подпрограммы

; Вывод результата

lea DX, MESS4

mov AH, 09h

int 21h;Заголовок вывода

lea BX, S_INPBUF

mov CX, 80

LLL3: cmp byte ptr [BX],0;Цикл поиска конца строки и выход

je LLL4; - когда конец строки найден

inc BX;Сдвиг по строке

loop LLL3

LLL4: mov byte ptr [BX],'$';Заменить признак конца строки

lea DX, S_INPBUF

mov AH, 09h

int 21h; Вывод результата

jmp MLOOP; На повторение работы

QUIT: exitcode 0

;Действие:

; функция вычисляет целое число по его строковому представлению.

; Результат не может быть больше 255.

; Для неверно введенных чисел устанавливает флаг переноса

;Параметры:

; BX - адрес строки - предстваления числа

; CX - длина этой строки

;Возвращает:

; CF - установлен, если в строке не цифры, AX - не определен

; сброшен, строка нормальная, AX - число

; AX - преобразованное число, если сброшен

VAL proc near

push DX;Сохранить все изменяемые регистры,

; кроме AX, в котором результат

mov CH, 0;Расширяем длину до слова

mov AX, 0;Начальное значение результата

mov DL, 10;Основание системы счисления

__1: imul DL;Умножить на основание

jc __2;Переполнение байта?

mov DH, [BX];Очередная цифра

sub DH, '0';Получить значение цифры

jl __2;Это была не цифра!

cmp DH, 9

jg __2;Это опять же была не цифра!

add AL, DH;+ значение цифры к результату

jc __2;Переполнение байта?

inc BX;Сдвиг по строке

loop __1;Цикл по строке

jmp __3;Нормальное число

__2: stc;Было переполн. - устанавливаем CF

__3: pop DX;Восстановить все, что сохраняли

ret

VAL endp

; Подпрограмма удаления подстроки

DELSUBS proc near

arg __Ldel: word, __Pdel: word, __StrAdr: word = __ArgSize

;Params struc;Структура стека после сохранения BP

; SaveBP dw?; Сохраненное значение BP

; SaveIP dw?; Адрес возврата

; LDel dw?; 3-й параметр - число удаляемых

; PDel dw?; 2-й параметр - позиция удаления

; StrAdr dw?; 1-й параметр - адрес строки

;Params ends

push BP;Сохранить BP

mov BP, SP;Теперь BP адресует стек ПОСЛЕ сохр.BP,

; но ДО сохранения остальных регистров

push ES AX SI DI CX;Сохранить все изменяемые регистры

mov AX,DS; ES будет указывать на

mov ES,AX; сегмент данных

mov DI,__StrAdr;Вычислить в DI адрес,

add DI,__PDel; куда надо

dec DI; пересылать символы

mov SI,DI;А в SI - адрес,

add SI,__LDel; откуда их пересылать

cld;Продвигаться от начала строки к концу

__REPEAT:

movsb

cmp byte ptr [SI-1], 0

jne __REPEAT

pop CX DI SI AX ES;Восстановить все, что сохраняли

pop BP

ret __ArgSize;Убрать из стека 3 параметра-слова

DELSUBS endp

end

ВАРИАНТЫ ЗАДАНИЙ

В приведенных ниже вариантах заданий используется стан­дартное представление строк ASCII с кодом 0 в качестве ограни­чителя конца строки. Способ передачи параметров выбирается программистом произвольно. Рекомендуется зациклить программу по вводу, а признаком окончания работы считать ввод пустой строки.

1. Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке, и если да, то, начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает, содержится ли одна из них в другой и сколько раз.

2. Разработать подпрограмму, которая подсчитывает, сколько раз заданный символ встречается в строке. Разработать программу, которая вводит с клавиатуры строку, вводит число N и выдает список символов, которые встречаются в строке не менее чем N раз.

3. Разработать две подпрограммы, одна из которых соединяет две строки в одну, а другая обрезает строку до заданной длины (или дополняет пробелами, если длина строки меньше задан­ной). Разработать программу, которая вводит с клавиатуры число N, затем вводит несколько строк (конец ввода – пустая строка) и формирует новую строку, состоящую из первых N символов каждой введенной строки.

4. Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обмени­вает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода – пустая строка) и сортирует их в лексикографическом порядке.

5. Разработать подпрограмму, которая разбивает заданную строку на две части: первое слово строки (до первого пробела) и оста­ток строки (пробелы после первого слова отбрасываются). Раз­работать программу, которая вводит с клавиатуры строку и выводит каждое слово с новой строки.

6. Разработать подпрограмму, которая переставляет символы за­данной строки в обратном порядке. Разработать программу, ко­торая вводит с клавиатуры строку и переставляет в обратном порядке символы в каждом слове (слова разделяются пробе­лами).

7. Разработать подпрограмму, которая вставляет подстроку в строку, начиная с заданной позиции. Разработать программу, которая вводит с клавиатуры исходную строку, вводит под­строку и позицию вставки, вставляет подстроку в строку.

8. Разработать две подпрограммы, одна из которых преобразует любую заданную букву в заглавную (в том числе для русских букв), а другая - преобразует букву в строчную. Разработать программу, которая вводит с клавиатуры строку и заменяет первые буквы всех слов на заглавные, а остальные буквы - на строчные.

КОНТРОЛЬНЫЕ ВОПРОСЫ

1. Что такое «ближние» и «дальние» подпрограммы?

2. Как определяется, «ближний» или «дальний» вариант команды call использован в программе?

3. Какие еще способы передачи параметров можно предложить, кроме двух, описанных в данной работе?

4. Может ли массив быть параметром процедуры?

5. Нельзя ли адресовать параметры в стеке через регистр SP, не используя BP?

6. Что и как нужно изменить в программе из примера, если ис­пользуется версия ассемблера, не поддерживающая понятие структуры?

7. Изменить описание подпрограммы из примера с использова­нием упрощенных директив описания подпрограмм.

8. Что означает операнд команды ret?

9. Какой последовательностью команд можно было бы заменить команду ret 6?


Лабораторная работа

ÈÑÏÎËÜÇÎÂÀÍÈÅ ÏÎÄÏÐÎÃÐÀÌÌ ÍÀ ßÇÛÊÅ ÀÑÑÅÌÁËÅÐÀ  ÏÐÎÃÐÀÌÌÀÕ ÍÀ ßÇÛÊÀÕ C È PASCAL


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: