Академический Документы
Профессиональный Документы
Культура Документы
Ассемблера
Лекция 2
2
Терминология
1. Язык ассемблера - это любой язык программирования низкого
уровня, в котором существует очень строгое соответствие между
инструкциями на языке и инструкциями машинного кода для
конкретной архитектуры процессора.
2. Инструкции - это специальные мнемоники, которые ассемблер
переводит в машинный код. Как следует из названия, они
«приказывают» процессору что-то делать.
3. Директивы - это руководства для транслятора, используемые им для
автоматизации процесса сборки и улучшения читаемости
программы.
4. Функция - это блок организованного многократно используемого
кода, который используется для выполнения одного связанного
действия.
3
Что такое ассемблер?
Ассемблер - это язык низкого уровня.
В чем его отличие от языков высокого уровня?
В языках высокого уровня программы не зависят от
оборудования или возможностей процессора. Эти
программы работают на разных процессорах, если
существует компилятор для этого языка и семейства
процессоров. Компилятор переводит эти языковые
конструкции на двоичный язык процессора.
4
Ассемблер для микроконтроллера
Идея ассемблера - сделать доступными Memory
аппаратные ресурсы процессора.
Под ресурсами будем понимать все
аппаратные компоненты, например
центральный процессор (ЦП) и его
математический сопроцессор, арифметико-
логический блок (АЛУ), различные блоки
хранения (внутренняя и внешняя RAM,
память EEPROM),порты, регистры
управления и настройки портов, таймеров,
аналого-цифровых преобразователей и assembler C
других устройств.
5
Ассемблер для микроконтроллера
Доступный ресурс - означает прямой доступ, а не через
драйверы или другие интерфейсы, которые предоставляет
операционная система. Это означает, что вы управляете
последовательным интерфейсом или аналого-цифровым
преобразователем и между оборудованием и вашей
программой нет никаких других драйверов, никакого
промежуточного слоя. Награда за ваши усилия - все
оборудование находится в вашем распоряжении, а не
только часть, которую вам предоставляют разработчик
компилятора и программист операционной системы.
6
Зачем учить ассемблер?
• Изучение ассемблера позволяет вам полностью оптимизировать
код для любой ситуации и позволяет писать программы, которые
делают именно то, что вы хотите, так, как вы хотите, чтобы
компилятор не пытался периначить вашу программу.
• Изучение ассемблера дает вам полную прозрачность в вашей
программе и, что самое главное, сделает вас лучшим
программистом на C.
• Кроме того, критичные ко времени алгоритмы могут быть написаны
на ассемблере и вызваны из основной программы, написанной на
C. Смешивание этих двух языков позволяет вам использовать
сильные стороны каждого языка для создания наилучших
программ.
7
Как устроена программа?
Программы на ассемблере будут сильно отличаться от программ на языке C,
к которым вы привыкли. В коде программы строки организованы в столбцы
для удобства чтения и обычно содержат метки, директивы или инструкции,
за которыми следуют один или два операнда. Кстати операндов может и не
быть.
Каждый из этих элементов может быть помещен в любой столбец по выбору
программиста, хотя порядок, в котором они расположены, имеет значение.
Обычно первый столбец оставляют для меток, а инструкции размещают во
втором или третьем.
.cseg ; директива
lbl1: .byte 10 ; метка перед директивой с аргументов
lbl2: add r22,r23 ; метка перед инструкцией с двумя операндами
inc r22 ; инструкция с одним операндом
nop ; инструкция без операндов
8
Инструкции
Инструкции могут содержать один, два или ни одного
операнда, которые должны сразу следовать за ним в
одной строке. Обратите внимание, что указанные
выше операнды должны быть разделены запятой.
Кроме того, они помещены в следующий столбец для
облегчения чтения.
11
Директивы (.def)
Директива .def позволяет привязать к любому слову любое значение из
ресурсов контроллера — порт или регистр. Например сделал я счетчик, а
считаемое значение находится в регистре R0, а в качестве регистра-
помойки для промежуточных данных я заюзал R16. Чтобы не запутаться и
помнить, что в каком регистре у меня задумано я присваиваю им через
.def символические имена.
.def schetchik = R0
.def pomoika = R16
ADD schetchik, pomoika
И теперь в коде могу смело использовать вместо официального имени R0
неофицальную кличку schetchik. Одному и тому же регистру можно давать
кучу имен одновременно и на все он будет честно откликаться.
Директивы (.EQU)
Директива .equ это присвоение выражения или константы какой либо
символической метке.
Например, у меня есть константа которая часто используется. Можно, конечно,
каждый раз писать ее в коде, но вдруг окажется, что константа выбрана неверно, а
значит придется весь код шерстить и везде править, а если где-нибудь забудешь, то
получишь такую махровую багу, что задолбаешься потом ее вылавливать. Так что
нафиг, все константы писать надо через .equ!
Кроме того, можно же присвоить не константу, а целое выражение. Которое при
компиляции посчитается препроцессором, а в код пойдет уже исходное значение.
Надо только учитывать, что деление тут исключительно целочисленное. С
отбрасыванием дробной части, без какого-либо округления, а значит 1/2 = 0, а 5/2 = 2
.equ Time = 5
.equ Acсelerate = 4
.equ Half_Speed = (Accelerate*Time)/2
Директивы (.CSEG)
.CSEG сегмент кода, он же флеш. После этой директивы идет тело программы,
команды процессора. Тут же можно засунуть какие ни будь данные которые не
меняются, например таблицу с заранее посчитанными значениями, статичный текст
или таблицу символов для знакогенератора. Делается это при помощи директив:
.db массив байтов. .dw массив слов —два байта.
.dd массив двойных слов — четыре байта .dq массив четверных слов — восемь байт.
Например так:
.CSEG
Constant: .db 10 ; или 0хAh в шестнадцатеричном коде
Message: .db "Привет лунатикам"
Words: .dw 10, 11, 12
В итоге, во флеше вначале будет лежать число 0А, затем побайтно будут хекскоды
символов фразы «привет лунатикам», а дальше 000A, 000B, 000С.
Последние числа, хоть сами и невелики, но занимают по два байта каждое, так как
объявлены как .dw.
Директивы (.org, .dseg)
.ORG address означает примерно следующее «копать отсюда и до обеда», т.е. до
конца памяти. Данный оператор указывает с какого адреса пойдет то что после этой
диррективы. Обычно используется для создания таблицы прерываний. Еще может
применятся в сегменте данных (см. далее) для резервирования данных по
конкретному адресу.
.DSEG сегмент данных, оперативка. Те самые жалкие считанные байты. Сюда не
зазорно пихать переменные, делать тут буфера, тут же находится стек.
Тут действует дирректива .BYTE позволяющая указать на расположение данных в
памяти.
Например так:
var1: .BYTE 1
table: .BYTE 10
В первом случае мы указали переменную var1 состоящую из одного байта.
Во втором случае у нас есть цепочка из 10 байт и метка (адрес) table указывающая на
первый байт из цепочки. Адрес остальных вычисляется смещением.
Директивы (.db, .dw)
.DB и.DW - это директивы, позволяющие поместить во флэш-память список констант или строку
текста и прочитать их.
.byte директива резервирует один или несколько последовательных байтов в текущем разделе
памяти данных.
16
Комментарии
Комментарии в программе начинаются с точки с запятой.
Комментарии обычно помещаются в крайний правый столбец
строки кода.
19
Как это работает?
Example Data segment Command segment
.dseg RAM FLASH
.org 0x70 Address Address
Array:. byte 6 $0060 ? $0000 ldi r30, low (Array)
.cseg … … ldi r31, high (Array)
ldi r30, low (Array) $0070 byte0 ld r28, Z+
ldi r31, high (Array) $0071 byte1
ld r28,Z+ … ... Z - register
The result of r28 is 10, $0075 byte5 $00 $70
Z=r31:r30=0x71 …
? $00 $71
Z – register ++
20
Потренируемся
1. ldi r22, 10 084 <255 6. add r21, r22, r23
adi
2. add r22, 5 7. add r23, r34 <r32
3. dec x , 1 8. .dseg
.byte 10
" "
4. .include ‘m8def.inc’ .db 1,3,-5
=
5. .def temp, R16
21
Лабораторный стенд STK500
Разъемы Панели Выходы
Кнопка «сброс»
портов для ЧИПа микроконтроллера
Кнопки
Кнопка питания
Разъем для programming
кнопок port Разъем питания