close

Вход

Забыли?

вход по аккаунту

?

МЕТОД УКАЗАНИЯ ОРГ ЭВМ v1.0

код для вставкиСкачать
ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
"ТВЕРСКОЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ"
(ГОУВПО "ТГТУ")
Кафедра ЭВМ
Сегментная адресация и сегментная структура программ. Программы с несколькими сегментами команд.
Методические указания к лабораторным работам по курсу
"Организация ЭВМ и систем"
для студентов специальности 230101
"Вычислительные машины, комплексы, системы и сети"
Тверь 2008
Методическое указание разработано в соответствии с рабочей программой по дисциплине "Организация ЭВМ и систем" для студентов специальности 230101 и предназначено для оказания помощи студентам в подготовке к выполнению лабораторных работ по данной дисциплине.
Составили: Карельская К.А., Блохин К.Л., Рачишкин А.А.
(c) Тверской государственный технический университет
Раздел 1
Теоретическая часть
1.1. Разрядность процессора
Важнейшей характеристикой любого процессора является его разрядность. Процессор 8086
Процессор 8086 имеет 16-разрядную внутреннюю архитектуру и 16-разрядную шину данных. Максимальное целое число, которое может быть адресовано, составляет 216 - 1, то есть 64 Кб. Однако, адресная шина имеет 20 линий. Это соответствует адресному пространству 220, то есть 1 Мб. Для того, чтобы с помощью 16-разрядных адресов можно было обращаться в любую точку 20-разрядного адресного пространства, в микропроцессоре предусмотрена сегментная адресация памяти, реализуемая с помощью четырех сегментных регистров.
Рисунок 1 - Образование физического адреса из сегментного адреса и смещения
32-разрядные процессоры
32-разрядные процессоры имеют 32-разрядную шину, что соответствует адресному пространству 232 = 4 Гб. Однако описанный способ сегментный адресации памяти не позволяет выйти за пределы 1 Мб. Для преодоления этого в 32-разрядных процессорах используют 2 режима работы: режим реального адреса и защищенный режим (режим виртуальной защиты адресов).
В реальном режиме 32-разрядный процессор функционирует как процессор 8086 с повышенным быстродействием, может обращаться только к 1 Мб адресного пространства, а остальная память используется в защищенном режиме. В защищенном режиме используются сегменты и смещения в них, но начальный адрес сегментов не вычисляется, а извлекается из специальной таблицы - Таблицы Дескрипторов Сегментов. Каждый сегментный дескриптор занимает 8 байт, половина из них отводится на сегментный адрес - таким образом обеспечивается полное использование 32-разрядного адресного пространства.
1.2. Регистры процессора 8086
Процессор содержит 12 программно адресуемых 16-разрядных регистров, которые делятся на группы.
Регистры данных
* AX - аккумулятор
* BX - базовый
* CX - счетчик
* DX - регистр данных
Каждый регистр данных содержит младший и старший байт, например, АХ = AH + AL (рисунок 2), к которым можно обращаться отдельно. Программа может использовать регистры по своему усмотрению: для временного хранения объектов и выполнения операций.
Рисунок 2 - Регистр данных АХ
Регистры-указатели (индексные регистры)
* SI - индекс источник
* DI - индекс приемника
* BP - указатель базы
* SP - указатель стека
Эти регистры могут использоваться произвольным образом, но их основное назначение - хранение индексов и смещений относительно некоторой базы. Адрес базы хранится в базовом регистре.
Сегментные регистры
* CS - регистр сегмента команд
* DS - регистр сегмента данных
* ES - регистр дополнительного сегмента данных
* SS - регистр сегмента стека
Эти регистры хранят начальные адреса сегментов программы и обеспечивают возможность доступа к этим сегментам. Сегментные регистры не могут выступать в качестве регистров общего назначения.
1.3. Сегментная адресация
Обращение к любым участкам памяти осуществляется исключительно посредством сегментов. Сегмент - это логическое образование, накладываемое на требуемые участки физического адресного пространства. Размер сегмента должен находиться в пределах от 0 до 64 Кб (допустимо иногда использовать сегменты нулевой длины).
Любая выполняемая программа должна состоять из сегментов. Обычно их 3: > сегмент команд (код)
> сегмент данных
> сегмент стека
Однако, возможна интеграция сегментов стека и/или данных в сегмент кода.
Суть сегментной адресации заключается в следующем: физический 20-разрядный адрес любой ячейки памяти вычисляется процессором путем сложения начального адреса сегмента памяти, в котором располагается эта ячейка, со смещением к ней (в байтах) от начала сегмента, которое иногда называют относительным адресом. Сегментный адрес без четырех младших битов (рисунок 1), то есть деленный на 16, хранится в одном из сегментных регистров. При вычислении физического адреса процессор умножает содержимое сегментного регистра на 16 и прибавляет к полученному 20-разрядному адресу относительный адрес. Умножение базового адреса на 16 увеличивает диапазон адресуемых ячеек до величины 64 Кб * 16 = 1 Мб.
Программа с несколькими сегментами команд
В случае, если в программе имеется только один сегмент команд, то суммарный объем команд во всех процедурах не может превысить 64 Кб. Но иногда для написания программы необходимо превысить это ограничение. Однако увеличить размер сегмента нельзя; если суммарный объем команд программы превышает 64 Кб, в ней следует организовать несколько сегментов команд. Программа, содержащая несколько сегментов команд, в принципе может иметь линейный характер. В этом случае сначала выполняются все команды первого сегмента, затем процессор переходит к выполнению команд второго сегмента, и так далее. Для того, чтобы организовать такую программу, надо осуществлять переход не в пределах одного сегмента, а в другой сегмент команд. Однако удобнее большую программу составить из процедур-подпрограмм. В этом случае надо уметь вызывать подпрограммы из другого сегмента. Любое обращение к другому сегменту команд носит название дальнего или межсегментного. Обращение же в пределах одного сегмента называется ближним или внутрисегментным. В соответствии с этим различаются команды ближних и дальних переходов, а также команды ближних и дальних вызовов подпрограмм.
Программа с несколькими сегментами данных
Часто относительно несложная программа обрабатывает значительные по объему массивы данных. В таких случаях требуется увеличивать число сегментов данных. При наличии нескольких сегментов данных возникают проблемы их адресации. Поскольку процессор имеет только 2 сегментных регистра данных DS и ES (в современных процессорах предусмотрены дополнительные сегментные регистры FS и GS), то в каждый момент времени в программе могут быть доступны только 2 сегмента данных общим объемом 128 Кб. Если число сегментов данных в программе больше 2, работать с ними придется последовательно, предварительно настраивая сегментные регистры данных на требуемую пару сегментов. 1.4. Стек
Стеком называют область программы для временного хранения произвольных данных. Отличительной особенностью стека является своеобразный порядок выборки содержащихся в нем данных: в любой момент времени в стеке доступен только элемент, загруженный в стек последним (дисциплина LIFO - Last In First Out). Элементы стека располагаются в области памяти, отведенной под стек, начиная со дна стека, то есть с его максимального адреса, по последовательно уменьшающимся адресам. Адрес верхнего доступного элемента хранится в регистре-указателе стека SP. Стек должен входить в один из имеющихся сегментов или образовывать отдельный сегмент. Сегментный адрес этого сегмента помещается в регистр SS. Таким образом, пара регистров SS и SP описывают адрес доступной ячейки стека: в SS хранится сегментный адрес стека, а в SP - относительный адрес текущей доступной ячейки (рисунок 3).
Рисунок 3 - организация стека: а - исходное состояние, б - после загрузки первого элемента (в данном примере - содержимого регистра AX), в - после загрузка второго элемента (содержимого регистра DS), г - после выгрузки одного элемента, д - после выгрузки двух элементов и возврата в исходное состояние.
Загрузка в стек осуществляется специальной командой работы со стеком - push. Эта команда сначала уменьшает на 2 содержимое указателя стека, а затем помещает операнд по адресу, находящемуся в SP. Если, например, мы хотим временно сохранить в стеке содержимое регистра AX, следует выполнить команду:
pushAX
Если спустя какое-то время нам понадобилось восстановить исходное содержимое сохраненных в стеке регистров, мы должны выполнить команду выгрузки из стека - pop:
popAX
1.5. Модели памяти
Модели памяти задаются директивой .MODEL так:
.model модель,язык,модификатор
1. Модель - одно из следующих слов:
* TINY - код, данные и стек размещаются в одном и том же сегменте размером до 64 Кб. Эта модель памяти чаще всего используется при написании на ассемблере небольших программ;
* SMALL - код размещается в одном сегменте, а данные и стек - в другом (для их описания могут применяться разные сегменты, но объединенные в одну группу). Эту модель памяти также удобно использовать для создания программ на ассемблере;
* COMPACT - код размещается в одном сегменте, а для хранения данных могут использоваться несколько сегментов, так что для обращения к данным требуется указывать сегмент и смещение (данные дальнего типа);
* MEDIUM - код размещается в нескольких сегментах, а все данные - в одном, поэтому для доступа к данным используется только смещение, а вызовы подпрограмм применяют команды дальнего вызова процедуры;
* LARGE и HUGE - и код, и данные могут занимать несколько сегментов;
* FLAT - то же, что и TINY, но используются 32-битные сегменты, так что максимальный размер сегмента, содержащего и данные, и код, и стек, - 4 Мб.
2. Язык - необязательный операнд, принимающий значения C, PASCAL, BASIC, FORTRAN, SYSCALL и STDCALL. Если он указан, подразумевается, что процедуры рассчитаны на вызов из программ на соответствующем языке высокого уровня, следовательно, если указан язык C, все имена ассемблерных процедур, объявленных как PUBLIC, будут изменены так, чтобы начинаться с символа подчеркивания, как это принято в C.
3. Модификатор - необязательный операнд, принимающий значения NEARSTACK (по умолчанию) или FARSTACK. Во втором случае сегмент стека не будет объединяться в одну группу с сегментами данных.
1.6. Процедуры
Процедурой в ассемблере является все то, что в других языках называют подпрограммами, функциями, процедурами и т.д. Ассемблер не накладывает на процедуры никаких ограничений - на любой адрес программы можно передать управление командой CALL, и оно вернется к вызвавшей процедуре, как только встретится команда RET. Такая свобода выражения легко может приводить к трудночитаемым программам, и в язык ассемблера были включены директивы логического оформления процедур.
метка proc язык тип USES регистры
...
ret
метка endp
Все операнды PROC необязательны.
* Операнд язык определяет взаимодействие процедуры с языками высокого уровня. В некоторых ассемблерах директива PROC позволяет также считать параметры, передаваемые вызывающей программой. В этом случае указание языка необходимо, так как различные языки высокого уровня используют разные способы передачи параметров.
* Тип может принимать значения NEAR и FAR, и если он указан, все команды RET в теле процедуры будут заменены соответственно на RETN и RETF. По умолчанию подразумевается, что процедура имеет тип NEAR в моделях памяти TINY, SMALL и COMPACT.
* USES - список регистров, значения которых изменяет процедура. Ассемблер помещает в начало процедуры набор команд PUSH, а перед командой RET - набор команд POP, так что значения перечисленных регистров будут восстановлены.
Раздел 2
Практическая часть
Общая схема разработки программы на ассемблере
Общая схема разработки программы на ассемблере включает четыре этапа:
> ввод исходного текста (кода) программы;
> создание объектного модуля (компиляция программы);
> создание загрузочного модуля (компоновка программы);
> отладка программы.
Для ввода кода программы может использоваться любой текстовый редактор. Основным требованием к нему является ввод текста без спецсимволов редактирования. Файл кода должен обязательно иметь расширение asm.
Программы (компиляторы, компоновщики, отладчики), реализующие остальные этапы разработки, как правило, входят в состав программных пакетов ассемблера. Чаще всего используются программные пакеты TASM, MASM и WASM соответственно компаний Borland, Microsoft и Watcom. Например, в пакете TASM компиляция программы осуществляется при помощи программы tasm.exe. Смысл компиляции заключается в получении объектного модуля, который включает в себя представление исходной программы в машинных кодах и некоторую другую информацию, необходимую для отладки и компоновки программы. Формат командной строки для запуска tasm.exe следующий:
tasm [опции] имя исходного файла[, имя объектного файла][, имя файла листинга][, имя_файла_перекрестных_ссылок]
Так как обязательным аргументом командной строки является только имя исходного файла, то для компиляции, например, программного файла prog.asm достаточно выполнить в командной строке
tasm prog.asm
После имени исходного файла через запятую могут следовать необязательные аргументы, обозначающие имена объектного файла, файла листинга и файла перекрестных ссылок. Если их задать, то будут созданы соответствующие файлы с расширениями obj, lst и xrf. Если имена этих файлов должны совпадать с именем исходного файла, то необходимо просто оставить запятые:
tasm prog.asm,,,
Необязательный аргумент опции позволяет задавать режим работы компилятора tasm. Например, опция /zi включает в объектный файл информацию для отладки, а опция /x - запрещает создание файла карты (с расширением map).
В результате компиляции вашей программы на экране появляется последовательность строк. Если программа содержит ошибки, то компилятор выдаст на экран строки сообщений, начинающиеся словами "Error" и "Warning". Имеющиеся ошибки лучше всего анализировать, используя файл листинга вашей программы (с расширением lst).
После устранения ошибок в исходном коде и получения объектного модуля, осуществляется компоновка (линковка) программы - генерация исполняемого модуля. Компоновка подразумевает объединение нескольких отдельно откомпилированных объектных модулей. При этом в функции компоновщика входит разрешение внешних ссылок (ссылок на процедуры и переменные) в этих модулях.
Формат командной строки для запуска компоновщика следующий:
tlink [опции] список объектных файлов[, имя загрузочного модуля][, имя файла карты][, имя файла библиотеки]
Обязательным аргументом командной строки является только список компонуемых файлов с расширениями obj. Файлы должны быть разделены пробелами или знаком "+".
Необязательный параметр опции служит для управления работой компоновщика.
Например, для компоновки модуля prog.obj в COM-файл prog.com необходимо выполнить в командной строке
tlink /t prog.obj
а для получения EXE-файла - tlink prog.obj
COM и EXE - основные два формата исполняемых файлов в DOS. Файлы типа COM содержат только скомпилированный код без какой-либо дополнительной информации о программе. Весь код, данные и стек COM-программы в отличие от EXE-программы располагаются в одном сегменте и не могут превышать 64Кб. Кроме того, файлы типа EXE содержат заголовок, где описывается размер файла, требуемый объем памяти, список команд в программе, использующих абсолютные адреса, которые зависят от расположения программы в памяти, и т.д.
Отладка программы осуществляется с целью поиска логических ошибок и для исследования существующих программ. В составе пакета TASM поставляется отладчик Turbo Debugger - td.exe, представляющий собой оконную среду для отладки программ на уровне исходного текста. Turbo Debugger позволяет выполнять трассировку программы в прямом и обратном направлении, а также просмотр и изменение состояния аппаратных ресурсов микропроцессора во время покомандного выполнения программы.
Лабораторная работа №1
Название: Сегментная адресация и сегментная структура программ.
Цель работы: Исследование расположения сегментов программы в памяти.
Задание: Создать и выполнить программу, выводящую на экран текстовую строку. Программа должна состоять:
> Из сегмента команд
> Из сегмента команд и данных
> Из сегмента команд, данных и стека
В каждом случае определить размер и положение программы в памяти. Получить листинги трансляции.
Пример выполнения работы:
Программа из одного сегмента - сегмента команд:
Объявляем начало сегмента команд:
textsegment 'code'
В данном случае сегмент данных помещен внутрь сегмента команд, так отсутствует объявление его отдельным сегментом.
Сегментные регистры CS и DS будут указывать на один и тот же сегмент - text:
assumecs:text, DS:text
Загружаем адрес сегмента команд в сегментный регистр DS через аккумулятор AX, так как операция передачи адреса напрямую в DS невозможна.
begin:movAX,text
movDS,AX
Загружаем в старший разряд регистра аккумулятора номер функции для вывода строки на экран из ряда служебных программ MS DOS.
movAH,09h
Помещаем в регистр данных адрес выводимого сообщения.
movDX,offset message
Вызов прерывания DOS. После вызова прерывания операционная система проверяет содержимое старшего разряда аккумулятора. Так как в нашем случае там находится номер функции вывода на экран, операционная система проверит содержимое регистра данных и выполнит вывод на экран текста, находящегося в памяти по указанному в регистре адресу.
int21h
Загружаем в старший разряд аккумулятора номер функции для завершения программы, а в младший разряд - код успешного завершения программы.
movAH,4Ch
movAL,00h
Вызов прерывания DOS, которое завершит программу.
int21h
Объявление данных, то есть выводимой строки. 0Dh - команда возврата курсора в начало строки, 0Ah - команда переноса курсора на следующую строку, символ $ означает конец строки.
messagedb"string", 0Dh, 0Ah,'$'
Конец сегмента команд.
textends
Директива END завершает программу, одновременно указывая, с какой метки должно начинаться ее выполнение.
endbegin
Для следующих примеров комментироваться будут только еще не встречавшиеся части.
Программа из сегмента кода и сегмента данных
textsegment 'code'
assumecs:text, DS:data
begin:movAX,text
movDS,AX
movAH,09h
movDX,offset message
int21h
movAH,4Ch
movAL,00h
int21h
textends
Объявление сегмента данных, где теперь располагаются данные, то есть выводимый на экран текст.
datasegment
messagedb"string", 0Dh, 0Ah,'$'
Конец сегмента данных.
dataends
endbegin
Приведенная программа отличается от примера из одного сегмента - сегмента кода лишь несколькими деталями, хотя её структура отличается радикально. Вслед за сегментом команд введен отдельный сегмент данных с произвольным именем (в примере - data). Скомпоновав и выполнив эту программу можно заметить, что результат работы этой программы тот же, что и для односегментной программы. Введение отдельного сегмента данных повысило наглядность программы и дало возможность увеличить общий размер программы до 128 Кб.
Программа из сегмента кода, данных и стека
textsegment 'code'
assumecs:text, DS:data
begin:movAX,text
movDS,AX
Команды push и pop описаны в пункте 1.4.
pushDS
popES
movAH,09h
movDX,offset message
int21h
movAH,4Ch
movAL,00h
int21h
textends
datasegment
messagedb"string",0Dh, 0Ah, '$'
dataends
Начало сегмента стека.
stksegmentstack
Устанавливаем размер стека. В данном случае это 128 слов памяти, т.е. 256 байт.
dw128 dup (0)
Конец сегмента стека.
stkends
endbegin
Так же, как и другие сегменты, сегмент стека можно назвать как угодно. Строка описания сегмента стека должна содержать так называемый тип объединения - описатель stack. Тип объединения указывает компоновщику, каким образом должны объединятся одноименные сегменты разных программных модулей, и используется главным образом в тех случаях, когда отдельные части программы располагаются в разных исходных файла и объединяются на этапе компоновки. Хотя для одномодульных программ тип объединения обычно не имеет значения, для сегмента стека обязательно указание типа stack, поскольку в этом случае при загрузке программы выполняется автоматическая инициализация регистров SS и SP.
Лабораторная работа №2
Название: Программа с несколькими сегментами команд.
Цель работы: Исследование программ с несколькими сегментами команд.
Задание: Создать программу, в которой присутствует несколько сегментов команд. В каждый сегмент кода добавить процедуру. Произвести вызов процедур, находящихся в разных сегментах. Получить листинги трансляции.
Пример выполнения работы:
.modelmedium
.stack100h
;--------------------------------------------------------------------
Начало сегмента команд, содержащего процедуры.
.codeLibrary
;--------------------------------------------------------------------
Начало процедуры ввода строки.
InputStrprocfar
Вывод приглашения ко вводу строки.
movdx,offset msgSt
movah,09h
int21h
В регистр dx загружается смещение, адресующее выделенный под строку участок памяти.
movdx,offset bufn
В старший разряд аккумулятора загружаем номер функции ввода строки.
movah,0ah
int21h
Команда возврата из процедуры.
ret
Конец процедуры ввода строки.
InputStrendp
;--------------------------------------------------------------------
Начало процедуры вывода строки.
OutputStrprocfar
Вывод введенной ранее строки.
movdx,offset strn
movah,09h
int21h
Команда возврата из процедуры
ret
Конец процедуры вывода строки.
OutputStrendp
;--------------------------------------------------------------------
Начало процедуры, вызываемой при завершении программы.
OnExitprocfar
Вывод сообщения "Нажмите любую клавишу"
movdx,offset msgEx
movah,09h
int21h
Загрузка в ah номера функции ожидания нажатия клавиши.
movah,01h
int21h
Команда возврата из процедуры.
ret
Конец процедуры, вызываемой при завершении программы.
OnExitendp
;--------------------------------------------------------------------
Начало сегмента данных.
.data
Выделение памяти для ввода строки.
bufndb21
lenndb?
strndb21 dup('$'),'$'
Инициализация используемых в программе строк.
msgStdb"Enter your name please:",0dh,0ah,'$'
msgExdb0ah,"Press any key... ",'$'
;--------------------------------------------------------------------
Начало второго сегмента команд.
.code
main:
movax,data
movds,ax
Вызов процедуры InputStr из др. сегмента кода
callfar ptr InputStr
Вызов процедуры OutputStr из др. сегмента кода
callfar ptr OutputStr
Вызов процедуры OnExit из др. сегмента кода
callfar ptr OnExit
Возврат управления операционной система
movax,4c00h
int21h
endmain
Список литературы
1. П.И. Рудаков, К.Г. Финогенов. Программирование на языке ассемблера IBM PC. - Обнинск: Издательство "Принтер", 1999.
2. Зубков С. В. Assembler для DOS, Windows и UNIX. - М.: ДМК Пресс, 1999.
3. Абель П. Язык Ассемблера для IBM PC и программирование M.: Высшая школа, 1992.
2
Документ
Категория
Рефераты
Просмотров
71
Размер файла
134 Кб
Теги
указания, метод, эвм, орг
1/--страниц
Пожаловаться на содержимое документа