iTunes Gift Card (Russia) 4000 руб
iTunes Gift Card (Russia) 4000 руб


iTunes Gift Card (Russia) 2000 руб
iTunes Gift Card (Russia) 2000 руб


Разблокировка Билайн Смарт
Разблокировка Билайн Смарт


В начало

Лекция. Язык программирования МП - Ассемблер

 

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

Мнемоника

Операнды

Описание

Действие

Флаги

Цкл

АРИФМЕТИЧЕСКИЕ И ЛОГИЧЕСКИЕ КОМАНДЫ

ADD

Rd, Rr

Сложить два регистра

Rd<Rd+Rr

Z,C,N,V,H

1

ADC

Rd, Rr

Сложить с переносом

Rd<Rd+Rr+C

Z,C,N,V,H

1

ADIW

Rdl,K

Сложить слово с конст

Rdh,l<Rdh,l+K

Z,C,N,V,S

2

SUB

Rd, Rr

Вычесть два регистра

Rd<Rd-Rr

Z,C,N,V,H

1

SUBI

Rd, K

Вычесть константу

Rd<Rd-K

Z,C,N,V,H

1

SBIW

Rdl,K

Вычесть слово с конст

Rdh,l<Rdh,l-K

Z,C,N,V,S

2

SBC

Rd, Rr

Вычесть с переносом

Rd<Rd-Rr-C

Z,C,N,V,H

1

SBCI

Rd, K

Вычесть с переносом

Rd<Rd-K-C

Z,C,N,V,H

1

AND

Rd, Rr

Логическое И

Rd<Rd AND Rr

Z,N,V

1

ANDI

Rd, K

Логическое И

Rd<Rd AND K

Z,N,V

1

OR

Rd, Rr

Логическое ИЛИ

Rd<Rd OR Rr

Z,N,V

1

ORI

Rd, K

Логическое ИЛИ

Rd<Rd OR K

Z,N,V

1

EOR

Rd, Rr

Исключающее ИЛИ

Rd<Rd XOR Rr

Z,N,V

1

COM

Rd

Дополнение до 1

Rd<$FF - Rd

Z,C,N,V

1

NEG

Rd

Дополнение до 2

Rd<$00 - Rd

Z,C,N,V,H

1

SBR

Rd,K

Установ. бит(ы) в рег.

Rd<Rd OR K

Z,N,V

1

CBR

Rd,K

Сброс. бит(ы) в рег.

Rd<RdAND(FFh-K)

Z,N,V

1

INC

Rd

Увеличить на 1

Rd<Rd+1

Z,N,V

1

DEC

Rd

Уменьшить на 1

Rd<Rd-1

Z,N,V

1

TST

Rd

Проверить на 0 или 1

Rd<Rd AND Rd

Z,N,V

1

CLR

Rd

Очистить регистр

Rd<Rd XOR Rd

Z,N,V

1

SER

Rd

Установить регистр

Rd<$FF

None

1

КОМАНДЫ ВЕТВЛЕНИЯ

RJMP

k

Относительный переход

PC<PC+k+1

None

2

LJMP

 

Переход по адресу (Z)

PC<Z

None

2

RCALL

k

Относ. вызов подпрогр.

PC<PC+k+1

None

3

ICALL

 

Вызов подпр по адр (Z)

PC<Z

None

3

RET

 

Выход из подпрограммы

PC<STACK

None

4

RETI

 

Выход из прерывания

PC<STACK

I

4

CPSE

Rd,Rr

Сравнить, пропуск

если  равно

if(Rd=Rr)

PC<PC+2 или 3

None

1/2

CP

Rd,Rr

Сравнить

Rd-Rr

Z,N,V,C,H

1

CPC

Rd,Rr

Сравнить с переносом

Rd-Rr-C

Z,N,V,C,H

1

CPI

Rd,K

Сравнить с константой

Rd-K

Z,N,V,C,H

1

SBRC

Rr,b

Пропуск если бит в регистре сброшен

if(Rr(b)=0)                        PC<PC+2 или 3

None

1/2

SBRS

Rr,b

Пропуск если бит в регистре установлен

if(Rr(b)=1)                    PC<PC+2 или 3

None

1/2

SBIC

P, b

Пропуск если бит в рег ввода/выв. сброшен

if(P(b)=0)                         PC<PC+2 или 3

None

1/2

SBIS

P, b

Пропуск если бит в рег ввода/выв. установлен

if(P(b)=1)                    PC<PC+2 или 3

None

1/2

BRBS

s, k

Переход если установл. флаг s

if(SREG(s)=1)                                     PC<PC+k+1

None

1/2

BRBC

s, k

Переход если сброшен флаг s

if(SREG(s)=0)                                     PC<PC+k+1

None

1/2

BREQ

k

