Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
001.doc
Скачиваний:
1
Добавлен:
12.11.2019
Размер:
275.97 Кб
Скачать

Глава 2. Выполнение программ.

ГЛАВА 3. Формат языка ассемблера

ГЛАВА 4. Ассемблирование и выполнение программы

ПРИЛОЖЕНИЕ 1 Коды ASCII-символов. [4].

Тема 2. Работа с экраном и клавиатурой.

Задание: Написать программу, выводящую в центр экрана содержимое командной строки программы. (см. префикс программного сегмента - PSP). Добавить в программу обработку стрелок и клавиши esc, так, чтобы строка символов перемещалась по экрану в соответствии с нажатой стрелкой (с учётом размера экрана – т.е. строка не должна выходить за размеры экрана). ESC – для выхода из программы.

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

Условно, лабораторную работу можно разделить на две части. Первая, вывод содержимого командной строки в центр экрана с предварительной очисткой. Вторая, обработка нажатия клавиш перемещения курсора («стрелок»).

В префиксе программного сегмента PSP (см. электронный справочник) по смещению 80h находится информация о количестве введённых в командной строке символов.

Например: При запуске вашей программы

D:\821…\>laba2.com abdc

всё, что написано после laba2.com вместе с первым после имени программы пробелом попадает в префикс программного сегмента, при чём количество этих символов - по смещению 80h от начала PSP, а по смещению 81h – собственно содержимое командной строки ( abdc). Сам префикс начинается по нулевому смещению от начала сегмента кодов, т.е. адрес сегмента кодов совпадает с адресом PSP.

Прежде всего, необходимо определиться с тем, какой функцией какого прерывания выводить строковую информацию на экран, т. к. от этого зависит последовательность дальнейших действий при написании программы. Для вывода можно воспользоваться возможностями DOS или BIOS прерываний. (См. int 10h BIOS, int 21h DOS)

Для того, что бы взять данные в ОП по смещению Х от начала сегмента, можно воспользоваться непосредственной, индексной или базовой адресацией:

mov регистр, [Х]; , где Х – базовый (bx, bp) или индексный регистр (si, di) или численная константа.

Например,

mov ax, [], означает, поместить в регистр ах содержимое ОП по смещению от начала текущего сегмента. Значение смещения, находится в регистре. Напоминание! В реальном режиме работы МП в качестве базового регистра могут использоваться только bx, bp.

Аналогично, и наоборот:

mov [X], data; где data – может принять значение регистра или константы – как численной, так и строковой. Строковая константа имеет вид: ‘A’, где A – буква или другой символ, В ТОМ ЧИСЛЕ И СИМВОЛ ЦИФРЫ!

Если провести аналогию между оперативной памятью (ОП) и матрицей, то можно сказать, что ОП - это одномерный массив бит, в котором адресуются (индексируются) байты. Т.е. под индексом матрицы понимается номер байта в ОП (его адрес), а под содержимым матрицы по данному индексу (A[I]) – значение в ОП, находящееся по данному адресу.

Часть программы, называемая префиксом программного сегмента инициализируется (заполняется) операционной системой в момент запуска программы. Программист может использовать помещенную в PSP информацию по своему усмотрению в соответствии с правилами написания программ на ассемблере, т.е. читать либо изменять содержимое оперативной памяти.

Содержание справки по PSP в электронном справочнике:

Когда программа начинает выполнение, DS:0000 и ES:0000 указывают на начало PSP

этой программы. Информация PSP позволяет выделить имена файлов и опции из строки

команд, узнать объем доступной памяти, определить окружение и т.д.

Смещ. Длина Содержимое

----- ----- --------------------------------------------------------------------

--------¬

+0 2 ¦INT 20H¦ EXE-программы могут делать сюда JMP или RET для выхода

+---+---+

+2 2 ¦MemTop ¦ вершина доступной памяти системы в параграфах

+---+----

+4 1 ¦ ¦ (резервируется)

+---+-------T-------¬

+5 5 ¦CALL смещ. сегмент¦ FAR CALL к диспетчеру функций DOS

L---+---+---+---+----

+6 ¦ Avail ¦ доступные байты в программном сегменте

----+---+---+---¬ (только для файла COM)

+0aH 4 ¦смещ. сегмент¦ Адрес завершения. См. INT 22H

+---+---+---+---+

+0eH 4 ¦смещ. сегмент¦ Адрес обработки Ctrl-Break. См. INT 23H

+---+---+---+---+

