ВІКІСТОРІНКА
Навигация:
Інформатика
Історія
Автоматизація
Адміністрування
Антропологія
Архітектура
Біологія
Будівництво
Бухгалтерія
Військова наука
Виробництво
Географія
Геологія
Господарство
Демографія
Екологія
Економіка
Електроніка
Енергетика
Журналістика
Кінематографія
Комп'ютеризація
Креслення
Кулінарія
Культура
Культура
Лінгвістика
Література
Лексикологія
Логіка
Маркетинг
Математика
Медицина
Менеджмент
Металургія
Метрологія
Мистецтво
Музика
Наукознавство
Освіта
Охорона Праці
Підприємництво
Педагогіка
Поліграфія
Право
Приладобудування
Програмування
Психологія
Радіозв'язок
Релігія
Риторика
Соціологія
Спорт
Стандартизація
Статистика
Технології
Торгівля
Транспорт
Фізіологія
Фізика
Філософія
Фінанси
Фармакологія


Загрузка и выполнение программ в DOS

При загрузке программ в оперативную память DOS (дисковая операционная система) инициализирует как минимум три сегментных регистра: CS, DS и SS. При этом совокупности байтов, представляющих команды процессора (код программы), и данные помещаются из файла на диске в оперативную память, а адреса этих сегментов записываются в CS и DS соответственно. Сегмент стека либо выделяется в области, указанной в программе, либо совпадает (если он явно в программе не описан) с самым первым сегментом программы. Адрес сегмента стека помещается в регистр SS. Программа может иметь несколько кодовых сегментов и сегментов данных и в процессе выполнения специальными командами выполнять переключения между ними.

Для того чтобы адресовать одновременно два сегмента данных, например, при выполнении операции пересылки из одной области памяти в другую, можно использовать регистр дополнительного сегмента ES. Кодовый сегмент и сегмент стека всегда определяются содержимым своих регистров (CS и SS), и поэтому в каждый момент выполнения программы всегда используется какой-то один кодовый сегмент и один сегмент стека. Причем если переключение кодового сегмента – довольно простая операция, то переключать сегмент стека можно только при условии четкого представления логики работы программы со стеком, иначе это может привести к зависанию системы.

Все сегменты могут использовать различные области памяти, а могут частично или полностью перекрываться (рис. 2.1).

Кодовый сегмент должен обязательно описываться в программе, все остальные сегменты могут отсутствовать. В этом случае DOS при загрузке программы в оперативную память инициирует регистры DS и ES значением адреса префикса программного сегмента PSP (Program Segment Prefics) – специальной области оперативной памяти размером 256 (100h) байт. PSP может использоваться в программе для определения имен файлов и параметров из командной строки, введенной при запуске программы на выполнение, объема доступной памяти, переменных окружения системы и так далее. Регистр SS при этом инициализируется значением сегмента, находящегося сразу за PSP, то есть первого сегмента программы. При этом необходимо учитывать, что стек «растет вниз» (при помещении в стек содержимое регистра SP, указывающего на вершину стека, уменьшается, а при считывании из стека – увеличивается). Таким образом, при помещении в стек каких-либо значений они могут затереть PSP и программы, находящиеся в младших адресах памяти, что может привести к непредсказуемым последствиям. Поэтому рекомендуется всегда явно описывать сегмент стека в тексте программы, задавая ему размер, достаточный для нормальной работы.

 

Рассмотрим распределение памяти на примере простейшей программы.

 

;Данные программы

DATA SEGMENT

MSG DB ‘Текст$’

DATA ENDS

;Код программы

CODE SEGMENT

ASSUME CS:CODE,DS:DATA

START:

MOV AX,DATA

MOV DS,AX

MOV AH,09H ;Вывод сообщения

MOV DX,OFFSET MSG

INT 21H

MOV AH,4CH ;Завершение работы

INT 21H

CODE ENDS

END START

 

В этой программе явно описаны два сегмента – кода с именем CODE и данных с именем DATA. Директива ASSUME связывает имена этих сегментов, которые в общем случае могут быть произвольными, с сегментными регистрами CS и DS соответственно. Распределение памяти при загрузке программы на исполнение показано на рис. 2.2.

 

Как видно из рис. 2.2, сегмент стека в данном случае установлен на PSP, что при его интенсивном использовании может привести к неожиданным результатам. После инициализации в регистре IP находится смещение первой команды программы относительно начала кодового сегмента, адрес которого помещен в регистр CS. Процессор, считывая эту команду, начинает выполнение программы, постоянно изменяя содержимое регистра IP и при необходимости CS для получения кодов очередных команд до тех пор, пока не встретит команду завершения программы. DS после загрузки программы установлен на начало PSP, поэтому для его использования в первых двух командах программы выполняется загрузка DS значением сегмента данных.

EXE- и COM-программы

DOS может загружать и выполнять программные файлы двух типов COM и EXE.