Переход если равно

if(Z=1)                                           PC<PC+k+1

None

1/2

BRNE

k

Переход если неравно

if(Z=0)                                           PC<PC+k+1

None

1/2

BRCS

k

Переход если установл. перенос

if(C=1)

PC<PC+k+1

None

1/2

BRCC

k

Переход если сброшен перенос

if(C=0)                                    PC<PC+k+1

None

1/2

BRSH

k

Переход если равно или больше

if(C=0)                                     PC<PC+k+1

None

1/2

BRLO

k

Переход если меньше

if(C=1)                                           PC<PC+k+1

None

1/2

BRMI

k

Переход если минус

if(N=1)                                           PC<PC+k+1

None

1/2

BRPL

k

Переход если плюс

if(N=0)                                           PC<PC+k+1

None

1/2

BRGE

k

Переход если больше или равно, со знаком

if(N XOR V=0)                        PC<PC+k+1

None

1/2

BRLT

k

Переход если меньше нуля, со знаком

if(N XOR V=1)                            PC<PC+k+1

None

1/2

BRHS

k

Переход если установл. флаг H

if (H=1)                                     PC<PC+k+1

None

1/2

BRHC

k

Переход если сброшен флаг H

if (H=0)                                     PC<PC+k+1

None

1/2

BRTS

k

Переход если установл. флаг T

if (H=1)                                     PC<PC+k+1

None

1/2

BRTC

k

Переход если сброшен флаг T

if (H=0)                                     PC<PC+k+1

None

1/2

BRVS

k

Переход если установлен флаг V (переполнение)

if (H=1)                      PC<PC+k+1

None

1/2

BRVC

k

Переход если сброшен флаг V

if (H=0)                                     PC<PC+k+1

None

1/2

BRIE

k

Переход если разрешены прерывания

if(I=1)                                 PC<PC+k+1

None

1/2

BRID

k

Переход если запрещены прерывания

if(I=1)                                 PC<PC+k+1

None

1/2

КОМАНДЫ ПЕРЕСЫЛКИ

MOV

Rd,Rr

Пересылка между рег.

Rd<Rr

None

1

LDI

Rd,K

Загрузить константу

Rd<K

None

1

LD

Rd,X

Загрузить регистр непосредственно

Rd<(X)

None

2

LD

Rd,X+

Загрузить регистр непоср. c пост инкрем.

Rd<(X),X<X+1

None

2

LD

Rd,-X

Загрузить регистр непоср. с предвекрем.

X<X-1,Rd<(X)

None

2

LD

Rd,Y

Загрузить регистр непосредственно

Rd<(Y)

None

2

LD

Rd,Y+

Загрузить регистр непоср. c пост инкрем.

Rd<(Y),Y<Y+1

None

2

LD

Rd,-Y

Загрузить регистр непоср. с предвекрем.

Y<Y-1,Rd<(Y)

None

2

LDD

Rd,Y+q

Загрузить регистр непоср. со смещением

Rd<(Y+q)

None

2

LD

Rd,Z

Загрузить регистр непосредственно

Rd<(Z)

None

2

LD

Rd,Z+

Загрузить регистр непоср. c пост инкрем.

Rd<(Z),Z<Z+1

None

2

LD

Rd,-Z

Загрузить регистр непоср. с предвекрем.

Z<Z-1,Rd<(Z)

None

2

LDD

Rd,Z+q

Загрузить регистр непоср. со смещением

Rd<(Z+q)

None

2

LDS

Rd,k

Загрузить из ОЗУ

Rd<(k)

None

3

ST

X,Rr

Записать регистр непосредственно

(X)<Rr

None

2

ST

X+,Rr

Записать регистр непоср.c пост инкр.

(X)<Rr,X<X+1

None

2

ST

-X,Rr

Записать регистр непоср.c предекрем.

X<X-1,(X)<Rr

None

2

ST

Y,Rr

Записать регистр непосредственно

(Y)<Rr

None

2

ST

Y+,Rr

Записать регистр непоср.c пост инкр.

(Y)<Rr,Y<Y+1

None

2

ST

-Y,Rr

Записать регистр непоср.c предекрем.

Y<Y-1,(Y)<Rr

None

2

STD

Y+q,Rr

Записег.непоср.со смещением

(Y+q)<Rr

None

2

ST

Z,Rr

Записать регистр непосредственно

(Z)<Rr

None

3

ST

Z+,Rr

Записать регистр непоср.c пост инкр.

(Z)<Rr,Z<Z+1

None

2

ST

-Z,Rr

Записать регистр непоср.c предекрем.

Z<Z-1,(Z)<Rr

None

2

STD

Y+q,Rr

Записег.непоср.со

смещением

(Y+q)<Rr

None

2

STS

k,Rr

Записать в ОЗУ