+12H 4 ¦смещ. сегмент¦ Обработчик критич. ошибок. См. INT 24H

+---+---+-------+ - -----¬

+16H 16H ¦ Резервная область DOS ¦

+---+---+---+---+ - -+----

+2cH 2 ¦EnvSeg ¦ Сегментный адрес окружения DOS

+---+---+-------- - -----¬

+2eH 2eH ¦ Резервная область DOS ¦

+---+---+---+---+ - -+---+

+5cH 10H ¦ форматир. обл. парам.1 ¦ как в FCB для 1-го параметра команды

+---+---+---+---+ - -+---+

+6cH 14H ¦ форматир. обл. парам.2 ¦ как в FCB для 2-го параметра команды

+---+---+---+---+ - -+----

+80H 1 ¦len¦ длина области UPA (с адреса 81H)

+---+------------ - -----¬ также смещение умалчиваемой DTA

+81H 7fH ¦ неформатир. обл. парам.¦ символы из командной строки DOS

L---+---+---+---+ - -+---- (исключая директивы переназначения)

100H Размер префикса программного сегмента

Для понимания того, как работать с клавиатурой, необходимо принять во внимание, что это - периферийное устройство ввода данных, которое имеет свой процессор, имеющий так называемый буфер и закрепляющий за каждой клавишей определённый номер. Буфер предназначен для накопления информации о нажатии клавиш: сколько раз и какая из них была нажата. Каждая из клавиш имеет свой уникальный номер – скан-код, позволяющий центральному процессору обрабатывать каждое нажатие, как определённый символ и интерпретировать его в соответствии с работой той или иной программы.

Так как клавиатура является общим (разделяемым) ресурсом для всех пользовательских программ, то в случае использования ввода данных в вашей программе, предварительно необходимо очистить буфер клавиатуры от попавших туда символов.

Для этих целей можно использовать функцию 0сh прерывания int 21h. Необходимым дополнительным параметром которой, является номер функции, которая должна быть вызвана после неё.

mov ah, 0ch ; указание номера функции 21го прерывания для очистки

;буфера клавиатуры

mov al, 08h ; указание номера функции 21го прерывания,

; которая будет вызвана следующей

int 21h ;приказ выполнится (вызов 21го прерывания)

Даная (08h прерывания int 21h) функция производит чтение символа с клавиатуры, помещая его в регистр al.

Стрелки на клавиатуре относятся к «управляющим символам», как и F1…F12. Такие клавиши при вводе в регистр al передают 0h при первом вызове функции 08h прерывания int 21h, и лишь при 2м чтении в этом регистре буден скан-код:

mov ah, 0ch ; указание номера функции 21го прерывания

mov al, 08h ; указание номера функции 21го прерывания,

; которая будет вызвана следующей

int 21h ;приказ выполнится (вызов 21го прерывания)

mov ah,08h ; указание номера функции 21го прерывания

int 21h

Скан-коды клавиш есть в электронном справочнике. Сравнивая содержимое регистра al с нужным кодом, можно управлять ходом программы:

cmp al, 48h ; сравнение al с 48h

je метка ; если равно – переход на метку

; иначе выполнение следующего оператора.

Рассмотрим пример работы с данными.

Предположим, что в области данных программы описано следующее байтовое поле:

имя поля директива размера содержимое

a db ‘байтовое поле’

;Далее идет текст программы…

….

Следующие два оператора делают, с точки зрения программы, одинаковые действия: в регистр bx помещается адрес начала байтового поля.

1) mov bx, offset a ;

2) lea bx, a ;

В случае работы с байтовым полем как с массивом допускается индексация: a[0], a[1], a[bx], a[si] и т.д., причем индекс 1го элемента – 0!

mov a[6],’ы’

mov a[11],’я’

В результате выполнения этих операторов в поле а будет содержаться: ‘байтовые поля’.

При работе с данными без использования имен необходимо применять смещения относительно начало сегмента. Если программа пишется изначально как *.com, то данные и код располагаются внутри одного и того же сегмента, если же - *.exe, то код программы находится в сегменте кода (CS), а данные– в сегменте данных (DS) (см. приложение Б). Для явного указания относительно начала какого сегмента берется смещение, используют префикс смены сегмента (ds:):

mov ds:[bx+81h],’$’

В данном примере показано, что в качестве базового сегмента берется ds. В квадратных скобках показан способ использования базовой адресации со смещением, т.е. в результате выполнения этой команды в область памяти по смещению bx+81h от начала ds помещается символ $.

Литература.

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