Ввиду сегментации адресного пространства процессора 8086 и того факта, что переходы (JMP) и вызовы (CALL) используют относительную адресацию, оба типа программ могут выполняться в любом месте памяти. Программы никогда не пишутся в предположении, что они будут загружаться с определенного адреса (за исключением некоторых самозагружающихся, защищенных от копирования программ).

Файл COM-формата – это двоичный образ кода и данных программы. Такой файл должен занимать менее 64K и не содержать перемещаемых адресов сегментов.

Файл EXE-формата содержит специальный заголовок, при помощи которого загрузчик выполняет настройку ссылок на сегменты в загруженном модуле.

Перед загрузкой COM- или EXE-программы DOS определяет сегментный адрес, называемый префиксом программного сегмента (PSP), как базовый для программы, а затем выполняет следующие шаги:

- создает копию текущего окружения DOS (область памяти, содержащая ряд строк в формате ASCIIZ, которые могут использоваться приложениями для получения некоторой системной информации и для передачи данных между программами) для программы;

- помещает путь, откуда загружена программа, в конец окружения;

- заполняет поля PSP информацией, полезной для загружаемой программы (количество памяти, доступное программе, сегментный адрес окружения DOS, текущие векторы прерываний INT 22H INT 23H и INT 24H и т. д.).

EXE-программы

EXE-программы содержат несколько программных сегментов, включая сегмент кода, данных и стека. EXE-файл загружается, начиная с адреса PSP:0100h. В процессе загрузки считывается информация заголовка EXE в начале файла и выполняется перемещение адресов сегментов. Это означает, что ссылки типа

 

mov ax,data_seg

mov ds,ax

 

и

 

call my_far_proc

 

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

После перемещения управление передается загрузочному модулю посредством инструкции далекого перехода (FAR JMP) к адресу CS:IP, извлеченному из заголовка EXE.

В момент получения управления программой EXE -формата:

- DS и ES указывают на начало PSP;

- CS, IP, SS и SP инициализированы значениями, указанными в заголовке EXE;

- поле PSP MemTop (вершина доступной памяти системы в параграфах) содержит значение, указанное в заголовке EXE. Обычно вся доступная память распределена программе.

COM-программы

COM-программы содержат единственный сегмент (или, во всяком случае, не содержат явных ссылок на другие сегменты). Образ COM-файла считывается с диска и помещается в память, начиная с PSP:0100h. В общем случае, COM-программа может использовать множественные сегменты, но она должна сама вычислять сегментные адреса, используя PSP как базу.

COM-программы предпочтительнее EXE-программ, когда дело касается небольших ассемблерных утилит. Они быстрее загружаются, так как не требуют перемещения сегментов, и занимают меньше места на диске, поскольку заголовок EXE и сегмент стека отсутствуют в загрузочном модуле.

После загрузки двоичного образа COM-программы:

- CS, DS, ES и SS указывают на PSP;

- SP указывает на конец сегмента PSP (обычно 0FFFEH, но может быть и меньше, если полный 64K сегмент недоступен);

- слово по смещению 06H в PSP (доступные байты в программном сегменте) указывает, какая часть программного сегмента доступна;

- вся память системы за программным сегментом распределена программе;

- слово 00H помещено (PUSH) в стек;

- IP содержит 100H (первый байт модуля) в результате команды JMP PSP:100H.

Выход из программы

Завершить программу можно следующими способами:

- через функцию 4CH (EXIT) прерывания 21H в любой момент, независимо от значений регистров;

- через функцию 00H прерывания 21H или прерывание INT 20H, когда CS указывает на PSP.

Функция DOS 4CH позволяет возвращать родительскому процессу код выхода, который может быть проверен вызывающей программой или командой COMMAND.COM «IF ERRORLEVEL».

Можно также завершить программу и оставить ее постоянно резидентной (TSR), используя либо INT 27H , либо функцию 31H (KEEP) прерывания 21H. Последний способ имеет те преимущества, что резидентный код может быть длиннее 64K, и что в этом случае можно сформировать код выхода для родительского процесса.

Ассемблер, редактор связей

Входной информацией для Ассемблера (TASM.EXE) является исходный файл – текст программы на языке Ассемблера в кодах ASCII. В результате работы Ассемблера может получиться до 3-х выходных файлов:

1) объектный файл – представляет собой вариант исходной программы, записанный в машинных командах;

2) листинговый файл – является текстовым файлом в кодах ASCII, включающим как исходную информацию, так и результат работы программы Ассемблера;

3) файл перекрестных ссылок – содержит информацию об использовании символов и меток в ассемблерной программе.

Передача параметров Ассемблеру осуществляется через командную строку. Командная строка вызова Turbo Assembler записывается в следующем формате:

 

TASM [options] source [,object] [,listing] [,xref]

где options - параметры ассемблирования;

source - файл, содержащий текст программы;

object - объектный файл;

listing - листинговый файл;

xref - файл перекрестных ссылок.

 

© 2013 wikipage.com.ua - Дякуємо за посилання на wikipage.com.ua | Контакти