Jazik_Assemblera_dlja_IBM_PC_i_programmir
.pdf0134 |
88 |
27 |
B30: |
MOV |
[BX],AH |
;Записать в TITLEX |
0136 |
43 |
|
INC |
BX |
;Следующий символ |
|
0136 |
EC |
|
||||
0137 |
E2 |
|
LOOP |
B20 |
;Повторить цикл 31 раз |
|
0139 |
C3 |
|
MAIN |
RET |
|
|
013A |
|
|
ENDP |
|
|
|
013A |
|
|
CODESG |
ENDS |
BEGIN |
|
|
|
|
|
END |
|
__________________________________________________________________________
Рис.7.6. Изменение строчных букв на прописные.
Используемый таким образом регистр BX действует как индексный регистр для адресации в памяти. Для этих целей можно использовать также регистры
SI и DI.
КОМАНДЫ СДВИГА И ЦИКЛИЧЕСКОГО СДВИГА
________________________________________________________________
Команды сдвига и циклического сдвига, которые представляют |
собой |
часть логических возможностей компьютера, имеют следующие свойства: |
|
-обрабатывают байт или слово;
-имеют доступ к регистру или к памяти;
-сдвигают влево или вправо;
-сдвигают на величину до 8 бит (для байта) и 16 бит (для слова)
-сдвигают логически (без знака) или арифметически (со знаком).
Значение сдвига на 1 может быть закодировано как непосредcтвенный операнд, значение больше 1 должно находиться в регистре CL.
Команды сдвига
----------------
При выполнении команд сдвига флаг CF всегда содержит значение последнего выдвинутого бита. Существуют следующие команды cдвига:
SHR ;Логический (беззнаковый) сдвиг вправо
SHL ;Логический (беззнаковый) сдвиг влево
SAR ;Арифметический сдвиг вправо
SAL ;Арифметический сдвиг влево
Следующий фрагмент иллюстрирует выполнение команды SHR:
MOV |
CL,03 |
; |
AX: |
|
|
MOV |
AX,10110111B |
; 10110111 |
;Сдвиг вправо на |
1 |
|
SHR |
AX,1 |
; 01011011 |
|||
SHR |
AX,CL |
; |
00001011 |
;Сдвиг вправо на |
3 |
Первая команда SHR сдвигает содержимое регистра AX вправо на 1 бит. Выдвинутый в результате один бит попадает в флаг CF, а самый левый бит регистра AX заполняется нулем. Вторая команда cдвигает содержимое регистра AX еще на три бита. При этом флаг CF последовательно принимает значения 1, 1, 0, а в три левых бита в регистре AX заносятся нули.
Рассмотрим действие команд арифметического вправо SAR:
MOV |
CL,03 |
; |
AX: |
|
MOV |
AX,10110111B ; 10110111 |
;Сдвиг вправо на 1 |
||
SAR |
AX,1 |
; 11011011 |
||
SAR |
AX,CL |
; 11111011 |
;Сдвиг вправо на 3 |
|
Команда SAR имеет важное |
отличие |
от команды SHR: для заполнения |
левого бита используется знаковый бит. Таким образом, положительные и отрицательные величины сохраняют свой знак. В приведенном примере знаковый бит содержит единицу.
При сдвигах влево правые биты заполняются нулями. Таким обpазом, результат команд сдвига SHL и SAL индентичен.
Сдвиг влево часто используется для удваивания чисел, а сдвиг вправо - для деления на 2. Эти операции осуществляются значительно быстрее, чем команды умножения или деления. Деление пополам нечетных чисел (например, 5
или 7) образует меньшие |
значения (2 или 3, |
соответственно) |
и |
устанавливает флаг CF в 1. |
Кроме того, если необходимо выполнить сдвиг на |
2 бита, то использование двух команд сдвига более эффективно, чем использование одной команды с загрузкой регистра CL значением 2.
Для проверки бита, занесенного в флаг CF используется команда JC (переход, если есть перенос).
Команды циклического сдвига
-----------------------------
Циклический сдвиг представляет собой операцию сдвига, при которой выдвинутый бит занимает освободившийся разряд. Существуют следующие команды циклического сдвига:
ROR ;Циклический сдвиг вправо
ROL ;Циклический сдвиг влево
RCR ;Циклический сдвиг вправо с переносом
RCL ;Циклический сдвиг влево с переносом
Следующая |
последовательность |
команд |
иллюстрирует |
операцию |
|
циклического сдвига ROR: |
|
|
|
|
|
MOV |
CL,03 |
; |
BX: |
|
|
MOV |
BX,10110111B |
; 10110111 |
;Сдвиг вправо на 1 |
|
|
ROR |
BX,1 |
; 11011011 |
|
||
ROR |
BX,CL |
; 01111011 |
;Сдвиг вправо на 3 |
|
Первая команда ROR при выполнении циклического сдвига переносит правый единичный бит регистра BX в освободившуюся левую позицию. Вторая команда ROR переносит таким образом три правых бита.
В командах RCR и RCL в сдвиге участвует флаг CF. Выдвигаемый из регистра бит заносится в флаг CF, а значение CF при этом поступает в освободившуюся позицию.
Рассмотрим пример, в котором используются команды циклического и простого сдвига. Предположим, что 32-битовое значение находится в регистрах DX:AX так, что левые 16 бит лежат в регистре DX, а правые - в AX. Для умножения на 2 этого значения возможны cледующие две команды:
SHL |
AX,1 |
;Умножение пары регистров |
RCL |
DX,1 |
; DX:AX на 2 |
Здесь команда SHL сдвигает все биты регистра AX влево, причем самый левый бит попадает в флаг CF. Затем команда RCL сдвигает все биты регистра DX влево и в освободившийся правый бит заносит значение из флага CF.
ОРГАНИЗАЦИЯ ПРОГРАММ
________________________________________________________________
Ниже даны основные рекомендации для написания ассемблерных программ:
1.Четко представляйте себе задачу, которую должна решить программа.
2.Сделайте эскиз задачи в общих чертах и спланируйте общую логику программы. Например, если необходимо проверить операции пеpесылки нескольких байт (как в примере на рис.7.5), начните c
определения полей с пересылаемыми данными. Затем спланируйте общую стратегию для инициализации, условного перехода и команды LOOP. Приведем основную логику, которую используют многие программисты в таком случае:
инициализация стека и сегментных регистров вызов подпрограммы цикла возврат
Подпрограмма цикла может быть спланирована следующим образом:
инициализация регистров значениями адресов и числа циклов
Метка: пересылка одного байта увеличение адресов на 1 уменьшение счетчика на 1:
если счетчик не ноль, то идти на метку если ноль, возврат
3.Представьте программу в виде логических блоков, следующих друг за другом. Процедуры не превышающие 25 строк (размер экрана) удобнее для отладки.
4.Пользуйтесь тестовыми примерами программ. Попытки запомнить все технические детали и программирование сложных программ "из головы" часто приводят к многочисленным ошибкам.
5.Используйте комментарии для описания того, что должна делать процедура, какие арифметические действия или операции сравнения будут выполняться и что делают редко используемые команды. (Например, команда XLAT, не имеющая операндов).
6.Для кодирования программы используйте заготовку программы, скопированной в файл с новым именем.
Вследующих программах данной книги важным является использование команды LEA, индексных регистров SI и DI, вызываемых процедур. Получив теперь базовые знания по ассемблеру, можем перейти к более развитому и полезному программированию.
ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ
________________________________________________________________
-Метки процедур (например, B20:) должны завершаться двоеточием для указания типа NEAR. Отсутствие двоеточия приводит к ассемблерной ошибке.
-Метки для команд условного перехода и LOOP должны лежать в границах -128 до +127 байт. Операнд таких команд генерирует один байт объектного кода. Шест. от 01 до 7F соответствует десятичным значениям от +1 до +127,
ашест. от FF до 80 покрывает значения от -1 до +128. Так как длина машинной команды может быть от 1 до 4 байт, то соблюдать границы не просто. Практически можно ориентироваться на размер в два экрана исходного текста (примерно 50 строк).
- При использовании команды LOOP, инициализируйте регистр CX положительным числом. Команда LOOP контролирует только нулевое значение, при отрицательном программа будет продолжать циклиться.
- Если некоторая команда устанавливает флаг, то данный флаг сохраняет это значение, пока другая команда его не изменит. Например, если за арифметической командой, которая устанавливает флаги, следуют команды MOV, то они не изменят флаги. Однако, для минимизации числа возможных ошибок, cледует кодировать команды условного перехода непосредственно после команд, устанавливающих проверяемые флаги.
-Выбирайте команды условного перехода соответственно операциям над знаковыми или беззнаковыми данными.
-Для вызова процедуры используйте команду CALL, а для возврата из процедуры - команду RET. Вызываемая процедура может, в свою очередь, вызвать другую процедуру, и если следовать существующим соглашениям, то команда RET всегда будет выбирать из стека правильный адрес возврата. Единственные примеры в этой книге, где используется переход в процедуру вместо ее вызова - в начале COM-программ.
-Будьте внимательны при использовании индексных операндов. Сравните:
MOV AX,SI
MOV AX,[SI]
Первая команда MOV пересылает в регистр AX содержимое регистра SI. Вторая команда MOV для доступа к пересылаемому слову в памяти использует относительный адрес в регистре SI.
- Используйте команды сдвига для удваивания значений и для деления пополам, но при этом внимательно выбирайте соответствующие команды для знаковых и беззнаковых данных.
ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ
________________________________________________________________
7.1.Какое максимальное количество байт могут обойти команды коpоткий JMP, LOOP и относительный переход? Какой машинный код операнда при этом генерируется?
7.2.Команда JMP начинается на шест.0624. Определите адрес перехода, если шест. объектный код для операнда команды JMP: а) 27, б) 6B, в) C6.
7.3.Напишите программу вычисления 12 чисел Фибоначчи: 1, 1, 2, 3, 5, 8, 13,... (каждое число в последовательности представляет собой сумму двух предыдущих чисел). Для организации цикла используйте команду LOOP.
Выполните ассемблирование, компоновку и с помощью отладчика |
DEBUG |
трассировку программы. |
|
7.4.Предположим, что регистры AX и BX содержат знаковые данные, a CX
иDX - беззнаковые. Определите команды CMP (где необходимо) и команды безусловного перехода для следующих проверок:
а) значение в DX больше, чем в CX? б) значение в BX больше, чем в AX? в) CX содержит нуль?
г) было ли переполнение?
д) значение в BX равно или меньше, чем в AX? е) значение в DX равно или меньше, чем в CX?
7.5. На какие флаги воздействуют следующие события и какое значение этих флагов?
a) произошло переполнение; б) результат отрицательный; в) результат нулевой;
г) обработка в одношаговом режиме; д) передача данных должна быть справа налево.
7.6.Что произойдет при выполнении программы , приведенной на рис.7.4, если в процедуре BEGIN будет отсутствовать команда RET?
7.7.Какая разница между кодированием в директиве PROC опеpанда с
типом FAR и с типом NEAR?
7.8.Каким образом может программа начать выполнение процедуры?
7.9.В EXE-программе процедура A10 вызывает B10, B10 вызывает C10, а C10 вызывает D10. Сколько адресов, кроме начальных адресов возврата в DOS, содержит стек?
7.10.Предположим , что регистр BL содержит 11100011 и поле по имени BOONO содержит 01111001. Определите воздействие на регистр BL для следующих команд: а) XOR BL,BOONO; б) AND BL,BOONO; в) OR BL,BOONO; г) XOR BL,11111111B; д) AND BL,00000000B.
7.11.Измените программу на рис.7.6 для: а) определения содержимого TITLEX заглавными буквами; б) преобразование заглавных букв в строчные.
7.12.Предположим, что регистр DX содержит 10111001 10111001, а pегистр CL - 03. Определите содержимое регистра DX после следующих несвязанных команд: а) SHR DX,1; б) SHR DX,CL; в) SHL DX,CL; г) SHL DL,1; д) ROR DX,CL; е) ROR DL,CL; ж) SAL DH,1.
7.13.Используя команды сдвига, пересылки и сложения, умножьте содержимое регистра AX на 10.
7.14.Пример программы, приведенной в конце раздела "сдвиг и циклический сдвиг", умножает содержимое пары регистров DX:AX на 2.
Измените |
программу |
для: а) умножения на 4; б) деления на 4; в) умножения |
48 бит в |
регистрах |
DX:AX:BX на 2. |
ГЛАВА 8 Экранные операции I: Основные свойства
__________________________________________________________________________
Ц е л ь: Объяснить требования для вывода информации на экран, а также для ввода данных с клавиатуры.
ВВЕДЕНИЕ
________________________________________________________________
В предыдущих главах мы имели дело с программами, |
в которых |
данные |
||||
oпределялись в операндах команд |
(непосредственные |
данные) |
или |
|||
инициализировались в конкретных полях программы. Число |
практических |
|||||
применений таких программ в действительности |
мало. |
Большинcтво программ |
||||
требуют ввода данных с клавиатуры, диска или модема и |
обеспечивают |
вывод |
||||
данных в удобном формате на экран, |
принтер |
или |
диск. |
Данные, |
||
предназначенные для вывода на экран и |
ввода |
с клавиатуры, |
имеют |
ASCII |
||
формат. |
|
|
|
|
(прерывание). |
|
Для выполнения ввода и вывода используется команда INT |
||||||
Существуют различные требования для указания системе какое действие |
(ввод |
или вывод) и на каком устройстве необходимо выполнить. Данная глава
раскрывает основные требования для вывода |
информации |
на экран |
и ввода |
|||||||
данных с клавиатуры. |
и |
клавиатурные |
операции |
можно |
выполнить |
|||||
Все необходимые экранные |
||||||||||
используя команду INT 10H, которая передает управление |
|
непосредственно |
в |
|||||||
BIOS. Для выполнения некоторых более |
сложных |
операций |
|
существует |
||||||
прерывание более высокого уровня INT |
21H, |
которое |
сначала |
передает |
||||||
управление в DOS. Например, при вводе с |
клавиатуры |
может |
потребоваться |
|||||||
подсчет введенных символов, проверку на |
максимальное |
|
число |
символов |
и |
|||||
проверку на символ Return. Преpывание DOS INT 21H |
выполняет многие из этих |
|||||||||
дополнительных вычислений и |
затем |
автоматически |
передает |
управление |
в |
BIOS.
Материал данной главы подходит как для монохромных (черно-белых, BW),
так и для цветных видеомониторов. В гл. 9 и 10 приведен материал для управления более совершенными экранами и для использования цвета.
КОМАНДА ПРЕРЫВАНИЯ: INT
________________________________________________________________
Команда INT прерывает обработку программы, передает управление в DOS или BIOS для определенного действия и затем возвращает управление в прерванную программу для продолжения обработки. Наиболее часто прерывание используется для выполнения операций ввода или вывода. Для выхода из программы на обработку прерывания и для последующего возврата команда INT выполняет следующие действия:
-уменьшает указатель стека на 2 и заносит в вершину стека содержимое флагового регистра;
-очищает флаги TF и IF;
-уменьшает указатель стека на 2 и заносит содержимое регистра CS в стек;
-уменьшает указатель стека на 2 и заносит в стек значение командного указателя;
-обеспечивает выполнение необходимых действий;
-восстанавливает из стека значение регистра и возвращает управление в прерванную программу на команду, следующую после INT.
Этот процесс выполняется полностью автоматически. Необходимо лишь определить сегмент стека достаточно большим для записи в него значений регистров.
В данной главе рассмотрим два типа прерываний: команду BIOS INT 10H и команду DOS INT 21H для вывода на экран и ввода с клавиатуры. В последующих примерах в зависимости от требований используются как INT 10H
так и INT 21H.
УСТАНОВКА КУРСОРА
________________________________________________________________
Экран можно представить в виде двумерного пространства с адресуемыми позициями в любую из которых может быть установлен курсор. Обычный видеомонитор, например, имеет 25 строк (нумеруемых от 0 до 24) и 80 столбцов (нумеруемых от 0 до 79). В следующей таблице приведены некоторые примеры положений курсора на экране:
________________________________________________________
|
Дес. формат |
Шест. формат |
Положение |
______________ |
______________ |
строка столбец |
строка столбец |
________________________________________________________
Верхний левый угол |
00 |
00 |
00 |
00 |
Верхний правый угол |
00 |
79 |
00 |
4F |
Центр экрана |
12 |
39/40 |
00 |
27/28 |
Нижний левый угол |
24 |
00 |
18 |
00 |
Нижний правый угол |
24 |
79 |
18 |
4F |
________________________________________________________
Команда INT 10H включает в себя установку курсора в любую позицию и очистку экрана. Ниже приведен пример установки курсора на 5-ую строку и 12-ый столбец:
MOV |
AH,02 |
;Запрос на установку курсора |
MOV |
BH,00 |
;Экран 0 |
MOV |
DH,05 |
;Строка 05 |
MOV |
DL,12 |
;Столбец 12 |
INT |
10H |
;Передача управления в BIOS |
Значение 02 в регистре AH указывает команде INT 10H на выполнение операции установки курсора. Значение строки и столбца должны быть в регистре DX, а номер экрана (или страницы) в регистре BH (обычно 0). Содержимое других регистров несущественно. Для установки строки и столбца можно также использовать одну команду MOV c непосредственным шест. значением:
MOV DX,050CH ;Строка 5, столбец 12
ОЧИСТКА ЭКРАНА
________________________________________________________________
Запросы и команды остаются на экране пока не будут смещены в результате прокручивания ("скроллинга") или переписаны на этом же месте другими запросами или командами. Когда программа начинает cвое выполнение, экран может быть очищен. Очищаемая область экрана может начинаться в любой позиции и заканчиваться в любой другой позиции с большим номером. Начальное значение строки и столбца заносится в регистр DX, значение 07 - в регистр BH и 0600H в AX. В следующем примере выполняется очистка всего экрана:
MOV |
AX,0600H |
;AH 06 |
(прокрутка) |
MOV |
BH,07 |
;AL 00 |
(весь экран) |
;Нормальный атрибут (черно/белый) |
|||
MOV |
CX,0000 |
;Верхняя левая позиция |
|
MOV |
DX,184FH |
;Нижняя правая позиция |
|
INT |
10H |
;Передача управления в BIOS |
Значение 06 в регистре AH указывает команде INT 10H на выполнение операции очистки экрана. Эта операция очищает экран пробелами; в следующей главе скроллинг (прокрутка) будет рассмотрен подробнее. Если вы по ошибке установили нижнюю правую позицию больше, чем шест. 184F, то очистка перейдет вновь к началу экрана и вторично заполнит некоторые позиции пробелами. Для монохромных экранов это не вызывает каких-либо неприятностей, но для некоторых цветных мониторов могут возникнуть серьезные ошибки.
ЭКРАННЫЕ И КЛАВИАТУРНЫЕ ОПЕРАЦИИ: БАЗОВАЯ ВЕРСИЯ DOS
________________________________________________________________
Обычно программы должны выдать на экран сообщение о завершении или об обнаружении ошибки, отобразить запрос для ввода данных или для получения указания пользователя. Рассмотрим сначала методы, применяемые в базовой версии DOS, в последующих pазделах будут показаны расширенные методы, введенные в DOS версии 2.0. Операции из базовой DOS работают во всех версиях, хотя в руководстве по DOS рекомендуется применять расширенные возможности для новых разработок. В базовой версии DOS команды вывода на экран более сложны, но команды ввода с клавиатуры проще в использовании, благодаря встроенным проверкам.
ВЫВОД НА ЭКРАН: БАЗОВАЯ ВЕРСИЯ DOS
________________________________________________________________
Вывод на экран в базовой версии DOS требует определения текстового сообщения в области данных, установки в регистре AH значения 09 (вызов функции DOS) и указания команды DOS INT 21H. В процессе выполнения операции конец сообщения определяется по oграничителю ($), как это показано ниже:
NAMPRMP |
DB 'Имя покупателя?','$' |
|
. |
. |
AH,09 |
;Запрос вывода на экран |
MOV |
||
LEA |
DX,NAMPRMP |
;Загрузка адреса сообщ. |
INT |
21H |
;Вызов DOS |
Знак ограничителя "$" можно кодировать непосредственно |
после cимвольной |
|||
строки (как показано в примере), внутри строки: 'Имя покупателя?$', или |
в |
|||
следующем операторе DB '$'. Используя данную операцию, нельзя вывести |
на |
|||
экран символ |
доллара "$". Кроме того, если знак |
доллара |
будет |
|
отсутствовать |
в конце строки, то на экран будут выводиться все последующие |
|||
символы, пока |
знак "$" не встретиться в памяти. |
|
|
|
Команда LEA загружает адрес области NAMPRMP в регистр DX для передачи в DOS адреса выводимой информации. Адрес поля NAMPRMP, загружаемый в DX по
команде LEA, является oтносительным, поэтому |
для |
вычисления |
абсолютного |
||||||||
адреса данных DOS складывает значения регистров DS и DX (DS:DX). |
|
|
|
||||||||
ПРОГРАММА: ВЫВОД НА ЭКРАН НАБОРА СИМВОЛОВ КОДА ASCII |
|
|
|
|
|
||||||
________________________________________________________________ |
|
||||||||||
Большинство из 256 кодов |
ASCII |
имеют |
символьное |
|
представление, |
и |
|||||
могут быть выведены на экран. |
Шест. коды 00 и FF |
не |
имеют |
символов |
и |
||||||
выводятся на экран в виде пробелов, хотя символ |
пробела |
имеет |
в |
ASCII |
|||||||
шест. код 20. |
|
|
|
|
|
|
на |
экран |
полный |
||
На рис.8.1 показана COM-программа, которая выводит |
|
||||||||||
набор символов кода |
ASCII. Программа |
вызывает |
три |
процедуры; |
|
B10CLR, |
|||||
C10SET и D10DISP. |
Процедура B10CLR очищает |
экран, а |
|
процедура |
C10SET |
||||||
устанавливает курсор в положение 00,00. Процедура |
D10DISP |
|
выводит |
||||||||
содержимое поля CTR, которое в |
начале |
инициализировано |
значением |
00 |
и |
||||||
затем yвеличивается на 1 при каждом выводе на |
экран, |
пока |
не |
достигнет |
|||||||
шест. значения FF. |
|
|
|
|
|
|
|
|
|
|
|
__________________________________________________________________________
TITLE |
page |
60,132 |
ALLASC |
(COM) Вывод на экран ASCII-символов 00-FF |
|
CODESC |
SEGMENT |
PARA 'Code' |
|
ASSUME |
CS:CODESG,DS:CODESG,SS:CODESG,ES:NOTHING |
BEGIN: |
ORG |
100H |
JMP |
SHORT MAIN |
|
CTR |
DB |
00,'S' |
;Основная процедура:
; |
PROC |
------------------ |
|
MAIN |
NEAR |
;Очистить экран |
|
|
CALL |
B10CDR |
|
|
CALL |
C10SET |
;Установить курсор |
|
CALL |
D10DISP |
;Вывести символ на экран |
MAIN |
RET |
|
|
ENDP |
|
|
;Очистка экрана:
; |
PROC |
-------------- |
|
B10CLR |
AX,0600H |
|
|
|
MOV |
|
|
|
MOV |
BH,07 |
;Левая верхняя позиция |
|
MOV |
CX,0000 |
|
|
MOV |
DX,184FH |
;Правая нижняя позиция |
|
INT |
10H |
|
B10CLR |
RET |
|
|
ENDP |
|
|
;Установка курсора в 00,00:
; |
------------------------- |
C10SET PROC |
AN,02 |
MOV |
MOV |
BN,00 |
MOV |
DX,0000 |
INT |
10H |
RET |
|
C10SET ENDP
;Вывод на экран ASCII символов:
; |
----------------------------- |
|
D10DISP PROC |
CX,256 |
;256 итераций |
MOV |
||
LEA |
DX,CTR |
;Адрес счетчика |
D20 |
AH,09 |
;Функция вывода символа |
MOV |
||
INT |
21H |
;Увеличить счетчик |
INC |
CTR |
|
LOOP |
D20 |
;Уменьшить CX, |
RET |
|
; цикл, если не ноль |
|
;Вернуться |
|
D10DISP ENDP |
|
|
CODESG ENDS |
BEGIN |
|
END |
|
__________________________________________________________________________
Рис.8.1. Вывод на экран набора символов кода ASCII
Так как символ доллара не выводится на экран и кроме того коды от шест.08 до шест.0D являются специальными управляющими cимволами, то это приводит к перемещению курсора и другим управляющим воздействиям. Задание: введите программу (рис.8.1), выполните ассемблирование, компоновку и преобразование в COM-файл. Для запуска программы введите ее имя, например,
В:ASCII.COM.
Первая выведенная строка начинается с пробельного символа (шест.00), двух "улыбающихся лиц" (шест.01 и 02) и трех карточных символов (шест.03, 04 и 05). Код 07 выдает звуковой сигнал. Код 06 должен отобразиться карточным символом "пики", но управляющие символы от шест.08 до 0D сотрут его. Код 0D является "возвратом каретки" и приводит к переходу на новую (следующую)строку. Код шест.0E - представляется в виде музыкальной ноты. Символы после шест.7F являются графическими.
Можно изменить программу для обхода управляющих символов. Ниже приведен пример фрагмента программы, позволяющий обойти все символы между шест.08 и 0D. Вы можете поэкспериментировать, oбходя только, скажем, шест.08 (возврат на символ) и 0D (возврат каретки):
CMP |
CTR,08H |
;Меньше чем 08? |
|
JB |
D30 |
; да - принять |
|
CMP |
CTR,0DH |
; Меньше/равно 0D? |
|
JBE |
D40 |
; да - обойти |
|
D30: |
AH,40H |
;Вывод символов < 08 |
|
MOV |
|||
... |
21H |
; |
и > 0D |
INT |
|
|
|
D40: |
CTR |
|
|
INC |
|
|
ВВОД ДАННЫХ С КЛАВИАТУРЫ: БАЗОВАЯ ВЕРСИЯ DOS
________________________________________________________________
Процедура ввода данных с клавиатуры проще, чем вывод на экран. Для ввода, использующего базовую DOS, область ввода требует наличия cписка параметров, содержащего поля, которые необходимы при выполнении команды INT. Во-первых, должна быть определена максимальная длина вводимого текста. Это необходимо для предупреждения пользователя звуковым сигналом,
если набран слишком длинный текст; символы, превышающие максимальную длину не принимаются. Во-вторых, в списке параметров должно быть определенное поле, куда команда возвращает действительную длину введенного текста в байтах.
Ниже приведен пример, в котором определен список параметров для области ввода. LABEL представляет собой директиву с атрибутом BYTE. Первый байт содержит максимальную длину вводимых данных. Так как это однобайтовое поле, то возможное максимальное значение его - шест.FF или 255. Второй байт необходим DOS для занесения в него действительного числа введенных символов. Третьим байтом начинается поле, которое будет содержать введенные символы.
NAMEPAR |
LABEL |
BYTE |
;Список параметров: |
||
MAXLEN |
DB |
20 |
|
; Максимальная длина |
|
ACTLEN |
DB |
? |
DUP (' ') |
; |
Реальная длина |
NAMEFLD |
DB |
20 |
; |
Введенные символы |
Так как в списке параметров директива LABEL |
не |
занимает |
места, то |
|
NAMEPAR и MAXLEN указывают на один и тот же aдрес |
памяти. В |
трансляторе |
||
MASM для определения списка параметров в виде |
структуры |
может |
||
использоваться также директива STRUC. Однако, в связи с тем, что ссылки на |
||||
имена, определенные внутри, требуют специальной |
адресации, |
воздержимся |
cейчас от рассмотрения данной темы до гл.24 "Директивы ассемблера".
Для запроса на ввод необходимо поместить в регистр AH номер функции -
10 (шест. 0AH), загрузить адрес списка |
параметров (NAMEPAR в нашем |
||
примере) в регистр DX и выполнить INT 21H: |
|
||
MOV |
AH,0AH |
;Запрос функции ввода |
|
LEA |
DX,NAMEPAR |
;Загрузить адреса списка параметров |
|
INT |
21H |
;Вызвать DOS |
Команда INT ожидает пока пользователь не введет с клавиатуры текст, проверяя при этом, чтобы число введенных cимволов не превышало максимального значения, указанного в списке параметров (20 в нашем примере). Для указания конца ввода пользователь нажимает клавишу Return. Код этой клавиши (шест. 0D) также заносится в поле ввода (NAMEFLD в нашем примере). Если, например, пользователь ввел имя BROWN (Return), то cписок параметров будет содержать информацию:
дес.: |20| 5| В| R| O| W| N| #| | | | | ...
шест.: |14|05|42|52|4F|57|4E|0D|20|20|20|20| ...
Во второй байт списка параметров (ACTLEN в нашем примере) команда заносит длину введенного имени - 05. Код Return находится по адресу NAMEFLD +5. Символ # использован здесь для индикации конца данных, так как шест. 0D не имеет отображаемого символа. Поскольку максимальная длина в 20 символов включает шест.0D, то действительная длина вводимого текста может быть только 19 символов.
ПРОГРАММА: ВВОД И ВЫВОД ИМЕН
________________________________________________________________
EXE-программа, приведенная на рис. 8.2, запрашивает ввод имени, затем отображает в середине экрана введенное имя и включает звуковой сигнал. Программа продолжает запрашивать и отображать имена, пока пользователь не нажмет Return в ответ на очередной запрос. Рассмотрим ситуацию, когда пользователь ввел имя TED SMITH:
1.Разделим длину 09 на 2 получим 4, и
2.Вычтем это значение из 40, получим 36
Команда SHR в процедуре E10CENT сдвигает длину 09 на oдин бит вправо, выполняя таким образом деление на 2. Значение бит 00001001 переходит в