Главная страница
Навигация по странице:

  • Практическая работа №2. Изучение принципов работы компьютеров в машинных кодах. Цель работы

  • Двоичный код – основа функционирования компьютера

  • Ассемблер: символьная запись команд

  • Ассемблер: идентификаторы и директивы

  • Debug не позволяет использовать идентификаторы

  • Методические указания для практических занятий по дисциплине мдк. 02. 01


    Скачать 7.37 Mb.
    НазваниеМетодические указания для практических занятий по дисциплине мдк. 02. 01
    Дата09.09.2022
    Размер7.37 Mb.
    Формат файлаpdf
    Имя файлаMetod_Mikroprocessornye-sistemy_PZ_09.02.01_2020.pdf
    ТипМетодические указания
    #669073
    страница2 из 43
    1   2   3   4   5   6   7   8   9   ...   43
    Практическая часть
    Задание 1. Построить временные диаграммы процесса формирования системных сигналов
    “ INT”, ”RESET”, “STEP”.
    Задание 2. Обратиться к ячейке ЗУ с адресом 0000 h. В этой ячейке расположен код операции первой команды системного монитора. Обращаясь последовательно к ячейкам ЗУ, записать текст программы начальной установки УМК до адреса 0052h в машинных кодах.
    Выполнить дизассемблирование кодов и проанализировать полученную программу начального запуска МП. При записи программы необходимо учитывать, что не запрограммированные ячейки
    РПЗУ содержат код FFh.
    Задание 3. С помощью процедуры "П" обратиться к адресу 035Bh. Это начальный адрес подпрограммы “DELAY” системного монитора. Назначение данной подпрограммы – формирование интервала времени (10 ms).
    Выполнить дизассемблирование подпрограммы “ DELAY”, составить алгоритм подпрограммы и проанализировать принцип формирования интервала времени программным путем.
    Составить и запустить программу формирования произвольного интервала времени, кратного 10 ms, c использованием подпрограммы “ DELAY” и регистров DE в качестве счетчика циклов обращения к подпрограмме.
    Задание 4. Составить и запустить программу для определения нижней границы оперативной памяти УМК. Объяснить разницу между адресом, полученным в результате работы программы, и адресом в счетчике SP при начальной установке УМК (граница доступной памяти).
    Задание 5. Составить электрическую принципиальную схему подключения одного разряда светодиодного индикатора к БИС интерфейса и схему формирования управляющих сигналов БИС интерфейса.
    Задание 6. С помощью соединительных проводников создать модель канала

    11
    последовательной передачи данных в асинхронном режиме между двумя УМК. Все коммутации производить при отключенном питании УМК. Составить программу для обмена данными между двумя УМК в асинхронном режиме с заданной преподавателем скоростью передачи. Выполнить двухсторонний обмен информацией в асинхронном режиме.
    Задание 7. С помощью соединительных проводников создать модель канала последовательной передачи данных в синхронном режиме между двумя УМК. Все коммутации производить при отключенном питании УМК. Составить программу для обмена данными между двумя УМК в синхронном режиме с заданными преподавателем параметрами передачи (вид синхронизации, число синхрослов, вид синхрослов). Выполнить двухсторонний обмен информацией в синхронном режиме.
    Контрольные вопросы.
    1. Что составляет основу аппаратных и программных средств УМК?
    2. Какой объем имеет ПЗУ и ОЗУ?
    3. За счет чего производится расширение аппаратных возможностей?
    4. Как формируется сигнал RESET?
    Практическая работа №2. Изучение принципов работы компьютеров в машинных кодах.
    Цель работы: изучить принципы работы компьютеров в машинных кодах
    Теоретическая часть
    Двоичный код – основа функционирования компьютера
    Вся информация хранится и обрабатывается в компьютере в двоичной системе. Сама программа обработки также представляет собой не что иное, как двоичный код. В настоящее время, когда пользователь отделен от компьютерного «железа» несколькими слоями программного обеспечения, данный факт не очевиден: вы вводите в электронную таблицу десятичное число, и в соседней ячейке ответ выводится также в десятичном виде. Так что тезис о том, что внутри компьютера вычисления были произведены в двоичном коде, во многом приходится принимать на веру.
    Сейчас мы не будем пытаться доказать или продемонстрировать справедливость тезиса о двоичном способе хранения и обработки информации в компьютере. Будем ссылаться на данный тезис как на твердо установленный факт.
    Итак, компьютер способен непосредственно обрабатывать только двоичную информацию.
    Принять бинарную информацию он может из устройств внешней памяти, а также от других компьютеров через посредство сети. Хотя устройства внешней памяти весьма разнообразны, их объединяет именно то, что они хранят любые данные в двоичном виде, т.е. в виде, пригодном для наиболее быстрого и оперативного использования. Что же касается человека, то он, разумеется, нуждается в специальных устройствах, которые преобразуют его информацию во внутреннюю компьютерную форму и обратно. Для ввода бинарных машинных кодов человек легко может использовать клавиатуру. Важно понимать, что прием данных с клавиатуры (даже если предположить, что некий оригинал вводит чисто двоичный код!) всегда происходит по определенной программе, которая преобразует поток набираемых символов в двоичные числа и отправляет последние в необходимое место ОЗУ. Замена громоздких двоичных чисел более компактными восьмеричными или даже шестнадцатеричными числами дела не меняет, лишь несколько усложняя программу кодирования.
    Мы видим, что простейшим способом организовать ввод цифровых кодов в память является несложное преобразование последовательности символов, соответствующих допустимым значениям цифр, в двоичный код. Именно такая программа, называемая монитором, имелась в ПЗУ отечественных «ДВК-образных» машин (семейство ДВК, БК, УКНЦ). Монитор позволял вводить коды в виде восьмеричных цифр и записывать их в набранный таким же образом адрес ОЗУ. Еще он умел запустить машинную программу и перехватить ее завершение, а

    12
    также выполнял некоторые другие действия. Если внимательно подумать, то по своей сути такой монитор являлся непосредственным предшественником отладчиков типа Debug. Главной особенностью последнего по сравнению с монитором является возможность символьного представления машинных инструкций. Таков первый шаг от машинных кодов к ассемблеру.
    Ассемблер: символьная запись команд
    Цифровой ввод, легко распознаваемый машиной, довольно неудобен для человека. В целом большинству людей проще запомнить некоторое слово (даже на неродном языке, например, ADD или LOOP) чем комбинации цифр, им соответствующие. Аналогичным образом часто отказываются от обращения ко внутренним регистрам микропроцессора по номерам, заменяя их буквенными обозначениями (EAX, AX, AH, AL, BX, IP и т.д.) Подобная замена особенно уместна, если регистры микропроцессора не являются универсальными и имеют выделенное назначение (например, A – аккумулятор). Заметим, что неуниверсальность рабочих регистров и их жестким образом фиксированное использование, что свойственно семейству процессоров Intel, вовсе не единственный возможный вариант. Скажем, в семействе PDP логическая структура процессоров была более стройной: все регистры общего назначения РОН могли использоваться в машинных инструкциях на равных основаниях; в такой ситуации давать регистрам имена было менее удобно, чем просто пронумеровать.
    Описанные символьные обозначения стали называться мнемониками (мнемонический значит облегчающий запоминание). Вот несколько мнемоник для записи машинных инструкций процессора Intel.
    Таблица 1
    hex-код
    мнемоника
    комментарий
    B81200
    MOV AX,12 занести число 12 в регистр AX
    01D8
    ADD AX,BX сложить регистры AX и BX
    8B1E1001 MOV BX,[110] прочитать в BX ячейку ОЗУ с адресом 110
    Примечание. В таблице жирным шрифтом выделен код, описывающий операцию и способы обращения к данным; обычным шрифтом набраны непосредственные данные и адреса ячеек ОЗУ. Обратите внимание, что использованные в командах двухбайтовые числа хранятся
    «задом наперед»: число 0110 лежит в памяти не как 01 10, а, наоборот, 10 01. Подобный способ хранения, принятый в IBM PC, носит название обратный порядок хранения байтов.
    Думается, читатели согласятся, что мнемонический способ записи команд легче понимается и запоминается. Именно поэтому при работе с Debug обычно пользуются именно им.
    Мнемоническое представление команд является неотъемлемой частью ассемблера, но отнюдь не главной его частью. Наибольшее достоинство языка ассемблер состоит в возможности заменять символическими именами не только операции и регистры, но и конкретные адреса памяти. В последнем случае программист получает возможность освободиться от «привязки» к конкретным адресам памяти, что, в свою очередь, позволяет элементарно, как в обычном текстовом редакторе, удалять или дополнять команды программы. Такая замечательная возможность заслуживает более подробного обсуждения.
    Ассемблер: идентификаторы и директивы
    Имеется как минимум две ситуации, когда программа однозначно привязывается к конкретным адресам памяти. Во-первых, при обращении к некоторым переменным (данным), которые находятся не во внутренних регистрах микропроцессора, но хранятся в памяти. И, во- вторых, при переходах, без которых невозможно организовать разветвляющиеся и циклические программы. Хотя обе ситуации по смыслу отличаются (происходит обращение к данным или программе), с формальной точке зрения оба этих случая выглядят необычайно похоже: требуется сослаться на адрес некоторой ячейки памяти – неважно, что именно там находится.
    Появление в программах конкретных адресов приводит к потере ее мобильности.
    Например, если по какой-либо причине потребуется изменить адрес переменной, то придется внести коррекцию во все команды, где на эту переменную содержится ссылка. Или при вставке всего одной машинной инструкции вся последующая часть программы сдвигается и приходится аналогичным образом модифицировать все переходы на ее адреса.

    13
    Чтобы читатели получили некоторое представление об описанных трудностях, реализуем в
    Debug простейшую программу.
    Пусть мы хотим решить на компьютере простейшую задачу, которая состоит вычислении по формуле r = x + y. Напишем и реализуем программу решения, а затем посмотрим, что потребуется исправлять, если мы захотим добавить к нашей формуле еще одну операцию, например: r = x + y – z.
    Договоримся, что все переменные являются двухбайтовыми целыми. Примем, что область хранения переменных будет находиться «в самом начале» – начиная с адреса 102. Поскольку по принятым в MS-DOS соглашениям программа стартует, начиная с адреса 100, придется предусмотреть «обход» области данных.
    Таблица 2
    адреса содержимое комментарии
    100,101 jmp 108 на начало программы (обход данных)
    102,103 3 x
    104,105 7 y
    106,107 0 r
    Примечание. Размещением данных указанным способом имеет свои достоинства и недостатки. С одной стороны, требуется обход области данных, возникают трудности при дизассемблировании (см. ниже), зато с другой – данные сохраняются на диск вместе с программой единым массивом и адреса информации в момент написания программы уже определены. При работе с Debug последнее немаловажно.
    Итак, память для данных спланирована и можно, постоянно заглядывая в табл. 2, набрать программу (см. следующий ниже протокол; директива dw в нем означает двухбайтовое число).
    Добавим, что в протоколе жирным шрифтом показаны символы, которые нам пришлось набирать; все остальные выведены на экран отладчиком. Причем текст, выделенный при редактировании курсивом, может отличаться от того, который получился на компьютере автора, а многоточие заменяет выводимые на экран строки, содержимое которых для нашей задачи абсолютно несущественно.
    -a
    13E4:0100 jmp 108
    13E4:0102 dw 3
    13E4:0104 dw 7
    13E4:0106 dw 0
    13E4:0108 mov ax,[102]
    13E4:010B add ax,[104]
    13E4:010F mov [106],ax
    13E4:0112 int 20
    13E4:0114
    -u
    13E4:0100 EB06 JMP 0108
    13E4:0102 0300 ADD AX,[BX+SI]
    13E4:0104 07 POP ES
    13E4:0105 0000 ADD [BX+SI],AL
    13E4:0107 00A10201 ADD [BX+DI+0102],AH
    13E4:010B 03060401 ADD AX,[0104]
    13E4:010F A30601 MOV [0106],AX
    13E4:0112 CD20 INT 20
    -u 108
    13E4:0108 A10201 MOV AX,[0102]
    13E4:010B 03060401 ADD AX,[0104]

    14
    13E4:010F A30601 MOV [0106],AX
    13E4:0112 CD20 INT 20
    -g
    Программа завершилась нормально
    -d 102
    13E4:0100 03 00 07 00 0A 00-A1 02 01 03 06 04 01 A3 ..............
    13E4:0110 06 01 CD 20 00 00 00 00-00 00 00 00 34 00 D3 13 ... ........4...
    13E4:0180 00 00
    Теперь проконтролируем набор директивой u. Из протокола видно, что наличие данных посреди программы «сбивает» дизассемблер отладчика: пытаясь интерпретировать значения переменных как машинные команды, Debug «не попадает» на адрес 108. В результате первая команда программы выглядит неверно. Проверка директивой u 108 подтверждает, что в памяти все сохранено правильно.
    Примечание. Из последней распечатки запомним тот факт, что программа начинается с адреса 108 и завершается байтом 113. Эти сведения нам потребуются позднее при переделке программы.
    Остается запустить нашу программу и посмотреть ответ, для чего вывести содержимое памяти командой d 102. При расшифровке шестнадцатеричных чисел 3, 7, A (10 10
    ) следует обязательно вспомнить о примечании к таблице 1 по поводу обратного хранения байтов в памяти.
    Для удобства анализа протокола результирующие байты переменной r в протоколе подчеркнуты.
    Переходим теперь к наиболее интересной части нашего эксперимента. Что придется поменять, чтобы переделать нашу программу для расчета по исправленной формуле r = x + y – z.
    Увы, придется проделать довольно много операций, хотя каждая из них сама по себе несложная.
    Начнем с расширения таблицы переменных. Новое распределение памяти приведено в табл. 3 (советуем читателям внимательно сравнить ее с предыдущей таблицей; все изменения в табл. 3 выделены цветом и подчеркнуты).
    Таблица 3
    адреса содержимое комментарии
    100,101 jmp 10A на начало программы (обход данных)
    102,103 3 x
    104,105 7 y
    106,107 4 z
    108,109 0 r
    Теперь будем вносить необходимые изменения. Все требуемые действия зафиксированы в приведенном ниже протоколе, который является продолжением предыдущего.
    -m 108 113 10a
    -u 10a
    13E4:010A A10201 MOV AX,[0102]
    13E4:010D 03060401 ADD AX,[0104]
    13E4:0111 A30601 MOV [0106],AX
    13E4:0114 CD20 INT 20
    -a 111
    13E4:0111 sub ax,[106]
    13E4:0115 mov [108],ax
    13E4:0118 int 20
    13E4:011A
    -a 100

    15
    13E4:0100 jmp 10a
    13E4:0102
    -e 106 4 0
    -u 100
    13E4:0100 EB08 JMP 010A
    13E4:0102 0300 ADD AX,[BX+SI]
    13E4:0104 07 POP ES
    13E4:0105 0004 ADD [SI],AL
    13E4:0107 00A102A1 ADD [BX+DI+A102],AH
    13E4:010B 0201 ADD AL,[BX+DI]
    13E4:010D 03060401 ADD AX,[0104]
    13E4:0111 2B060601 SUB AX,[0106]
    13E4:0115 A30801 MOV [0108],AX
    13E4:0118 CD20 INT 20
    -g
    Программа завершилась нормально
    -d 102
    13E4:0100 03 00 07 00 04 00-06 00 A1 02 01 03 06 04 ..............
    13E4:0110 01 2B 06 06 01 A3 08 01-CD 20 00 00 34 00 D3 13 .+....... ..4...
    13E4:0180 00 00 ..
    Передвинем основную часть программы, чтобы освободить 2 байта под новую переменную. Для этого наберем команду m 108 113 10a, которая означает задание отладчику подвинуть (move) байты со 108 по 113 (эти значения мы запомнили из предыдущих экспериментов с программой). Проверим, что программа действительно теперь находится с адреса 10a. Далее можно было бы аналогичным образом освободить байты под команду вычитания и ввести ее, но проще набрать 3 последние команды заново, тем более, что в команде записи результата в переменную r все равно потребовалось бы изменить адрес. Так что введем эти команды с адреса 111, а затем не забудем поменять адрес в стартовой инструкции перехода.
    Далее командой e 106 4 0 занесем в переменную z ее числовое значение (опять-таки в обратном порядке!) и все еще раз проверим. Наконец, запустим программу и убедимся в правильности получившегося результата: 3 + 7 – 4 = 6.
    Таким образом, поработав с простейшей программой, мы убедились в том, что замена адресов и переменных, и переходов при модификации программы представляет собой весьма трудоемкую работу, требующую предельного напряжения внимания (но, несмотря на все усилия, ошибки неизбежно случаются). От указанных трудностей можно избавиться, если для реализации программы в командах процессора использовать ассемблер. Главное преимущество ассемблера перед программой Debug заключается в том, что ассемблер нигде не использует конкретные адреса ОЗУ – вместо них везде указываются символические имена, которые называются идентификаторы. При трансляции текста программы ассемблер автоматически связывает идентификаторы с адресами ячеек памяти, в которых они будут располагаться. Как следствие, модификация текста программы не потребует никакого пересчета адресов, поскольку ассемблер при новой трансляции распределит их уже в соответствии с модифицированной программой.
    Текст нашей программы на ассемблере будет выглядеть так. jmp start x: dw 3 y: dw 7
    z: dw 4 r: dw 0 start: mov ax,x add ax,y

    16
    sub ax,z mov r,ax int 20
    Легко видеть, что вставка двух выделенных строк это все, что потребуется при рассмотренной выше модификации программы. К сожалению, Debug не позволяет
    использовать идентификаторы, а значит, заметно уступает ассемблеру в данном вопросе.
    Впрочем, никто и не обещал, что данное программное средство является полноценным ассемблером.
    Язык ассемблер содержит целый ряд специальных управляющих операторов (обычно их называют директивами), из которых Debug поддерживает только некоторые. В частности, команда dw 3, определяющая в памяти некоторую константу, суть одна из таких поддерживаемых отладчиком директив. В то же время, ассемблер содержит целый ряд директив, которые отсутствуют в Debug [2]. Между прочим, в свете наличия дополнительных директив, некоторые из которых в ассемблерной программе приходится писать обязательно, программа для Debug вводится проще. Зато ассемблер засчет добавочных директив становится мощнее; например, отдельные участки ассемблерной программы можно помещать внутрь условий, так что в зависимости от их выполнения или невыполнения будет генерироваться различный код.
    Таким образом, оказывается, что Debug не является в полном смысле слова ассемблирующей программой, хотя и позволяет вводить ассемблерные мнемоники команд.
    Следовательно, работая в Debug, мы не реализуем всех возможностей, которыми обладает настоящий язык ассемблер.
    Отметим, что хорошее понятие об ассемблере дают школьные учебники [3-6], где описываются учебные ЭВМ «Малютка» и «Нейман» (в книгах [4,6] изложение проведено более подробно). Особенно полезна практическая работа с программными реализациями указанных моделей, в которых имеется поддержка ассемблера.
    В качестве еще одного эксперимента предлагаем сконструировать свой собственный ассемблер. Главное достоинство идеи заключается, конечно, не в практической полезности полученного продукта, а в том, что в процессе написания программы мы лучше поймем принципы ассемблирования программ.
    Таблица 4
    1   2   3   4   5   6   7   8   9   ...   43


    написать администратору сайта