Исследование процессов вводавывода информации и системы арифметических команд x86 микропроцессоров семейства Intel. Учебное пособие
.pdfможно вводить символы с клавиатуры, имеющие формат 1 байт или прочитать 150 байт с жёсткого диска. В области памяти buffer_2 могут, например, размещаться результаты различных вычислений, размером в 2 байта каждый. Область памяти, обозначенная как buffer_3, всегда должна заполняться данными, имеющими формат 4 байта. Эти области памяти иногда предварительно заполняют нулями или символом $, например:
buffer_1 db 150 dup(0)
или
buffer_1 db 150 dup(’$’)
Здесь оператор dup означает дублирование.
Если в программе заранее создаётся какой-то массив чисел, например, 127, 5678, 9573, 752, то в сегменте данных после идентификатора .data следует написать инструкцию:
Array_1 dw 127, 5678, 9573,752
Отметим, что несколько аналогичных массивов, только под другими названиями, могут располагаться в сегменте данных.
Если в какой-то точке программы необходимо вывести на экран монитора некоторое сообщение, например, слово ’ASSEMBLER’, то в сегменте данных .data нужно сформировать инструкцию вида:
String_1 db ’ASSEMBLER’,’$’,
т.е. выводимую на экран информацию заключают в кавычки (одинарные или двойные – неважно). В конце сообщения обязательно ставится символ ’$’, означающий окончание вывода. Для того чтобы информация выводилась с новой строки, в области памяти .data формируется инструкция:
end_line db 0dh, 0ah,’$’,
41
где код 0dh (ASCII – код) обозначает управляющий символ CR – перевод курсора на начало текущей строки, а код 0ah – управляющий символ LF – перевод курсора на одну позицию вниз. Для исполнения этих инструкций язык ASSEMBLER использует специальные подпрограммы, называемые прерываниями. Так, например, для перевода маркера в начало новой строки и вывода заранее заготовленного текста на экран монитора используется прерывание под номером 21h с функцией DOS 09h, которая предварительно загружается командой mov в регистр ah. Само прерывание вызывается командой int 21h. Например, для вывода на экран с новой строки слова ASSEMBLER в тексте программы в сегменте кода необходимо поместить следующий фрагмент:
mov ah,09h
mov dx,offset end_line
int 21h
mov dx,offset string_1
int 21h
Здесь оператор offset означает, что в регистр dx загружается начальный адрес области памяти с данными end_line, а затем области памяти с данными string_1.
Отметим, что исполняемая часть программы, т.е. сегмент кода, всегда должна располагаться после идентификатора .code и обязательно начинаться меткой, например, start или begin или любой другой. После метки начала программы всегда должны стоять две команды:
mov ax,@data
mov ds,ax
Эти две команды обеспечивают загрузку в сегментный регистр ds начального адреса сегмента данных. С этих двух команд всегда должен начинаться сегмент кода всех программ, использующих малую модель памяти. Это необходимо делать, так как в начале исполнения программы сегментные регистры ds и es всегда
42
настроены на начало области памяти, называемой префиксом программного сегмента. Отметим, что непосредственно загружать операндом сегментные регистры командой mov, как и другими командами, нельзя. При необходимости для быстрой настройки регистра es на начало сегмента данных (после того, как регистр ds уже настроен) можно воспользоваться следующими командами:
push ds pop es
Здесь команда push ds загружает содержимое регистра ds в вершину стека, а команда pop es извлекает из вершины стека два ранее записанных байта и помещает их в регистр es.
Конец программы всегда должен заканчиваться следующими инструкциями:
mov ax,4c00h
int 21h
end start
Первые две команды обеспечивают выход работающей программы после её завершения в операционную систему DOS. Метка после команды end всегда должна совпадать с меткой, с которой начинается исполняемая часть программы. Таким образом, ассемблерная программа, выводящая на экран монитора с новой строки слово ASSEMBLER, будет иметь вид:
.model small
.stack 100h
.data
end_line db 0dh, 0ah,’$’
string_1 db ’ASSEMBLER’,’$’
.code
begin:
mov ax,@data
43
mov ds,ax mov ah,09h
mov dx,offset end_line int 21h
mov dx,offset string_1 int 21h
mov ax,4c00h int 21h
end begin
Отметим, что описание структуры сегмента данных в исходном тексте программы может располагаться и в конце программы перед командой end begin.
Для запоминания на жестком диске набранной программы нажимается клавиша F2, а затем клавиша Esc, и после этого имя набранного Вами файла с расширением .asm появится в DOSовских панелях. Для повторного открытия данного файла с целью его редактирования необходимо нажать клавишу F4. После редактирования текста программы отмеченные выше действия для записи файла на диск повторяются, т.е. нажимаются клавиши F2, а затем Esc.
После набора текста программы и его записи на диск необходимо выполнить трансляцию программы и её компоновку. Трансляция исходной программы осуществляется с помощью DOSовской программы tasm.exe. Для этого формируется командная строка вида:
D:\SHELLS>tasm.exe lab_1.asm
Командную строку можно сформировать следующим образом: вначале маркер (светлая полоса) устанавливается на файл tasm.exe и нажимаются клавиши Ctrl – Enter, затем маркер устанавливается на файл lab_1.asm и также нажимаются клавиши Ctrl – Enter. После формирования командной строки нажимается клавиша Enter и тогда в DOSовских панелях (на жестком диске), если нет синтаксических ошибок в исходном тексте программы, появляется объектный файл с
44
расширением obj, т.е. lab_1.obj. Этот файл необходимо скомпоновать с встроенными в операционную систему DOS вспомогательными программами, например подпрограммами, которые обслуживают различные прерывания. Компоновка программы осуществляется также с помощью DOSовской программы tlink.exe. Для этого набирается командная строка вида:
D:\SHELLS>tlink.exe lab_1.obj
и нажимается клавиша Enter. После этого на диске появится файл с картой распределения памяти lab_1.map и готовый к исполнению бинарный файл с расширением exe, т.е. lab_1.exe. Для его исполнения подводится маркер к этому файлу и нажимается клавиша Enter. Если при трансляции программы были обнаружены ошибки, то объектный файл с расширением .obj не образуется, и некоторую информацию о них можно получить, нажав клавиши Ctrl–o. Эти клавиши используются и для просмотра результата выполнения готовой программы. Для возврата в DOSовские панели после просмотра результатов трансляции или выполнения программы также используется комбинация этих клавиш.
45
ПРАКТИЧЕСКАЯ ЧАСТЬ
Лабораторная работа № 1 ИССЛЕДОВАНИЕ ПРОЦЕССА ВЫВОДА ТЕКСТОВОЙ
ИНФОРМАЦИИ ИЗ ПАМЯТИ ПЭВМ НА ЭКРАН МОНИТОРА
Цель работы – изучить особенности составления программы на языке ассемблер для вывода заранее составленного текста в самой программе в сегменте данных на экран монитора с помощью прерывания int 21h и функции DOS 09h, изучить работу ассемблерных команд передачи данных, передачи управления, а также выполнить программную задержку выводимой информации на экран монитора с помощью регистров РОН CX и BX.
Порядок выполнения лабораторной работы
1. Подготовка к работе Изучить теоретический материал, приведенный в теоретической
части (см. Команды и передачи данных (задание № 1). Основные правила при разработке программ на языке ASSEMBLER (для задания № 2).
2. Последовательность выполнения работы Последовательность выполнения работы изложена выше (см.
Основные правила при разработке программ на языке ASSEMBLER).
Задание № 1
Набрать приведённый выше текст программы, заменив в нем выводимое сообщение ’ASSEMBLER’ на предложение ’Я изучаю ассемблер’, составленное на английском языке, получить исполняемый файл с расширением exe, запустить его и посмотреть результат работы программы, т.е. выполнить практически все выше рассмотренные этапы разработки и исполнения ассемблерной программы.
46
Задание № 2
Так как результат работы выполненной программы мгновенно исчезает с экрана монитора и его можно наблюдать только после нажатия клавиш Ctrl–o, в предыдущую программу перед выполнением команд:
mov ax,4c00h
Int 21h
необходимо ввести временную задержку для устранения этого недостатка.
Временную задержку можно организовать на основе использования регистров блока РОН. Например, в какой-то регистр загружается определённое число. Затем из содержимого этого регистра вычитается единица и проверяется его содержимое на ноль. Если его содержимое не равно нулю, то опять вычитается единица и т.д., пока в этом регистре не окажется ноль. Таким образом, на время вычитания единицы и будет происходить временная задержка в дальнейшем выполнении программы, т.е. в её завершении и выходе в операционную систему DOS. Для вычитания единицы из содержимого регистра используется команда dec имя регистра, а для прибавления единицы – inc имя регистра, например:
dec bx
inc si
Проверку содержимого регистра на ноль осуществляют, используя так называемый z-бит, который устанавливается в единицу при нулевом содержимом регистра после выполнения некоторых операций, в частности команды dec. Для этого могут использоваться две команды условных переходов:
jz метка или
jnz метка
Первая команда обеспечивает переход на метку при нулевом содержимом регистра, т.е. при z=1, а вторая – при z=0, когда
47
содержимое регистра не равно нулю. Для автоматической организации операции вычитания, проверки содержимого на ноль и условного перехода по нулю (либо не по нулю) в рассматриваемых микропроцессорах используются регистр cx, который предварительно загружается определённой константой. После этого в программе могут использоваться команды:
loop метка loopz метка loopnz метка
Первая команда обеспечивает переход при нулевом содержимом регистра cx, вторая – при (cx)=0 и z=1, третья – при (cx)≠0 и z=0.
Таким образом, с учётом изложенного выше, сформируйте задержку в исходной программе перед её выходом в DOS. Вначале используйте только регистр cx. Если задержка окажется недостаточной, то используйте дополнительный регистр из блока РОН, например bx, и команды dec и jnz ,т.е. организуйте цикл в цикле.
Контрольные вопросы
1.Из каких основных частей состоит ВМ86?
2.Какие сегментные регистры входят в состав ВМ86 и какие функции они выполняют?
3.Какие индексные регистры входят в состав ВМ86 и какие функции они выполняют?
4.Какие регистры общего назначения входят в состав ВМ86 и какие функции они выполняют?
5.Какие флажки состояния ВМ86 входят в состав регистра флагов?
6.Для чего нужны команды передачи данных?
7.Какие способы адресации данных существуют?
8.Как работает команда MOV и какие ограничения на ее применение существуют?
9.Из каких частей состоит ассемблерная программа, которая использует малую модель памяти? Каким оператором начинается сегмент данных в ассемблерной программе, которая использует малую модель памяти?
48
Лабораторная работа № 2 ИССЛЕДОВАНИЕ ПРОЦЕССА ВЫВОДА ASCII-КОДОВ
НА ЭКРАН МОНИТОРА ПЭВМ
Цель работы – изучить особенности составления программы на языке ассемблер для вывода ASCII-символов на экран монитора, начиная с символа восклицательный знак (!) и заканчивая символом DEL – забой. При этом использовать прерывание int 21h и функции
DOS 02h.
Порядок выполнения лабораторной работы
1. Подготовка к работе Изучить теоретический материал, приведенный в теоретической
части (см. Команды и передачи данных и Основные правила при разработке программ на языке ASSEMBLER, лабораторную работу № 1.
2. Последовательность выполнения работы Последовательность выполнения работы изложена выше (см.
Основные правила при разработке программ на языке ASSEMBLER).
Задание
На примере первой ассемблерной программы мы познакомились с одним из способов вывода текста на экран, а именно – вызовом функции DOS 09h. Это далеко не единственный способ вывода текста
– DOS представляет для этого ещё несколько функций.
Функция DOS 02h. Записать символ в STDOUT (стандартное устройство вывода, в данном случае – экран) с проверкой на Ctrl –
Break.
Вход: ah=02h
dl=ASCII – код символа
Выход: al=код последнего записанного символа (равен dl, кроме случая, когда dl=09h (табуляция), тогда в al возвращается 20h.
49
Данная функция обрабатывает некоторые управляющие символы: BEL (07h) – появляется звуковой сигнал, BS (08h) – курсор перемещается влево на одну позицию, HT (09h) – используется для замены на несколько пробелов. Назначение символов LF (0ah) и CR (0dh) было описано выше.
Если в ходе работы этой функции была нажата комбинация клавиш Ctrl – Break или Ctrl – C, вызывается прерывание 23h, которое по умолчанию осуществляет выход из программы.
Таким образом, используя подфункцию 02h и прерывание 21h, необходимо составить программу, которая выводит на экран все ASCII-символы, начиная с символа восклицательный знак (!) и заканчивая символом DEL – забой, т.е. необходимо вывести 95 символов. Первый отмеченный символ имеет код 21h. Следовательно, этот код перед выводом следует загрузить в регистр dl и вызвать прерывание 21h. Каждый последующий выводимый на экран символ имеет код на единицу больший, чем предыдущий, т.е. код кавычек (") будет 21h, код символа (#) будет 22h и.т.д. Последний выводимый код забоя будет иметь значение 7fh. Из сказанного следует, что для получения последующего кода из предыдущего можно воспользоваться командой inc dl, используемой в теле цикла, который необходимо организовать в программе для вывода отмеченных выше 95 символов на экран монитора. Между выводимыми символами предусмотреть вывод пробелов, имеющих код 20h. Отметим, что перед выводом пробела готовый к выводу очередной код символа в регистре dl следует поместить в стек командой push dx, т.е. временно его сохранить, а после формирования пpобела на экране, восстановить его в регистре командой pop dx. Для организации циклического участка программы используйте регистр cx и команду loop метка. В начале выполнения программы предусмотрите вывод на экран сообщения 'OUT ASCII-CODE ON MONITOR', затем,
пропустив одну строку, выводите сами символы. В конце программы также сформируйте временную задержку для наблюдения результатов работы Вашей программы.
50
