Поиск

Полнотекстовый поиск:
Где искать:
везде
только в названии
только в тексте
Выводить:
описание
слова в тексте
только заголовок

Рекомендуем ознакомиться

'Документ'
прайс-лист Производства ЛСТК ) Дизайнерское оформление основных разделов (часто посещаемых страниц, таких как страницы О компании, главная Проектирова...полностью>>
'Документ'
В 1973 г. Б.Картер сформулировал тезис, получивший известность как «антропный космологический принцип» (АКП)1. Учитывая быстроту, с которой АКП распро...полностью>>
'Конкурс'
С 13 по 15 февраля 2015 года в Екатеринбурге состоится III Международный Форум детского и юношеского художественного творчества «ЕВРОПА-АЗИЯ». Основны...полностью>>
'Решение'
Согласие пациента на медицинское вмешательство означает лишь реализацию его права обладать информацией для принятия решения о вмешательстве. И вовсе н...полностью>>

Главная > Документ

Сохрани ссылку в одной из сетей:
Информация о документе
Дата добавления:
Размер:
Доступные форматы для скачивания:

Замечание

Здесь и далее, если не указано иное, под словом ассемблер подразумевается ассемблер для AVR – архитектуры, используемой в контроллерах ATMEL.

0. Вводные замечания

Язык программирования "ассемблер" это запись непосредственно инструкций для процессора.

В принципе, инструкции процессора можно было бы записывать прямо в шестнадцатеричных кодах, например $2001 – это инструкция, совершающая логическую операцию AND, причем в коде этой инструкции уже зашифровано, что операция должна быть осуществлена над первыми двумя регистрами (внутренними ячейками памяти) – а результат будет помещен в первую из этих двух ячеек.

По общепринятому мнению программировать прямо в кодах неудобно – не только из-за необходимости запоминать как шифруется каждая команда, но и из-за того, что приходится заниматься кучей нудных расчетов – считать на сколько шагов по программе должна перескочить инструкция перехода, например и т.п.

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

Очевидно, при таком подходе программист все равно будет точно уверен в том, сколько и каких инструкций он записал, но просто записывать их сможет в более удобном виде. Например, вышеупомянутая инструкция запишется так: and r0,r1, но на выходе ассемблера из нее получится все тот же код $2001. Впоследствии цепочку получившихся кодов мы можем записать в программную память процессора и он, после включения, радостно начнет их выполнять.

1. Начнем с примера

Переведем программу с Паскаля на ассемблер. Эта программа очень проста, она ничего не спрашивает у пользователя и ничего не сообщает ему. Если ее запустить, мы даже не заметим, что что-то произошло. Тем не менее она очень полезна для изучения.

текст на Паскале:

текст на ассемблере:

коды инструкций:

{это комментарий}

var

a,b,c:byte;

begin

a:=1;

b:=2;

c:=a+b;

end.

;это комментарий

ldi r16,1

ldi r17,2

add r16,r17

mov r18,r16

$E001

$E012

$0F01

$2F20

Что именно здесь записано – будет объяснено ниже. Сейчас же попробуем преобразовать нашу программу в коды процессора.

Чтобы скомпилировать программу в Паскале мы обычно запускаем интегрированную среду разработки, например, Турбо-Паскаля, открываем в нем файл с исходным текстом, нажимаем Compile в меню и восторгаемся результатам. Если мы не пользуемся интегрированной средой обработки, мы просто запускаем компилятор Паскаля, указав ему в качестве параметра файл с программой:

c:\tp70\tpc.exe prg1.pas

из командной строки. В результате, если повезет, получаются несколько файлов, среди них и prg1.exe – исполнимый модуль готовой программы.

С ассемблером дело обстоит примерно так же. Существуют, вообще говоря, и интегрированные среды разработки в которых можно "щелкнуть" где-нибудь Compile и все получится. Однако чтобы разобраться с этими средами хорошо бы знать собственно ассемблер. Поэтому пока обойдемся без них.

Воспользуемся компилятором avrasm32.exe, который я высылал. Для этого:

- наберем нашу программу в каком-нибудь простом текстовом редакторе;

- сохраним ее в текстовый файл с именем prg1.asm;

- скомпилируем ее компилятором введя указанную ниже команду.

c:\atmel\avrasm32.exe -fG prg1.asm

Как видим, кроме имени файла с исходным текстом нам пришлось указать ключ "-fG" – не следует беспокоиться по этому поводу, для компилятора Паскаля количество возможных ключей гораздо больше, чем для компилятора ассемблера, нам просто повезло, что не пришлось их задавать. Этот конкретный ключ сообщает, что выходной файл мы хотим получить в самом примитивном и простом для нашего понимания формате (generic). Заметим, что программатор-прошивальщик avreal.exe работает с файлами, записанными в формате "Intel", поэтому для создания таких файлов нужно будет указать ключ "-fI" вместо только что упомянутого.

Итак, компилятор скомпилировал нашу программу и, вероятно, сообщил, после слов о копирайтах и о том, какой он хороший, что-то вроде:

Creating 'prg1.hex'

Assembling 'prg1.asm'

Program memory usage:

Code : 4 words

Constants (dw/db): 0 words

Unused : 0 words

Total : 4 words

Assembly complete with no errors.

Здесь он пишет что создал файл prg1.hex, который является собственно выходным файлом и стал ассемблировать входной файл, записывая в выходной результаты. По окончании он сообщает, что всего скомпилировано 4 слова кода и компиляция завершена без ошибок.

Слово – это историческое название для ячейки памяти, не равной байту. Слово может содержать несколько байт 2 или, скажем, 4 (и даже нецелое число, например, у разных контроллеров PIC слова бывают по 12 и 14 бит) – но вполне возможно, что собственно на байты оно не разбивается, как байт, например (в Паскале), не разбивается на кусочки по 4 бита – вы можете работать только с байтом целиком.

Заметим, что во входном файле у нас было 4 инструкции и они соответственно преобразовались в 4 слова. Каждая в одно. Например в микроконтроллере ATtiny15 флеш-память для программ имеет объем всего 512 слов. Если вы чувствуете, что написали программу, состоящую более чем из 512 инструкций, вы можете быть уверены, что она не влезет.

Теперь рассмотрим выходной файл prg1.hex. Он тоже текстовый, так что его можно без боязни открыть, например, в "блокноте". Сделав это мы увидим:

000000:e001

000001:e012

000002:0f01

000003:2f20

Догадаться несложно. Слева записан номер ячейки памяти программ, куда должна быть записана инструкция (то есть, ее адрес), а дальше через двоеточие шестнадцатеричное число, представляющее собственно код инструкции.

Теперь перекомпилируйте программу так, чтобы получить hex-файл в формате Intel. В дальнейшем компилируйте только в этот формат.

2. Разберемся с программой

В третьем параграфе мы попытаемся запустить нашу программу в симуляторе, однако прежде чем делать это, необходимо осознать смысл записанных нами инструкций.

В первую обратим внимание, что программа на Паскале состоит из двух важных частей:

- раздел распределения памяти данных;

- описание инструкций кода.

Первая часть начисто отсутствует в нашей ассемблерной программе. Программист на Паскале не заботится о том, где его переменные будут размещены в памяти компьютера – он только придумывает для них имена и определяет ее тип. Все остальное отдается на решение компилятора и операционной системы. В ассемблере все более "деревянно". Программист заранее решает, в каких ячейках памяти он собирается хранить свои данные. В нашем случае мы решили, что для хранения переменных мы используем регистры процессора:

- А хранится в 16-м регистре;

- B хранится в 17-м регистре;

- C хранится в 18-м регистре.

Регистрами называются ячейки оперативной памяти встроенные прямо в вычислительное устройство, их обычно немного, зато работа с ними происходит быстрее всего. Даже если у микроконтроллера есть дополнительная оперативная память, обычно его процессор не может выполнять с ней всех действий, какие он может выполнять с регистрами. Поэтому для обработки данных, находящихся в оперативной памяти их сначала нужно загрузить в регистры, потом обработать и выгрузить обратно.

Вторая часть собственно и записана всеми 4-мя инструкциями программы. Как мы видим, запись инструкции состоит из имени ("мнемоники") данной инструкции и указания того, с чем эта инструкция должна работать – то есть "операндов". Некоторые инструкции требуют в качестве операндов названий регистров, некоторые – просто чисел, некоторые требуют и того и другого, а некоторые не используют операндов вообще. Я настоятельно рекомендую открыть файл справки по ассемблеру avrasm.chm и найти в нем описания трех использованных нами инструкций. Вкратце их смысл изложен ниже.

Первая инструкция LDI (сокращение от Load Immediate – загрузить непосредственное значение) загружает в указанный регистр указанное число – мы указали регистр №16 и число 1. Как видим, обычно в инструкциях, обрабатывающих два операнда результат записывается в первый из операндов – это выглядит немножко "задом наперед" но в целом к этому быстро привыкаешь. Заметим также что:

- регистр обозначается буквой R (большой или маленькой) с номером регистра;

- десятичные числа обозначаются просто цифровой записью, начинающейся с цифры от 1 до 9.

Кроме этого можно записывать числа в двоичной, восьмеричной и шестнадцатеричной системе счисления. В ассемблере это бывает полезно, поэтому в отличие от большинства языков он позволяет такое разнообразие:

- двоичные состоят из цифр 0 и 1, в начале числа пишется префикс "0b";

- восьмеричные состоят из цифр от 0 до 7, в начале числа пишется префикс "0" (просто 0);

- шестнадцатеричные состоят из цифр от 0 до 9 и букв от A до F (можно маленькими), в начале числа пишется префикс "0x" или ставится знак "$".

Таким образом, например, 25=0b11001=031=0x19=$19.

Вторая инструкция, как несложно догадаться, осуществляет подобную же загрузку, но с регистром №17 и числом 2.

Что делает третья инструкция, можно догадаться из ее названия. ADD – по-английски "добавлять". Эта инструкция имеет в качестве операндов названия двух регистров и добавляет к числу, находящемуся в первом, число, находящееся во втором. Результат, как обычно, записывается обратно в первый регистр (в принципе, это соответствует смыслу слова "добавить").

Четвертая инструкция MOV (от английского слова Мove – "задвинуть", в данном случае, – считается, что это не очень удачное название) также принимает два регистра в качестве операндов и "задвигает" в первый значение из второго. То есть она, как и LDI осуществляет загрузку в регистр, только значение берется не непосредственно "зашитое" в код инструкции, а то, которое находится в другом регистре. Как видим, в Паскале обе эти инструкции обозначаются знаком присваивания.

Обратим на то, как в ассемблере принято записывать комментарии. Комментарием считается все, что указано после знака "точка-с-запятой" и до конца строки.

Вообще инструкции могут выполнять еще и некоторые побочные действия, однако об этом мы пока говорить не будем, а перейдем к тестированию нашей программы в симуляторе.

3. Симулятор и отладка программы

Первым делом нам потребуется симулятор. Неплохой симулятор встроен в интегрированную среду разработки AVR Studio – ее можно скачать на сайте , или например (/Software/files/astudio3.exe) – ссылку я даю на старенькую третью версию, хотя существуют уже и четвертые разные. Это не очень принципиально, просто старая версия достаточна, а по размеру значительно меньше.

Установив и запустив этот продукт (в дальнейшем будем называть его симулятором) откроем в нем созданный нами файл с кодами инструкций для микроконтроллера (в формате Intel). Сделайте это пользуясь меню или еще как-нибудь, если вы не можете этого сделать, то прекратите сейчас же читать этот текст и вообще больше не включайте никогда компьютер. Объяснений типа "Щелкните левой кнопкой мыши по слову File в строке меню в верхней части окна, потом выберите Open и в открывшемся диалоге найдите нужный каталог и выберите нужный файл" я давать разумеется не буду. В крайнем случае я буду записывать через слеш путь по системе меню и подменю (например, File/Open).

Если вы открываете файл в первый раз, то симулятор выдаст запрос (диалоговое окно с заголовком Simulator Options) по поводу того, какую микросхему мы собрались "симулировать". Можно выбрать из списка Device нужную или даже придумать что-то свое. Я выбрал ATtiny15, при этом симулятор сразу прописал сколько кода, данных и так далее есть в этой микросхеме. (кстати, симулятор написал что у этой микросхемы 32 байта оперативной памяти еще есть, кроме регистров – по-моему это ошибка).

После нажатия кнопки OK cимулятор немного подумает, и откроет файл, однако уже не в текстовом виде. Симулятор расшифровал коды инструкций и записал эти инструкции снова в "человеческом" виде, то есть на ассемблере. Это называется "дизассемблированием". Однако для отладки нам нужно открыть еще одно полезное окно, показывающее текущее состояние регистров процессора, которое можно достать из меню View/Registers. В этом окне перечислены все 32 регистра и указано, какие значения в них сейчас находятся.

Разместите оба открытых окна как-нибудь рядышком, чтоб получить примерно такой вид:

+00000000: E001 LDI R16,0x01

+00000001: E012 LDI R17,0x02

+00000002: 0F01 ADD R16,R17

+00000003: 2F20 MOV R18,R16

R0 = 0x00 R16 = 0x00

R1 = 0x00 R17 = 0x00

........................

R15 = 0x00 R31 = 0x00

Теперь мы готовы наслаждаться видом выполняющейся программы. Обратите внимание, что в окне с инструкциями есть стрелка, показывающая, какая инструкция сейчас должна выполняться. Команда меню Debug/TraceInto (она привязана к клавише F11) позволяет выполнять программу по шагам. Сделайте это четыре раза и после выполнения каждой инструкции смотрите во втором окне, как изменяется содержимое регистров №№ 16, 17 и 18.

После того, как вы дойдете до конца (точнее когда счетчик инструкций станет равен 4 при том, что инструкции №4 в программе нет – они начинаются с 0) симулятор не даст больше трассировать программу. Чтобы повторить все сначала воспользуйтесь Debug/Reset. Вообще в этом меню есть много полезных команд.

Откройте окно состояния процессора (View/Processor). В нем можно видеть кое-какую полезную информацию о процессоре, которую мы изучим в дальнейшем. Пока же обратите внимание на:

- счетчик адресов инструкций (Program Counter) – это служебный регистр процессора, который хранит номер следующей выполняемой инструкции;

- счетчик циклов (Cycle Counter) – импульсов тактовой частоты процессора – обычно одна команда выполняется за один цикл (такт);

- указатель времени выполнения и секундомер – при тактовой частоте 1МГц один такт выполняется за 1 микросекунду (миллионная доля) и таково же время выполнения одной инструкции.

Попробуйте пошаговую трассировку, наблюдая за окном состояния процессора. Когда до вас дойдет смысл происходящих изменений, запустите Debug/AutoStep. Чтобы выйти из этого режима, используйте Debug/Break. Скорость выполнения в режиме AutoStep настраивается в DebugOptions в том же меню.



Похожие документы:

  1. В. В. Бибихин Витгенштейн: смена аспекта М.: Институт философии, теологии и истории св. Фомы, 2005. 576 с

    Документ
    ... записей ... включен в бесконечное пространство оттенков. Теперь мы можем ... их пример В. бы в Трактате привел. До первой публикации он послал ... выполнить ... , мы получаем в ... программный автомат никак не отреагирует, ес- ли человек за пультом начнет ... впоследствии ...
  2. Давайте проведем небольшой тест. Какие ассоциации вызывает у вас слово «хакер?»

    Документ
    ... памяти самомодифицирующийся программный код. Он мне ... Ну, мы можем сделать ... После этого, он собирал в кучу все подпрограммы и объединял их в одну, после чего получалось то, чего он ... возможно впоследствии создавал ... процессор — 6502, мог теперь выполнять ...
  3. Новые педагогические и информационные технологии в системе образования под редакцией д-ра пед. наук проф. е.сполат

    Документ
    ... выполнять, но они должны 39 знать, какие могут быть роли (лучше записать их ... • получите возможность проанализировать пример циклового пла ... язык команд, память, процессор и некоторые ... кода HTML, что, конечно, по силам далеко не всем ученикам), но мы можем ...
  4. И. П. Беляев проектирование

    Документ
    ... , что мы можем любую деятельность нарисовать с помощью квадратиков, потом нажать кнопочку, и получить работоспособное ... , процессором и программными средствами, позволяющими редактировать и обрабатывать данные независимо от работы ЭВМ. Примерами ИТ ...
  5. Велосипедный туризм ббк 75. 81 В27

    Документ
    ... Но мы можем проследить ... он должен быть включен. В результате такой съемки можно получить ... память компьютера, обору-дованного соответствующим аппаратным и программным ... записи и помет-ки в пути можно заносить в отдельный блокнот. Маршрутная схема выполняется ...

Другие похожие документы..