Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Met_Lab2.pdf
Скачиваний:
160
Добавлен:
11.05.2015
Размер:
1.1 Mб
Скачать

Рис. 3.2. Таблица символов ASCII

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

Тема работы. Использование сервисных функций DOS ввода-вывода и работа со строками.

Цель работы. Научиться работать с некоторыми функциями 21-го прерывания и строковыми переменными. Понять структуру таблицы ASCII кодов.

Содержание работы.

В данной работе происходит знакомство с функциями DOS 21-го прерывания. Вызов функций, параметры входа и параметры вывода.

П р о г р а м м а 1

1

IDEAL

2

MODEL small

3STACK 256

4

descrip_in

=

0

;Дескриптор стандартного

ввода

 

5

descrip_out = 1

;Дескриптор

стандартного

вывода

6

descrip_err

=

2

;Дескриптор

стандартной ошибки

(экрана)

7DATASEG

8

msg

Db

'Введите строку!',10,13,'$'

9

Buf

DB

80

DUP(?)

10

act_in

DW

?

11

 

CODESEG

12

Start:

 

mov ax,@data

13

 

 

mov ds,ax

14

 

 

mov ah,09h ;Функция вывода

15mov dx,offset msg ;Адрес сообщения

16int 21h

17

mov ah,3fh ;Функция ввода

18mov bx,descrip_in

19mov cx,80 ;Ввод максимум 80 байт

20mov dx,offset Buf ;Адрес буфера

21int 21h

22

mov [act_in],ax

;Фактически введено

23

mov cx,[act_in]

;Счётчик элементов строки

24

mov si,0

;Инициализация указателя элементов строки

25

filter: mov al,[Buf+si]

;Возьмём символ

26

cmp al,'a'

;Меньше 'a'?

27

jb no_letter

;Да, не преобразовывать

28

cmp al,'z'

;Больше 'z'?

29

ja no_letter

;Да, не преобразовывать

30

sub al,20h

;Преобразуем в прописную

80

31

mov [Buf+si],al

;Отправим в Buf

32

no_letter:

inc si

;Цикл

 

33

loop filter

 

34

mov ah,40h

;Функция вывода

35

mov bx,descrip_out

;Длина сообщения

36

mov cx,[act_in]

37mov dx,offset Buf ;Адрес сообщения

38int 21h

39Exit: mov ax,4C00h

40int 21h

41END Start

В данной программе происходит ввод строки с клавиатуры с дальнейшим

преобразованием полученых строчных символов в прописные.

Программа состоит из 3х основных логических блоков - ввода строки, преобразования строчных символов в прописные и вывод получившейся строки. Сначала с помощью функции 09h выводится сервисное сообщение "Введите строку", затем, функцией 3Fh производится ввод строки с клавиатуры, поскольку строковой переменной Buf в сегменте данных было выделено максимум 80 байт, то в счетчик CX так же нужно загрузить число не более 80. В регистр BX загружается дескриптор стандартного ввода, в регистр DX смещение буфера ввода.

Замечание. Поскольку адрес буфера состоит из DS:DX, а при использовании модели памяти small, мы работаем только с одним сегментом, который загружается в самом начале, то устанавливать адрес сегмента нет необходимости, нужно установить только смещение в данном сегменте.

После того, как все регистры подготовлены к функции 3Fh, производится ее вызов и программа принимает с клавиатуры строку символов.

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

Далее идет подготовка регистров к переводу строчных символов в прописные. Основной принцип данной операции заключается в том, что бы выделить из всей строки именно строчные латинские символы и уменьшить их ASCII код на 20h, если внимательно посмотреть на таблицу кодов ASCII можно увидеть что код символа каждой строчной буквы больше на 20h кода аналогичной ей прописной буквы. Выделение строчных латинских букв происходит с помощью опертора сравнения и двух операторов условного перехода. В качестве счетчика символов (указателя на номер символа в строке) используется регистр SI. Начало цикла сравнения и преобразования начинается с загрузки очередного символа в регистр AL (строка 25), на данной строке установлена метка filter для того, что бы цикл начинался именно с оператора загрузки очередного символа. Очередной символ сравнивается с символом 'a', если код очередного символа меньше кода символа 'a', произойдет переход оператором JB (если меньше) на метку no_letter (строка 32), и в результате операторы в строках 28-31 пропускаются, увеличивается указатель на символ в строке и операция повторяется. Данная часть отсекает от преобразования все символы коды которых меньше кода символа 'a'. Аналогично отсекаются все коды, которые больше кода символа 'z', при этом используется оператор JA (если больше).

В случае, если же код символа лежит в диапазоне 'a' - 'z', то ни оператор JB, ни оператор JA не вызовет перехода на метку no_letter и произойдет произойдет

