Описание задач пользователя, решаемых на ЭВМ
Описание программы, создаваемое пользователем с помощью текстового редактора, представляется в виде последовательности операторов языка программирования. Операторы языка ассемблера могут быть:
1) исполняемыми (команды языка) операторами, которые транслируются из символьного представления в двоичное представление машинных инструкций (команд).
2) Неисполняемыми (называются псевдокомандами или директивами) операторами, которые не транслируются в машинные команды, а служат для управления процессом трансляции (ассемблирования), для определения данных и др.
Ниже представлены форматы операторов, размещаемых обычно в одной строке.
1. [МЕТКА:] (гт) Операция (гт) [операнд1], [операнд2] (гт) [; комментарий]
МЕТКА – это адрес ячейки, в которой расположена описываемая команда; (гт) – горизонтальная табуляция (клавиша).
2. [переменная] (гт) Операция (гт) Операнд [, операнд2, …] (гт) [; комментарий]
Переменная – адрес ячейки, начиная с которой хранятся обрабатываемые данные.
Операнды представлены некоторым выражением, задающим порядок вычисления значения операнда.
Пример:
1. mov ax, OPERAND ; копирование содержимого ячейки с именем ; (адресом) OPERAND в ячейку (регистр) ax.
2. OPERAND dw 1,3,5 ; dw – аббревиатура ключевых слов define word ;(определяющая размер ячеек в виде слова, которое соответствует двум байтам для ;представления каждого из трех заданных значений).
С помощью директив ассемблера можно осуществлять структурирование программы. Структура программы может быть одномодульной и многомодульной.
Модуль – это структурно выделенная и поименованная часть прикладной программы, предназначенная для выполнения заданных функций (решения подзадачи). Исходный модуль содержит текст программы на языке ассемблера. Исходный модуль транслируется в объектный (.obj), а из объектных модулей строится загрузочный (исполняемый) модуль. Существует два типа исполняемых модулей, именуемых с расширениями .exe и .com.
Каждый модуль может содержать одну или несколько подпрограмм (процедур). Процедура – это поименованная часть программы.
Пример структуры одномодульной программы:
TITLE prog ; имя программного модуля и поясняющий текст
………………………
Объявление глобальных и локальных переменных.
………………………
[Описание стека]
………………………
Начало сегмента данных.
Описание данных.
ENDS ; завершение сегмента
………………………
Начало сегмента программ.
Описание сегментных регистров и соответствия имен сегментов и регистров.
START: описание операторов.
ENDS ; завершение сегмента.
END START ; завершение модуля (при завершении модуля обязательно ; указывается стартовая метка).
Модулей, составляющих программу, может быть несколько. В многомодульной программе выделяется один главный модуль, который задает порядок срабатывания остальных модулей. Программа имеет иерархическую структуру.
|
При завершении описания модуля main в директиве end необходимо указать стартовую метку (только в main!). Когда создается многомодульная программа, требуются глобальные и локальные метки и переменные. Переменная – это информационный объект, имеющий текущее значение, имя, обозначающее адрес хранения текущего значения и структуру, которая может быть простой (из одного элемента) или составной. Для обеспечения взаимодействия модулей необходимо объявить глобальные метки и переменные. Объявление меток и переменных производится с помощью двух списков, задаваемых директивами EXTRN и PUBLIC. Список, задаваемый в модуле директивой EXTRN, содержит идентификаторы внешних переменных и меток, к которым осуществляется обращение из данного модуля. Второй список содержит внутренние идентификаторы, к которым разрешено обращаться из других модулей.
Далее приводятся описания некоторых директив.
TITLE текст, представляющий заголовок листинга.
Директива TITLE инициирует печать на каждой странице листинга заголовка, включающего имя модуля (6 символов) и описание (60 символов) его назначения. Листинг представляет собой текстовый файл, содержащий описание исходной ассемблерной программы, код каждой ассемблированной команды, список используемых меток, описание перекрестных ссылок, сегментов и групп сегментов.
Необходимость использования директив EXTRN и PUBLICвозникает при описаниивзаимодействующих программных модулей.
Пусть два модуля взаимодействуют следующим образом. В модуле 1 осуществляется изменение данных, хранимых в переменной F, определенной в модуле 2. Для объявления глобальной переменной F используются директивы EXTRN и PUBLIC. Для определения переменной F необходима директива, задающая тип переменной. В качестве такой директивы можно использовать, например, директиву DB – определить байт (define byte). Определение переменной задается строкой, разделенной пробелами на три части. В начале строки размещается идентификатор – имя переменной. Далее размещается аббревиатура директивы, указывающей тип именованной переменной. После аббревиатуры директивы следует перечень значений и специальных операторов, разделенных запятыми. В качестве значений используются четыре типа констант. Целые константы, заданные с помощью цифр требуемой системы счисления. Константы с плавающей запятой. Символьные константы, представленные символом, размещенным между двумя апострофами. Строковые литералы, представляемые последовательностью символов, размещенных между знаками двойных кавычек. В качестве специальных операторов используются оператор повторения константы DUP, который быть вложенным и оператор ? задания неопределенного значения.
При описании взаимодействующих модулей mod1 и mod2 необходимо в директиве EXTRN для объявляемых переменных и меток указать тип, который соответствует типу, заданному при определении переменных и меток.
TITLE mod1 TITLE mod2
EXTRN F:BYTE ;внешняя глобальная переменная. PUBLIC F
DATA SEGMENT ;начало сегмента с именем DATA. DATA SEGMENT
DATA ENDS F DB ? ; переменная F типа
DATA ENDS ; байт
CODE SEGMENT CODE SEGMENT
ASSUME CS:CODE, DS:DATA CODE ENDS
START: MOV AX, DATA END
MOV DS, AX
MOV F, 5
CODE ENDS
END START
Операнды директив EXTRN и PUBLIC разделяются запятыми.
EXTRN имя:ТИП, …, имя:ТИП
PUBLIC имя, …, имя
Типы для переменных: byte, word, dword, а другие можно найти в справочнике.
Типы для меток:
NEAR – указывает на размещение метки внутри сегмента;
FAR – указывает на размещение метки за пределами данного сегмента;
SHORT – метки указанного типа используется в инструкциях перехода для задания адреса назначения. Пределы перехода от текущей команды ограничены величинами +127 и -128 байт.
Директивы резервирования и инициализации памяти задаются строкой, в которой указываются имя переменной, ее тип с помощью аббревиатуры двух ключевых слов, например, define byte-db, а затем перечисляются значения переменной.
A DB 8,?,10,10h,10b,’’word’’
EQU – директива используется для отождествления имени и значения выражения.
Имя EQU выражение
ORG – директива изменения значения адресного счетчика, который служит для
указания значения смещения местоположения текущей команды (или данных) относительно начала сегмента.
ORG выражение
Выражение может содержать текущее значение адресного счетчика. Для обозначения текущего значения счетчика адреса используется знак $.
Директива ORG используется при описании исходного модуля, для которого создается компактный исполняемый модуль (.com), имеющий размер не более сегмента. Ниже приведено описание структуры com-программы.
TITLE com_prog
code segment
assume cs:code,ds:code,ss:code,es:code
org 100h ;для служебной информации резервируется память.
;определение данных, имеющих значения 5, 2, 7, каждое из которых представлено байтом.
F db 5,2,7 ;Fобозначает адрес ячейки памяти размером 8 бит, в которую помещено число 5.
;------------
main: add F+1,5 ; описана команда сложения величин 2 и 5.
code ends
end main
Ранее рассмотренная директива segment может иметь 5 операндов:
1) Readonly (для ассемблера MASM) – при записи в сегмент, содержащий в качестве операнда ключевое слово Readonly выдается сообщение об ошибке.
2) Операнд выравнивания сегмента, указывающий кратность адреса начала сегмента. Сегмент может начинаться с четного адреса, если используется операнд word, или с любого адреса, если используется операнд byte. По умолчанию используется выравнивание с адреса, кратного 16.
3) Операнд типа объединения сегментов.
4) Разрядность (use16, use32) сегмента.
5) Класс сегмента, обозначаемый меткой, выделенной апострофами.
Для многомодульной программы необходимо явно задать тип объединения объектных модулей в исполняемый модуль.
Если объектных модулей несколько и в них используются сегменты с одинаковыми именами, то нужно задать тип объединения сегментов для размещения их в загрузочном модуле. Формат описания сегмента следующий.
имя segment тип_объединения.
Тип указывает правило размещения сегмента в загрузочном модуле.
Public – этот тип используется для кодовых сегментов и сегментов данных. В загрузочном модуле сегменты различных объектных модулей сцепляются в один сегмент. Порядок сцепления необходим редактору связей (link).
Common – обеспечивает перекрытие сегментов. При выделении памяти указывается один начальный адрес и длина, равная длине максимального по размеру сегмента из объединяемых.
Stack – стек. Тип stack аналогичен типу public, но используется для стековых сегментов. Выделяется один сегмент, длина которого равна сумме длин отдельных стековых сегментов.
AT <выражение> ; используется для размещения сегмента в памяти по абсолютному адресу. <выражение> - константное выражение, указывающее адрес размещения сегмента в памяти.
Директива определения сегмента может быть упрощена. Для упрощения необходимо задать модель памяти.
Модель задается с помощью директивы:
.model (1) модель, (2) язык, (3) модификатор
(1) tiny – код, данные и стек находятся в одном сегменте, размер которого 65 Кбайт.
ü Small – код в одном сегменте, данные и стек в другом.
Compact – код в одном сегменте, а данные в нескольких.
Medium – код в нескольких сегментах, а данные в одном.
Huge – и код и данные в нескольких сегментах.
FLAT - то же, что и tiny, но используются сегменты размером 4 Гбайт.
(2) – можно задать имя языка программирования.
(3) NEARSTACK (по умолчанию)
FARSTACK в этом случае сегмент стека не будет объединяться в одну группу с сегментами данных.
Фрагмент программы с упрощенными директивами определения сегментов:
TITLE prog
.model small
.stack 100h
.data
len EQU 5
val db len dup(?)
mes db 10,13,’’vvod chisla: $’’;10 и 13 коды управляющих символов для перемещения ;курсора
.code
begin: mov AX, @data
mov DS, AX
Директива описания процедуры.
Процедура – это поименованная часть программы. Используется для структурирования программы. Вызывается с помощью команды call имя_процедуры. Формат описания процедуры следующий.
имя proc атрибуты
---------------------
операторы процедуры
---------------------
ret ;команда завершения процедуры
имя endp
При выполнении команды ret из стека извлекается на регистр IP адрес возврата, который был помещен в стек при выполнении команды call.
Адрес возврата может быть дальний (far). Для его хранения используются 2 слова, которые из стека перемещаются в регистры CS:IP. Если адрес возврата ближний (near), тогда для хранения используется 1 слово, перемещаемое в регистр IP. Размер слова – 2 байта. Для указания типа адреса возврата используется атрибут в директиве proc. Тип атрибута определяется местоположением тела процедуры по отношению к оператору вызова процедуры call
а) Если call и тело процедуры расположены в одном сегменте кода и в одном модуле, то используется near. Указывать явно необязательно.
б) Если call и тело процедуры расположены в разных сегментах, но в одном модуле, то используется тип far и атрибутный оператор ptr (указатель).
call FAR PTR имя
в) Если call и тело процедуры расположены в разных сегментах и в разных модулях, то используется far и еще требуется в начале модуля основной программы, содержащей call, указать имя процедуры в списке extrn, а в модуле, содержащем тело процедуры, указывается имя процедуры в списке public. В операторе call использовать тип и атрибутный оператор FAR PTR не требуется.
В теле процедуры сначала необходимо выполнить операции сохранения регистров в стеке (PUSH), а в конце процедуры восстановить (POP) содержимое регистров. Для передачи данных между процедурами существуют специальные методы. Простейший способ передачи данных в процедуру предусматривает использование глобальных переменных или регистров.
Операционная система DOS
ОС представляет собой совокупность иерархически упорядоченных программ для осуществления следующих функций.
1. Общения пользователя с ЭВМ (пользовательский интерфейс).
2. Организация и управление процессами, выполняющимися в ЭВМ.
3. Организация и управление основной (оперативной) памятью.
4. Организация и управление внешней памятью.
5. Организация и управление вводом/выводом (ближняя и дальняя связи).
Для промышленного применения используется дисковая ОС – DOS, структура которой представляется ниже.
верхний уровень
№³20
Интерфейс
Пользовательский прикладных
|
· ·
INT № - команда
№<20 прерывания
нижний функционирования.
Драйверный уровень
интерфейс
BIOS – Basic Input Output System.
Рис.6. Структура операционной системы DOS.
API – интерфейс прикладных программ.Для обращения к функциям ОС DOS в языке ассемблера используются программные прерывания. Обращение осуществляется при помощи команды int №, где № - это номер прерывания. При этом в AH – старшем байте регистра AX должен содержаться номер вызываемой функции DOS.
Рассмотрим некоторые функции программного интерфейса DOS:
01h – ввод символа (чтение с клавиатуры в AL) и отображение символа на экран (эхо).
02h – вывод на экран символа, который должен быть сформирован в DL (ASCII).
В операционной системе все устройства представляются в виде файлов.
09h– вывод на экран символьной строки, завершающейся символом ‘$’.
4Сh – завершение работы модуля и передача управления операционной системе (mov AX, 4C00h).
3Ch – создание файла. При создании необходимо в DX поместить адрес ASCIIZ-строки (строка заканчивается нулем), в которую помещено описание полного имени файла. В CX необходимо задать один из атрибутов файла:
00h – обычный файл, 01h – только для чтения, 02h – скрытый файл, 04h – системный файл, 08h – метка тома, 20h – архивный файл, 43h – изменение атрибутов файла.
3Dh – открытие файла. При открытии файла в AL задается режим доступа: 00h – только чтение, 01h – только запись, 02h – чтение и запись.
3Eh– закрытие файла. В BX должен быть помещен номер файла, полученный при открытии или создании файла
3Fh– чтение из файла или ввод с устройства. В BX должен быть номер файла.
40h– запись в файл. В BX должен быть номер файла, в CX – число байт, которые будут записаны, в DX – адрес области вывода.
42h – установка позиции для последовательного доступа к элементам файла.