|
В начало
Лекция. Язык программирования МП - Ассемблер
1. Правила программирования на языке
Ассемблер Компилятор языка Assembler преобразует текст из
программы, написанной на языке Assembler
в машинные коды, которые в последующем записываются в область ПЗУ процессора. Программа на языке Assembler содержит команды, метки и
директивы. Команды и директивы, как правило, имеют один или несколько
операндов. Любая строка программы может начинаться с
метки, которая является набором символов, заканчивающихся двоеточием. Метки используются для определения места,
в которое передается управление при переходах, реализуемых командами передачи
управления (ветвления). Метки используются также для задания имен переменных. Строка программы на языке Assembler может иметь одну из
4-х форм: 1. [метка] _ директива _ [операнды] _
[комментарий] 2. [метка] _ команда _ [операнды] _
[комментарий] 3. комментарий 4. пустая строка Комментарии имеют форму, состоящую из 2-х
элементов: ; [текст] Позиции в [ ]
являются не обязательными. Текст после “ ; “
до конца строки игнорируется компилятором. Длина строки не должна превышать 120
символов. 2. Директивы языка ассемблер Директивы не транслируются непосредственно
в машинный код. Они используются для указания компилятору положения кода в
программной памяти, для инициализации памяти и для других целей. Директива BYTE . Это директива резервирует байты ОЗУ (в области Data). Все директивы начинаются
с символа «точка». Пример №1: .DSEQ Var1: .BYTE 1 .CSEQ ldi r30, low(varl) ldi r31, high(varl) ld r1, z Директива .DSEQ . Определяет, что
нижеследующие строки относятся к области Data ОЗУ. Эта директива не имеет операндов. Директива
.BYTE .
Имеет один обязательный операнд, указывающий количество выделенных байтов. Если необходимо чтобы обращение к
выделенным байтам происходило по имени, то вводится метка (в данном случае это
метка Var
1). Директива
.CSEQ. Указывает компилятору, что последующие строчки программы
должны компилироваться и располагаться в области ПЗУ. В последующих командах используется
переменная Var
1, определяющая содержимое ячеек памяти ОЗУ. Выражения low и high являются стандартными выражениями языка Assembler и предназначены для
определения старшего и младшего байтов адреса переменной Var 1, указанного в
качестве операнда этих выражений. Пример №2: определить старший и младший
байты числа 30010. Переводим 30010→Х16 300| 16 288| 18|16 12 16| 1|16 2 0| 0 1 30010→12C16 Старший байт – 01, младший байт – 2С. Директива
.DEF. Эта директива назначает регистру символическое имя. Это имя
может использоваться в нижеследующей части программы для обращения к данному
регистру. Символическое имя может быть переименовано в программе несколько раз.
Синтаксис этой директивы следующий: .DEF Символическое имя =регистр Пример №3: .DEF temp=R16 .DEF ior=R0 .CSEQ .ldi _ temp, 0×f0 .eor temp, ior Директива
.DEVICE. Определяет
устройство, для которого компилируется программа. Использование данной
директивы позволяет компилятору выдать предупреждение, если появится команда,
не поддерживаемая данным контроллером. Пример №4: .DEVICE AT90S2313 Директива
.EQU.Позволяет определить константу путем задания ее меткой. Формат
этой директивы: .EQU метка=выражение Пример №5: .EQU io_offset=0×23 .EQU port a = io_offset+2 .CSEQ clr r2 out port a, r2 Директива
.include. Означает вложение другого файла (содержимое файла
включается в программу при компиляции). Встретив .include компилятор
открывает указанный в этой директиве файл, компилирует его до конца (т.е.
переводит в машинные коды) или до директивы .EXIT. После этого продолжается компиляция начального файла со
строки, следующей за директивой include.
Вложенный файл тоже может содержать директиву include. Пример №6: ; файл iodefs.asm .EQU sreq=0×3F .EQU sphigh=0×3e .EQU splow=0×3d ; файл incdemo.asm .include iodefs.asm in ro,sreg Директива
.ORG устанавливает
счетчик в положение равным заданной величине, которая входит как параметр в эту
директиву. Для сегмента данных она устанавливает счетчик положения ОЗУ, для
сегмента программ или памяти программ она устанавливает содержимое РС
(программного счетчика), а для сегмента Eeprom устанавливает положение в
области Eeprom. Если директиве предшествует метка, то она
становится равной адресу, указанному в параметре директивы при компиляции программы. Перед началом компиляции РС и счетчик Eeprom
нулю, а счетчик ОЗУ=32. Для ОЗУ и Eeprom используются
побайтные счетчики, а для программного сегмента пословные. Пример №7: .DSEQ .ORG 0×37 ; variable: .BYTE 1 ; резервирует байт по адресу 0×37 .CSEQ .ORG 0×10 MOV RO, R1; данная команда размещается по адресу 0×10 Директива
.SET присваивает метке определенное значение, которое далее может
быть использовано в выражениях. В отличие от директивы EQU значение метки может быть изменено
другой директивой .SET Пример №8: .SET io1=0×23 .SET PORTA=io1+1 .CSEQ out PORTA, R2 3. Команды языка ассемблер Набор команд AT90S2313
Команды
ветвления позволяют разветвлять ход
выполнения программы за счет анализа флагов статусного регистра, которые
изменяются после выполнения арифметической команды вычитания (с целью
сравнения, например, текущего значения счетчика и его предельного значения).
Если после выполнения арифметической операции изменяется содержимое флага,
контролируемое в данной команде ветвления, то после выполнения команды
ветвления содержимое программного счетчика может принимать двоякое значение: 1)
либо оно на единицу больше, чем содержимое РС при выполнении предыдущей
программы ( т.е. условие не выполняется); 2) либо содержимое
РС изменяется на константу, являющуюся операндом команды ветвления ( условие
выполняется). 4. Выражения языка ассемблер Компилятор позволяет использовать в программе выражения, которые состоят
из операндов, операторов и функций. Все выражения являются четырехбайтными. Операнды могут быть следующих видов: 1. Метки, определенные пользователем,
которые определяют численные значения адреса либо ячейки ОЗУ, либо программы
команды. 2. Переменная, определенная директивой .SET 3. Константы, определенные директивой EQU 4. Операндами могут быть числа, заданные в
разных форматах:
а) десятичный, который использует лишь десятичные символы 10, 20,….
б) 16-ричный использует 2 варианта записи: 0хОА и $ ОА в) двоичный начинается с символов Ов
и использует лишь нули и 1. г) восьмеричный
начинается обязательно с 0 и использует младшие 8 десятичных цифр.(0-7). 5.Имя РС, текущие значения программного
счетчика. Компилятор
поддерживает ряд операторов в выражениях, которые перечислены ниже согласно их
приоритету. Изменения приоритета того или иного оператора при вычислении
выражения добиваются использованием круглых скобок. 1. Оператор «Логическое отрицание»
записывается символом «!». Этот оператор возвращает единицу, если его операнд
равен нулю и возвращает ноль, если операнд отличен от нуля Пример №1: LDI R16, !0×F0; в R16 загружается число 0×00 2. Оператор «Побитное отрицание»
записывается символом ~ (тильда). Этот оператор возвращает операнд, в котором
все биты проинвертированы Пример №2: LDI R16, ~0×F0;
в R16 загружается число
0×0F LD R16, ~0×28 3. Оператор «минус» “ - ” возвращает
арифметическое отрицание исходного операнда. Пример №3: LD R16, - 2; в R16
загружается число 0×FE 4. Оператор умножения обозначается
знаком “ * ” Пример №4: Ldi r30, label*2 5. Оператор деления записывается символом
“ / ”, возвращает целую часть деления (частное) левого выражения на правое. Пример №5: Ldi r30, label/2 6. Оператор суммирования обозначается “ +
” и возвращает сумму двух выражений. Пример №6: Ldi r30, c1+12 7. Оператор вычитания обозначается
символом “ - ” и возвращает результат вычитания из левого операнда правого операнда. Пример №7: Ldi r30, с1 – с2 8. Оператор «сдвиг влево» записывается
символом “ << ” и возвращает левое
выражение сдвинутое влево на число бит указанное справа. Пример №8: Ldi r17, 1<<bit 9. Оператор «Сдвиг вправо» записывается
символом “ >> ” и возвращает выражение сдвинутое
вправо на число бит указанное справа. Пример №9: Ldi r17, c1>>c2 10. Оператор “ меньше чем ” записывается
символом “ < ” и возвращает 1, если левое выражение меньше чем правое (в
скобках учитывается знак) и возвращает 0 в противном случае. Пример №10: Ori r18, bitmask*(c1<c2)+1 11. Оператор “ <= ”, возвращает 1, если
левое выражение <= чем правое и 0 в противном
случае. 12. Оператор «больше или равно “ >= ”
вводится аналогично. 13. Оператор «равно» записывается в виде “
= = ” возвращает 1, если левое выражение равно правому и 0 в противном случае. 14. Оператор «не равно» записывается в
виде “ != ”возвращает 1, если левое выражение не равно
правому и 0 в противном случае. 15. Оператор “ побитное
И ” записывается символом “ & ” возвращает результат побитного
логического умножения двух выражений. 16. Оператор “ побитное
исключающее ИЛИ ”записывается символом “ ^ ” возвращает результат побитного
логического сложения двух выражений по модулю два. 17. Оператор “ побитное
ИЛИ ” записывается символом “ | ” возвращает результат побитного логического
сложения двух выражений. 18. Оператор “ логическое И ” записывается символом “ && ”и возвращает 1,
если оба выражения не равны 0 и 0 в противном случае. 19. Оператор “ логическое ИЛИ
”записывается символом “ | | ” возвращает 1, если хотя бы одно выражение не
было равно 0 и 0 в противном случае. В языке
Assembler
определены следующие функции: LOW (выражение) эта функция возвращает
младший байт выражения. HIGH (выражение) эта функция возвращает
второй байт выражения. BYTE 2 (выражение) эта функция
возвращает второй байт выражения. BYTE 3 (выражение) эта функция
возвращает третий байт выражения. BYTE 4 (выражение) эта функция
возвращает четвертый байт выражения. LWRD (выражение) эта функция возвращает
биты с 0 по 15. HWRD (выражение) эта функция возвращает
биты с 16 по 31. PAGE (выражение) эта функция возвращает
биты с 16 по 21 от выражения. EXP 2 (выражение) возвращает 2 в степени
выражения. LOG 2 (выражение) возвращает целую часть логарифма с основанием 2
от выражения. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||