(k)<Rr

None

3

LPM

 

Загрз памяти прогр.

R0<(Z)

None

3

IN

Rd, P

Ввод из порта

Rd<P

None

1

OUT

P, Rr

Вывод в порт

P<Rr

None

1

PUSH

Rr

Записать в стек

STACK<Rr

None

2

POP

Rr

Прочитать из стека

Rr<STACK

None

2

КОМАНДЫ РАБОТЫ С БИТАМИ

SBI

P,b

Установить бит в рег. ввода/вывода

I/O(P,b)<1

None

2

CBI

P,b

Сбросить   бит в рег. ввода/вывода

I/O(P,b)<0

None

2

LSL

Rd

Логический сдвиг влево

Rd(n+1)<Rd(n), Rd(0)<0

Z,C,N,V

1

LSR

Rd

Логичдвиг вправо

Rd(n)<Rd(n+1), Rd(7)<0

Z,C,N,V

1

ROL

Rd

сдвиг влево через C

Rd(0)<C, Rd(n+1)<Rd(n), C<Rd(7)

Z,C,N,V

1

ROR

Rd

сдвиг вправо через C

Rd(7)<C, Rd(n)<Rd(n+1), C<Rd(0)

Z,C,N,V

1

ASR

Rd

Арифметический сдвиг вправо

Rd(n)<Rd(n+1), n=0..6

Z,C,N,V

1

SWAP

Rd

Обмен нибблов (тетрад)

Rd(3-0)<Rd(7-4) Rd(7-4)<Rd(3-0)

None

1

BSET

s

Установить флаг

SREG(s)<1

SREG(s)

1

BCLR

s

Сбросить флаг

SREG(s)<0

SREG(s)

1

BST

Rr,b

Запомнить бит в T

T<Rr(b)

T

1

BLD

Rd, b

Прочитать бит из T

Rd(b)<T

None

1

SEC

 

Установить перенос

C<1

C

1

CLC

 

Сбросить перенос

C<0

C

1

SEN

 

Установить флаг N

N<1

N

1

CLN

 

Сбросить флаг N

N<0

N

1

SEZ

 

Установить флаг Z

Z<1

Z

1

CLZ

 

Сбросить флаг Z

Z<0

Z

1

SEI

 

Разрешить прерывания

I<1

I

1

CLI

 

Запретить прерывания

I<0

I

1

SES

 

Установить флаг S

S<1

S

1

CLS

 

Сбросить флаг S

S<0

S

1

SEV

 

Установить флаг V

V<1

V

1

CLV

 

Сбросить флаг V

V<0

V

1

SET

 

Установить флаг T

T<1

T

1

CLT

 

Сбросить флаг T

T<0

T

1

SEH

 

Установить флаг H

H<1

H

1

CLH

 

Сбросить флаг H

H<0

H

1

NOP

 

Нет операции

 

None

1

SLEEP

 

Останов

 

None

3

WDR

 

Сброс сторожевого таймера

 

None

1

                                                  

Команды ветвления позволяют разветвлять ход выполнения программы за счет анализа флагов статусного регистра, которые изменяются после выполнения арифметической команды вычитания (с целью сравнения, например, текущего значения счетчика и его предельного значения). Если после выполнения арифметической операции изменяется содержимое флага, контролируемое в данной команде ветвления, то после выполнения команды ветвления содержимое программного счетчика может принимать двоякое значение: 1) либо оно на единицу больше, чем содержимое РС при выполнении предыдущей программы ( т.е. условие не выполняется); 2) либо содержимое РС изменяется на константу, являющуюся операндом команды ветвления ( условие выполняется).

                    

4. Выражения языка ассемблер

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

Операнды могут быть следующих видов:

1. Метки, определенные пользователем, которые определяют численные значения адреса либо ячейки ОЗУ, либо программы команды.

2. Переменная, определенная директивой .SET

3. Константы, определенные директивой EQU

4. Операндами могут быть числа, заданные в разных форматах:

    а) десятичный, который использует лишь десятичные символы 10,                       20,….

   б) 16-ричный использует 2 варианта записи: 0хОА и $ ОА

 в) двоичный начинается с символов Ов и использует лишь нули и 1.

г) восьмеричный начинается обязательно с 0 и использует младшие 8 десятичных  цифр.(0-7).

5.Имя РС, текущие значения программного счетчика.

Компилятор поддерживает ряд операторов в выражениях, которые перечислены ниже согласно их приоритету. Изменения приоритета того или иного оператора при вычислении выражения добиваются использованием круглых скобок.

1. Оператор «Логическое отрицание» записывается символом «!». Этот оператор возвращает единицу, если его операнд равен нулю и возвращает ноль, если операнд отличен от нуля

Пример №1:

LDI R16, !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 от выражения.