Автор: Пользователь скрыл имя, 25 Января 2012 в 10:10, курсовая работа
В курсовой работе в соответствии с заданием на проектирование решается задача на языке ассемблера для CPU i8086, в которой требуется вычислить значение логической формулы F=(X7&X6&X1) V (X6&X4&X2X1&X0 ) V (X7&X6&X3&X1) логическими переменными которой являются значения массива из 8 байт, и размещающей результат в оперативной памяти.
Описание пошаговой реализации алгоритма решения задачи в виде последовательности арифметических, логических и других действий, которые необходимо проделать для реализации принятого метода решения. Реализация задачи предполагает создание исходного, объектного и загрузочного модулей, а также подробное описание каждого действия по написанию программы.
Введение 4
1 Постановка задачи 6
2 Анализ задачи 8
2.1 Определение входной и выходной информации 8
2.2 Выбор модели памяти 8
2.3 Выбор режимов адресации 9
2.4 Разработка блок-схемы программы 12
3 Реализация 13
3.1 Описание этапов создания программы 13
3.1.1 Описание исходного модуля 16
3.1.2 Трансляция программы 18
3.2 Характеристика полученного файла листинга 20
3.3 Характеристика полученного загрузочного модуля 22
3.4 Анализ команд программы 22
3.5 Анализ команд jmp, jl, jg и loop 24
3.6 Анализ дампа памяти (сегменты данных, кода и стека) 27
4 Тестирование и отладка программы 29
4.1 Отладка программы 29
4.2 Тестирование программы 29
Заключение 33
Литература 34
Приложение А 35
Приложение Б 36
Приложение В 38
Приложение Г 39
В результате компиляции программы были созданы 4 файла: var11.exe, var11.lst, var11.map и var11.obj. Содержимое файла листинга var11.lst будет представлено в приложении Б.
В верхней части каждой страницы листинга выводится заголовок, содержащий версию используемого ассемблера, с помощью которой выполнено ассемблирование файла, дату и время ассемблирования и номер страницы в листинге.
Файл листинга содержит две части: аннотированный листинг исходного кода и таблицу идентификаторов. Сначала выводится исходный ассемблируемый код с заголовком, содержащим имя файла, в котором находится исходный код. Вывод исходного кода сопровождается информацией о машинном коде, который ассемблирует ассемблер. Все ошибки или предупреждения, обнаруженные в процессе ассемблирования, включаются в листинг непосредственно за содержащей ошибку строкой.
Строки кода в файле листинга имеет следующий формат:
<глубина><номер_строки><
Поле <номер_строки> содержит номер строки в файле листинга (не включая заголовки). Номера строк особенно полезны при использовании перекрестных ссылок ассемблера. Поле <номер_строки> не соответствует номерам строк исходного модуля. Например, если в файл включается другой файл или выполняется макрорасширение, то значение поля <номер_строки> продолжает увеличиваться, хотя текущая строка в исходном файле остается той же.
Поле <смещение> представляет смещение в текущем сегменте начала машинного кода, сгенерированного из соответствующей исходной строки ассемблером.
Поле <машинный_код> показывает фактическую последовательность шестнадцатеричных значений размером в байт или слово, которые ассемблированы из соответствующей исходной строки на ассемблере.
Поле <исходный_код> – это просто исходная строка ассемблера, с комментариями и всем, что в ней содержится. Некоторые исходные строки (например, те, которые содержат только комментарии) не генерируют никакого машинного кода. Эти строки не содержат полей <смещение> и <машинный_код>, но имеют номер строки.
Рассматривая листинг, можно отметить ряд полезных моментов общего характера. Каждому транслируемому предложению программы соответствует определенное смещение, причем задание смещений выполняется в каждом сегменте в отдельности. Первая команда mov ax,@data имеет смещение от начала сегмента команд, равное нулю. Она занимает 3 байта, поэтому следующая команда начинается с байта 3 и имеет соответствующее смещение. Транслятор не смог полностью определить код команды mov ax,@data. В этой команде в регистр ax засылается сегментный адрес сегмента data. Однако этот адрес станет известен лишь в процессе загрузки выполнимого файла программы в память. Поэтому в листинге на месте этого адреса стоят нули, напоминающие о том, что здесь должен быть пока неизвестный сегментный адрес.
Согласно цели курсового проекта было разработано 16-разрядное приложение для CPU i8086 и операционной системы MS DOS. Операционная система MS DOS воспринимает в качестве исполняемых программ файлы двух типов: *.exe и *.com.
Разработанная программа var11.exe является односегментной – команды, данные и стек располагаются в единственном сегменте и не превышают 64Кб.
Команда AND осуществляет логическое (побитовое) умножение первого операнда на второй. Исходное значение первого операнда (приемника) теряется, замещаясь результатом умножения. В качестве первого операнда можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами.
Пример:
mov AX, 0FFEh
and AX, 5555h ;AX=0554h
Команда OR выполняет операцию логического (побитового) сложения двух операндов. Результат замещает первый операнд (приемник); второй операнд (источник) не изменяется.
В качестве первого операнда можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами.
Пример:
mov AX, 0FA01h
mov BX, 1C15h
or AX, BX ;AX=FE15h, BX=1C15h
Команда MOV замещает первый операнд (приемник) вторым (источником). При этом исходное значение первого операнда теряется. В зависимости от описания операндов пересылается слово или байт. Если операнды описаны по-разному или режим адресации не позволяет однозначно определить размер операнда, для уточнения размера передаваемых данных в команду следует включить один из атрибутных операторов byte ptr или word ptr. В зависимости от использованных режимов адресации команда MOV может осуществлять пересылки следующих видов:
Запрещены пересылки из ячейки памяти в ячейку памяти (для этого предусмотрена команда MOVS), а также загрузка сегментного регистра непосредственным значением, которое, таким образом, приходится загружать через регистр общего назначения. Нельзя также непосредственно переслать содержимое одного сегментного регистра в другой. Такого рода операции удобно выполнять с использованием стека. Некоторые примеры команды MOV:
mov DI, AX ;Из регистра в регистр
mov AL, memb ;Из памяти в регистр (число 5)
mov memb, CL ;Из регистра в память (на место числа 6)
mov DX, word ptr memb ;Слово из памяти в регистр (число 0605)
Безусловный переход в программе на ассемблере производится по команде JMP. Полный формат команды следующий: JMP [модификатор] [адрес_перехода].
Адрес перехода может быть либо меткой, либо адресом области памяти, в которую предварительно помещен указатель перехода. В системе команд микропроцессора существуют несколько кодов машинных команд безусловного перехода. Их различия определяются дальностью перехода и способом задания целевого адреса. Дальность перехода определяется местоположением операнда [адрес_перехода]. Этот адрес может находиться в текущем сегменте кода или в некотором другом сегменте. В первом случае переход называется внутрисегментным или близким, а во втором случае – межсегментным или дальним.
Команда JMP имеет пять разновидностей:
Команда CMP выполняет вычитание второго операнда из первого. В соответствии с результатом вычитания устанавливаются состояния флагов CF, PF, AF, ZF, SF и OF. Сами операнды не изменяются. Обычно вслед за командой CMP стоит одна из команд условных переходов, анализирующих состояние флагов процессора (jl или jg).
При выполнении перехода по условию выполняется два шага: сначала выполняется арифметическая команда или команда сравнения для установки одного или более флагов, затем команда условного перехода заставляет процессор перейти к выполнению нового адреса. Эти команды делятся на две группы:
Команда перехода по условию передает управление по указанному адресу, когда признак условия установлен, в противном случае перехода не происходит, и процессор продолжает работу со следующей команды.
Синтаксис команды следующий: Jcc <метка>, где сс определяет признак условия, идентифицируя состояние одного или нескольких флагов. Команды условных переходов представлены в таблице 2.
Таблица 2 – Условные переходы после команд сравнения
Типы операндов | Мнемокод команды условного перехода | Критерий условного перехода | Значения флагов для осуществления перехода |
Любые | je | операнд_1 = операнд_2 | zf = 1 |
Любые | jne | операнд_1<>операнд_2 | zf = 0 |
Со знаком | jl/jnge | операнд_1 < операнд_2 | sf <> of |
Со знаком | jle/jng | операнд_1 <= операнд_2 | sf <> of or zf = 1 |
Со знаком | jg/jnle | операнд_1 > операнд_2 | sf = of and zf = 0 |
Со знаком | jge/jnl | операнд_1 => операнд_2 | sf = of |
Без знака | jb/jnae | операнд_1 < операнд_2 | cf = 1 |
Без знака | jbe/jna | операнд_1 <= операнд_2 | cf = 1 or zf=1 |
Без знака | ja/jnbe | операнд_1 > операнд_2 | cf = 0 and zf = 0 |
Без знака | jae/jnb | операнд_1 => операнд_2 | cf = 0 |
Команды условного перехода используют 8-разрядные непосредственные операнды, которые добавляются к текущему значению указателя команд IP для определения точного адреса перехода. Переход может осуществляться как вперед, так и назад в диапазоне -128 …+127 байтов.