81

преобразование очередного строчного символа в прописной и загрузка получившегося прописного символа в буфер (строки 30-31).

В строке 33 оператор LOOP организует цикл, длина которого находится в регистре CX, предварительно в него загружено значение act_in. Оператор LOOP будет возвращаться на метку filter, пока значение CX>0, при этом, при каждом очередно возврате CX автоматически уменьшается на 1. В завершении происходит вывод получившейся преобразованной строки на экран средствами функции 40h.

Задания к работе.

1.Измените программу таким образом, чтобы в случае, если в веденной строке не оказалось ни одной строчной латинской буквы, программа бы потребовала повторного воода строки.

2.Измените блок вывода строки таким образом, что бы вывод производился средствами функции 09h, а не 40h.

82

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

Тема работы. Работа с одиночными символами и сравнение строк.

Цель работы. Научиться использовать функции DOS для работы с одиночными символами и использование оператора сравнения строк для сравнения массива байт в памяти.

Содержание работы.

В данной работе рассматривается программа, в которой демонстрируется работа функции ввода одиночных символов с клавиатуры и процесс сравнения двух строк.

П р о г р а м м а 1

1IDEAL

2

MODEL

small

3

STACK

256

4DATASEG

5

password

DB

'tspu'

;Пароль

6

pass_len

=

$ - password

7string DB 80 DUP(?)

8 promt DB 13,10,'Введите пароль: $'

9OK DB 13,10,'Верный пароль $'

10CODESEG

11Start: mov ax,@data

12mov ds,ax

13begin: mov ah,09h

14mov dx,offset promt

15int 21h

16mov bx,0

17pass: mov ah,08h

18int 21h

19cmp al,13

20je cmpr

21mov [string+bx],al

22mov ah,02

23mov dl,'*'

24int 21h

25inc bx

26jmp pass

27cmpr: push ds

28pop es

29mov si,offset string

30mov di,offset password

31cld

32mov cx,pass_len

33 repe cmpsb

34jne Error

35mov ah,09h

36mov dx,offset OK

37int 21h

38Exit: mov ax,4C00h

39int 21h

40Error: jmp begin

41END Start

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

Для ввода пароля используется функция DOS 08h, которая считывает скан-код клавиши и заносит ASCII код, соответствующий нажатой клавиши, в регистр AL (строки 17-

83

19). Сразу после ввода идет проверка завершения ввода пароля путем сравнения содержимого регистра AL с числом 13, т.к. 13 - это ASCII код клавиши <Enter>. В случае, если нажата клавиша <Enter>, оператор JE произведет переход на метку cmpr и начнется сравнение пароля. В случае, если нажата любая другая клавиша (не <Enter>) произойдет загрузка полученного очередного символа в заранее созданную строковую переменную string. В качестве указателя на номер символа в строке используется регистр BX. Для повтора считывания символа используется оператор безусловного перехода JMP (строка 26), который будет постоянно возвращать ход программы на метку pass. Параллельно со считыванием вновь введенных символов и загрузкой их в string, в данном "цикле" размещен вызов функции 02h с предварительной загрузкой в регистр DL кода символа '*', для того, чтобы получить эффект ввода пароля - т.е. при нажатии очередной клавиши считывается ее код, загружается в строковую переменную и сразу же выводится на экран символ '*'.

Сравнение полученной строки string и строки password, в которой хранится пароль, производится с помощью оператора CMPSB, который побайтно сравнивает строки с адресами DS:SI и ES:DI. Для данного оператора используется префикс Repe, это означает, что сравнение будет происходить до тех пор, пока сравниваемые символы совпадают, но не более, чем длина, указанная заранее в CX . Перед тем, как вызвать оператор СMPSB, нобходимо подготовить все нужные регистры, а именно уравнять значения регистра сегмента данных DS и регистра расширенного сегмента данных ES, что делается в строках 27 и 28 при помощи стека, затем поместить смещение одной строки в SI, другой в DI (строки 29 и 30), и установить количество сравниваемых байт в CX (строка 32). Так же, помимо подготовки регистров нужно обнулить флаг направления DF оператором CLD (строка 31).

В случае единственного несовпадения флаг ZF станет равным 0 и сравнение закончится, при этом, так же, сработает безусловный переход оператором JNE на метку Error, которая отсылает ход программы на начало и ввод пароля повторяется.

Данная программа не закончится пока не будет введен правильный пароль, либо не будет нажато сочетание клавиш Ctrl+C.

Задания к работе.

1.Напишите программу, которая будет считывать набор из n символов средствами функции считывания одиночных символов, после считывания программа должна вывести этот набор в виде строки.

2.2

84

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]