Приложение П.2.1. Примеры реализаций типового задания
В данном приложении приведены два листинга программ, самостоятельное прочтение которых поможет составлению собственных программ к данной работе. Листинг 2.3. Программа осуществляет ввод строки с произвольными ASCII-символами с последующим преобразованием строчных символов в прописные. Программа может быть дополнительно использована для изучения поведения универсальных функций ввода-вывода строковых переменных DOS (38h и 40h) при переназначении ввода-вывода данных. IDEAL MODEL small STACK 256 ; Макроопределения descrip_in = 0; Дескриптор стандартного ввода descrip_out = 1; Дескриптор стандартного вывода descrip_err = 2; Дескриптор стандартной ошибки (экрана) DATASEG msg Db 'Введите строку! ' msg_len = $-msg Buf DB 80 DUP(?) actual_len DW? CODESEG Start: mov ax, @data; Установка в ds адреса mov ds, ax; сегмента данных ; Вывод служебного сообщения msg mov ah, 40h; Функция вывода mov bx, descrip_err mov cx, msg_len; Длина сообщения mov dx, offset msg; Адрес сообщения int 21h ; Ввод строки с клавиатуры в буфер Buf mov ah, 3fh; Функция ввода mov bx, descrip_in mov cx, 80; Ввод максимум 80 байт mov dx, offset Buf; Адрес буфера int 21h mov [actual_len], ax; Фактически введено ; Преобразование строчных латинских букв в прописные mov cx, [actual_len]; Счётчик элементов строки mov si, 0; Инициализация указателя элементов строки filter: mov al, [Buf+si]; Возьмём символ cmp al, 'a'; Меньше 'a'? jb no_letter; Да, не преобразовывать cmp al, 'z'; Больше 'z'? ja no_letter; Да, не преобразовывать sub al, 20h; Преобразуем в прописную mov[Buf+si], al; Отправим в Buf no_letter: inc si loop filter; Цикл ; Вывод на экран mov ah, 40h; Функция вывода mov bx, descrip_out mov cx, [actual_len]; Длина сообщения mov dx, offset Buf; Адрес сообщения int 21h Exit: mov ax, 4C00h; Функция DOS 4Сh: выход из программы int 21h; Вызов DOS. Останов END Start; Конец программы/точка входа Листинг 2.4. Программа выполняет вставку одной строки в другую с произвольной позиции первой. Номер позиции по запросу программы задаётся с клавиатуры одной десятичной цифрой (ограниченное значение номера позиции объясняется преждевременностью решения вопроса преобразования ASCII-числа в двоичное число). Программа снабжена подробными комментариями, помогающими усвоить основные подходы в построении подобных программных продуктов. Помимо функций DOS в программе используется операция очистки экрана с помощью функции BIOS. Рассмотрению функций BIOS посвящена следующая лабораторная работа. IDEAL MODEL small STACK 256 DATASEG mes1 DB 13, 10, 'Введите первую и вторую строки', 13, 10, '$' mes2 DB 'Введите номер позиции N $' N DW? Buf1 DB 50,?, 50 DUP(?) Buf2 DB 20,?, 20 DUP(?) Buf3 DB 80 DUP(?) len_str1 DW 0 len_str2 DW 0 CODESEG Start: mov ax, @data; Установка в ds адреса mov ds, ax; сегмента данных mov es, ax call screen; Очистка экрана с установкой курсора в левый верхний угол ; Вывод запроса mes1 mov ah, 09h; Функция вывода mov dx, offset mes1; Адрес сообщения mes1 int 21h; Вызов DOS ; Последовательный ввод первой и второй строк функцией 0Ah (с эхом) в буферы Buf1 и Buf2 ; соответственно. Нулевой элемент – заявленный пользователем максимальный размер буфе- ; ра, первый- число действительно введённых байтов, второй- первый введённый элемент строки и т. д. mov dx, offset Buf1; Адрес буфера ввода для строки_1 mov ah, 0Ah int 21h; Вызов DOS mov cl, [Buf1+1]; Число элементов строки_1 mov [byte len_str1], cl; Сохраним call CR_LF; Перевод курсора на новую строку mov ah, 0Ah mov dx, offset Buf2; Адрес буфера ввода для строки_2 int 21h mov cl, [Buf2+1]; Число элементов строки_2 mov [byte len_str2], cl; Сохраним call CR_LF ; Вывод запроса mes2 и ввод номера позиции N (десятичная цифра) mov ah, 09h mov dx, offset mes2; Адрес сообщения mes2 int 21h; Вызов DOS mov ah, 01h; Функция ввода одиночного символа int 21h; Вызов DOS sub al, 30h; Преобразование ASCII- символа числа в mov [byte N], al; двоичное число и его сохранение call CR_LF ; Перезапись элементов 1-й части строки_1, т.е. элементов с индексами 0...N, в Buf3. mov si, offset Buf1+2; DS: SI- адрес строки_1 mov di, offset Buf3; ES: DI- адрес объединённой строки_3,; совпадающий с адресом Buf3 cld; DF=0- просмотр вперёд mov cx, [N] inc cx; Число пересылаемых элементов rep movsb; Переслать 1-ую часть строки_1 в буфер Buf3 mov bx, si; Сохраним адрес этого элемента строки_1 ; Перезапись строки_2 в Buf3 с позиции N mov si, offset Buf2+2; DS: SI- адрес строки_2 mov cx, [len_str2]; Число пересылаемых элементов строки_2 rep movsb; Добавить строку_2 к первой части строки_1 в Buf3 ; Перезапись 2-й части строки_1 в Buf3 (число оставшихся элементов: len_str1-N-1) mov si, bx; Восстановим адрес источника mov cx, [len_str1] sub cx, [N] dec cx; Число элементов оставшейся части строки_1 rep movsb; Переписать ; Подсчёт числа элементов объединённой строки и вывод её на экран mov cx, [len_str1] add cx, [len_str2]; Число элементов объединённой строки_3 mov ah, 40h; Функция вывода mov dx, offset Buf3; Адрес строки_3 mov bx, 1; Дескриптор экрана int 21h; Вызов DOS Exit: mov ax, 4C00h; Функция DOS 4Сh: выход из программы int 21h; Вызов DOS. Останов ; Процедура очистки экрана и установки курсора в левый верхний угол PROC screen mov ah, 06; Функция инициализации окна или его скроллинг mov al, 0; Очистка mov bh, 0Fh; Атрибут: Ярко-белый по чёрному mov cx, 0; Левый верхний угол mov dx, 184Fh; Правый нижний угол int 10h mov ah, 02; Функция установки позиции курсора mov bh, 0; Номер видеостраницы mov dx, 0; Координаты курсора (y=00, x=00) int 10h ret ENDP screen ; Процедура перевода курсора на новую строку функцией 02h PROC CR_LF push ax push dx mov ah, 02h; Функция вывода одиночного элемента mov dl, 13; CR=13-возврат каретки int 21h; Вызов DOS mov dl, 10; LF=10-перевод на новую строку int 21h pop dx pop ax ret ENDP CR_LF END Start; Конец программы/точка входа
|