Foreversoft.ru

IT Справочник
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Ассемблер команда переадресации стека памяти 20th

Ассемблер команда переадресации стека памяти 20th

6.1. Типы операндов.

При изучении данной темы мы рассмотрим всего три типа операндов, которые могут встречаться в любой команде: непосредственно заданное значение (immediate), регистр (register) и память (memory). Из всех перечисленных здесь типов только последний (память) довольно труден для освоения. Список условных обозначений возможных типов операндов, взятых из руководства фирмы Intel по процессору Pentium, приведен в табл. 1. Довайте изучим его, поскольку с этого момента мы будем активно пользоваться этими обозначениями при описании синтаксиса команд процессоров Intel.

Таблица 1. Условное обозначение типов операндов.

Один из 8-разрядных регистров общего назначения: АН, AL, BH, BL, CH, CL, DH, DL

Один из 16-разрядных регистров общего назначения: АХ, BX, СХ, DX, SI, DI, SP, BP

Один из 32-разрядных регистров общего назначения: ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP, EBP

Произвольный регистр общего назначения

Один из 16-разрядных сегментных регистров: CS, DS, SS, ES, FS, GS

Непосредственно заданное 8-разрядное значение (байт)

Непосредственно заданное 16-разрядное значение (слово)

Непосредственно заданное 32-разрядное значение (двойное слово)

Непосредственно заданное 8-, 16- или 32-разрядное значение

8-разрядный операнд, в котором закодирован один из 8-разрядных регистров общего назначения или адрес байта в памяти

16-разрядный операнд, в котором закодирован один из 16-разрядных регистров общего назначения или адрес слова в памяти

32-разрядный операнд, в котором закодирован один из 32-разрядных регистров общего назначения или адрес двойного слова в памяти

Адрес 8-, 16- или 32-разрядного операнда в памяти

Команда MOV копирует данные из операнда-источника в операнд-получатель. Она относится к группе команд пересылки данных (data transfer) и используется в любой программе. Команда MOV является двуместной (т.е. имеет два операнда): первый операнд определяет получателя данных (destination), а второй — источник данных (source):

При выполнении этой команды изменяется содержимое операнда-получателя, а содержимое операнда-источника не меняется. Принцип пересылки данных справа налево соответствует принятому в операторах присваивания языков высокого уровня, таких как C ++:

Практически во всех командах ассемблера операнд-получатель находится слева, а операнд-источник— справа.

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

1. Оба операнда должны иметь одинаковую длину.

2. В качестве одного из операндов обязательно должен использоваться регистр (т.е. пересылки типа «память-память» в команде MOV не поддерживаются).

3. В качестве получателя нельзя указывать регистры CS , EIP и IP .

4. Нельзя переслать непосредственно заданное значение в сегментный регистр.

Ниже приведены варианты использования команды MOV с разными операндами (кроме сегментных регистров):

Сегментные регистры в команде MOV обычно используются только в программах, написанных для реального или виртуального режимов работы процессора. При этом могут существовать следующие ее формы (следует учитывать, что регистр CS нельзя указывать в качестве получателя данных):

Пересылка типа «память—память». С помощью одной команды MOV нельзя напрямую переслать операнд из одной области памяти в другую. Поэтому вначале нужно загрузить исходное значение в один из регистров общего назначения, а затем переслать его в нужное место памяти.

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

6.3. Команда MOVZX.

Команда MOVZX (Move With Zero-Extend, или Переместить и дополнить нулями) копирует содержимое исходного операнда в больший по размеру регистр получателя данных. При этом оставшиеся неопределенными биты регистра-получателя (как правило, старшие 16 или 24 бита) сбрасываются в ноль. Эта команда используется только при работе с беззнаковыми целыми числами. Существует три варианта команды MOVZX:

MOVZX r 16, r / m 8

MOVZX r 32, r / m 8

Условные обозначения операндов этой команды приведены в табл. 1. В каждом из приведенных трех вариантов первый операнд является получателем, а второй — источником данных. В качестве операнда-получателя может быть задан только 16- или 32-разрядный регистр. На рис. 8 показано, как 8-разрядный исходный операнд загружается с помощью команды MOVZX в 16-разрядный регистр.

Рис. 8. Иллюстрация работы команды MOVZX.

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

movzx eax, bx ; EAX = 0000A69Bh

movzx edx, bl ; EDX = 0000009Bh

movzx cx, bl ; CX = 009Bh

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

char byte1 = 0x9B;

short word1 = 0xA69B;

Команда MOVSX ( Move With Sign — Extend , или переместить и дополнить знаком) копирует содержимое исходного операнда в больший по размеру регистр получателя данных, также как и команда MOVZX . При этом оставшиеся неопределенными биты регистра-получателя (как правило, старшие 16 или 24 бита) заполняются значением знакового бита исходного операнда. Эта команда используется только при работе со знаковыми целыми числами. Существует три варианта команды MOVSX :

MOVSX r 16, r / m 8

MOVSX r 32, r / m 8

MOVSX r 32, r / m 16

При загрузке меньшего по размеру операнда в больший по размеру регистр с помощью команды MOVSX , знаковый разряд исходного операнда дублируется (т.е. переносится или расширяется) во все старшие биты регистра-получателя. Например, при загрузке 8-разрядного значения 10001111 b в 16-разрядный регистр, оно будет помещено в младшие 8 битов этого регистра. Затем, как показано на рис. 9, старший бит исходного операнда переносится во все старшие разряды регистра-получателя.

Рис. 9. Иллюстрация работы команды MOVSX.

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

movsx eax, bx ; EAX = FFFFA69Bh

movsx edx, bl ; EDX = FFFFFF9Bh

movsx cx, bl ; CX = FF9Bh

Команда LAHF ( Load Status Flags Into АН, или загрузить флаги состояния в регистр АН) позволяет загрузить в регистр АН младший байт регистра флагов EFLAGS . При этом в регистр АН копируются следующие флаги состояния: SF (флаг знака), ZF (флаг нуля), AF (флаг служебного переноса), PF (флаг четности) и CF (флаг переноса). С помощью этой команды можно легко сохранить содержимое регистра флагов в переменной для дальнейшего анализа:

Команды пересылки данных

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

Команда пересылки MOV — основная команда пересылки данных, которая позволяет переслать содержимое источника (операнд 2) в приемник (операнд 1). Содержимое приемника безвозвратно теряется, содержимое источника не изменится

Формат команды MOV ,

В качестве приемника можно использовать один из регистров общего назначения 8-ми и 16-ти разрядный или переменную в памяти размерностью в байт или слово.

В качестве источника можно также использовать один из регистров общего назначения (8-ми или 16-ти разрядные), переменную в памяти (байт или слово), а также константу размерностью в байт или слово (понятно, что константу нельзя использовать в качестве приемника).

При использовании команд пересылки необходимо помнить:

— нельзя пересылать данные непосредственно между двумя адресами памяти;

— следить за тем, чтобы размерности пересылаемых операндов соответствовали друг другу, иначе может возникнуть ошибка;

— нельзя пересылать данные из одного сегментного регистра в другой;

— при помощи команды MOV нельзя загрузить сегментный регистр CS.

При выполнении команды MOV никакие флаги — не меняются.

Команда замены XCHG

Команда XCHG просто меняет местами между собой содержимое двух операндов (например, двух регистров, или регистра и ячейки памяти).

Формат команды XCHG ,

Команда XCHG заменяет три команды пересылки и не требует промежуточной ячейки памяти.

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

При выполнении команды XCHG никакие флаги не меняются

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

Читать еще:  Структура ip адреса

Формат команды LEA , , где — один из регистров общего назначения, значение которого безвозвратно теряется. Второй операнд является некоторым адресом или адресным выражением. В качестве второго операнда можно использовать любой вид адресации.

При выполнении команды LEA никакие флаги микропроцессора, описывающие его состояние, не меняются.

Отличие от команды MOV в том, что по команде MOV загружается значение некоторого участка памяти, а при команде LEA — адрес начала этого участка.

Оператор указания типа — PTR

При записи команд в символьной форме необходимо внимательно следить за правильным указанием типа (размера) операндов, чтобы не было ошибок. Тип обычно определяется по внешнему виду одного из них, например:

MOV AH,5 ; пересылка байта, т.к. AH — байтовый регистр

MOV AX,5 ; пересылка слова, т.к. AX — 16-битовый регистр

; (операнд 5 может быть байтом и словом, по нему нельзя определить размер пересылаемой величины)

MOV [BX],300 ; пересылка слова, т.к. число 300 не может быть байтом

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

MOV DS,AX ; оба операнда имеют размер слова

MOV CX,BH ; ошибка: регистры CX и BH имеют разные размеры

MOV DL,300 ; ошибка: DL — байтовый регистр, а число 300 не может быть байтом.

Возможны ситуации, когда по внешнему виду операндов нельзя опреде­лить тип ни одного из них, как, например, в команде

Здесь число 5 может быть и байтом, и словом, а адрес из регистра BX может указывать и на байт памяти, и на слово. В подобных ситуациях ас­семблер фиксирует ошибку. Чтобы избежать ее, надо уточнить тип одного из операндов с помощью оператора с названием PTR, который записывается следующим образом:

— это BYTE, WORD, а — может быть константой или адресом, например,

MOV BYTE PTR [BX],5 ; пересылка байта

MOV WORD PTR [BX],5 ; пересылка слова

Оператор PTR необходим и в том случае, когда надо изменить тип, предписанный имени при его описании. Если, например, X описано как имя переменной размером в слово:

и если надо записать в байтовый регистр AH значение только первого байта этого слова, тогда воспользоваться командой

нельзя, т.к. ее операнды имеют разный размер. Эту команду следует за­писать несколько иначе:

MOV AH,BYTE PTR X

Здесь конструкция BYTE PTR X означает адрес X, но уже рассматриваемый не как адрес слова, а как адрес байта. (Напомним, что с одного и того же адреса может начинаться байт, слово и двойное слово; оператор PTR уточняет, ячейку какого размера мы имеем в виду.)

К командам пересылки относятся также команды стека PUSH и POP

Стеком называют область памяти для временного хранения произвольных данных. Удобство стека заключается в том, что его область используется многократно. Размер стека не должен превышать 64 кбайт и начальный адрес должен быть кратен 16. Другими словами, эта область должна быть сег­ментом памяти; он называется сегментом стека, где начальный адрес хранится в регистре SS

В ПК принято стек заполнять снизу вверх: первый элемент записывается в стек в ячейку области с наибольшим адресом (дно стека), следующий элемент записывается над ним и т.д. При считывании из стека первым удаляется самый верхний элемент (признак LIFO — “последним пришёл — первым ушёл”).

Таким образом, получается, что дно стека фиксировано, а вершина стека всё время сдвигается. Для того чтобы знать текущее положение этой вершины, используется регистр SP — указатель стека, в котором хранится адрес той ячейки, где находится элемент, записанный в стек последним.

Следовательно, в SP — находится смещение, т.е. адрес, отсчитанный от начала сегмента стека. Абсолютный адрес вершины стека задается парой регистров SS:SP

И не следует забывать, что по мере записи данных в стек, последний растёт в сторону младших адресов (эта особенность заложена в алгоритм команд работы со стеком).

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

Основными стековыми командами являются команды записи слова в стек и считывания слова из стека.

Формат команды: PUSH

Команда PUSH записывает в стек свой операнд, которым может быть слово. Флаги команда не меняет.

Чтение из стека слова: POP

Команда POP считывает слово из вершины стека

Следующая пара стековых команд используется для записи в стек и чтения из стека регистра флагов:

Эти команды обычно используются для сохранения текущих состояний флагов и последующего их восстановления.

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

При работе со стеком необходимо помнить: если мы что-то записали в стек, то обязаны всё это считать из стека (сколько было команд PUSH, столько должно быть команд POP).

Дата добавления: 2014-11-09 ; Просмотров: 2326 ; Нарушение авторских прав?

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

Лабораторная работа «Команды пересылки данных. Стек.»

Как организовать дистанционное обучение во время карантина?

Помогает проект «Инфоурок»

Методические указания к выполнению лабораторных работ по МДК 01.01 «Системное программирование»

для специальности 09.02.03 «Программирование в компьютерных системах»

Лабораторная работа №3

Тема: «Команды пересылки данных. Стек.»

изучение режимов адресации;

изучение правил адресации при использовании регистров;

дать понятие о директивах определения данных;

понятие о стеке.

Изучить теоретическую часть

Выполнить задание в соответствии с указаниями

Ответить на контрольные вопросы

Предъявить преподавателю результаты работы: проект и исходный код

Оформить отчет в соответствии с ходом работы

Во всех 16-битовых ЭВМ принимаются какие-либо меры для расширения адресного пространства памяти, т.к 16-битовый адрес позволяет адресоваться только к 64кб. Память разбивается на сегменты размером до 64кб. По умолчанию каждый сегмент начинается с границы параграфа (фрагмента памяти размером в 16 б). Физический адрес в памяти складывается из начального адреса сегмента и 16-битового смещения (исполнительного адреса, ЕА) в пределах сегмента. Для получения физического начального адреса (ФА) содержимое сегментного регистра (начальный номер параграфа) умножается на 16, т.е дополняется справа четырьмя нулями:

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

Адресации обычно делят на 7 групп (способов адресации):

1) регистровая; 2) непосредственная; 3) прямая; 4)косвенная регистровая; 5) базовая; 6) прямая с индексированием; 7) адресация по базе с индексированием (базовая индексная).

Способы адресации приведены в табл.1

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

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

Команда копирует содержимое источника (или сам источник, если это непосредственный операнд). В приёмник. При этом источник не изменяется. Возможны различные комбинации операндов: регистр-регистр, регистр-память, память-регистр и т.д. нельзя копировать командой mov содержимое ячейки памяти в другую, т.е. недопустима команда

mov word ptr [200],[300]

примечание. Оператор PTR позволяет в одной команде изменить тип переменной, в качестве типа используется ключевые слова BYTE , WORD , DWORD .

Для этого придется воспользоваться каким-нибудь промежуточным регистром, лучше всего АХ.

Имеются также ограничения на операции пересылки с сегментными регистрами.

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

Под стек можно отвести область в любом месте памяти. Размер её может быть любым, но не должен превосходить 64кб, а её начальный адрес должен быть кратным 16. Другими словами, эта область должна быть сегментом памяти; он называется сегментом стека. Начало этого сегмента (первые 16 битов начального адреса) должно обязательно храниться в сегментном регистре SS .

Читать еще:  Методы адресации данных

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

Запись слова в стек: PUSH opt

Здесь opt обозначает любой 16-битовый регистр (в том числе и сегментный) или адрес слова памяти. По этой команде значение регистра SP уменьшается на 2 (вычитание происходит по модулю 2^16), после чего указанное операндом слово записывается в стек по адресу SS : SP .

Чтение слова из стека: POP op

Слово, считанное из вершины стека, присваивается операнду op (регистру, в том числе сегментному, но не CS , или слову памяти), после чего значение SP увеличивается на 2.

Другими словами , для реального режима процессора связка сегмента ss указателем sp. Для защищенного режима просто указатель sp указывает на вершину, следовательно, маневры с сегментом делать не нужно.

Итак, стек работает наоборот то есть с верху вниз.

Допустим, стек равен sp=20 после выполнения команды push ax он будит равен sp=18 и тд. пушим регистр dx и sp=16 при восстановление данных вынимаем все что засунули в обратном порядке так pop dx а затем только pop ax.

push ax ; сохранение данных регистра

push dx ; сохранение данных регистра

pop dx ; восстановление данных регистра

pop ax ; восстановление данных регистра

Т.е. когда мы что-нибудь «засовываем» в стек, указатель регистра sp значение уменьшается, а когда вытаскиваем – значение увеличивается, вытаскивать из стека данные нужно в обратной последовательности !

Адресация с примерами

В архитектуре МП 8086/8088 адрес любого байта задается двумя 16-битовыми словами — сегментом и смещением. При формировании 20-разрядного полного адреса, необходимого для адресации в пределах 1 Мбайт, сегмент сдвигается влево на 4 разряда (умножается на 16) и складывается со смещением. Поскольку емкость 16-разрядного смещения составляет 65536 значений, в пределах одного сегмента можно адресовать до 64 Кбайт.

Архитектура МП позволяет использовать семь различных способов адресации.

Извлекает операнд из регистра или помещает его в регистр. Примеры:

Операнд (8- или 16-разрядная константа) содержится непосредственно в теле команды. Примеры:

Смещение операнда задается в теле программы и складывается с регистром DS; например:

Исполнительный адрес операнда (точнее, его смещение) содержится в одном из регистров ВХ, ВР, SI или DI. Для указания косвенной адресации этот регистр должен заключаться в квадратные скобки, например:

Каждый из регистров BX. DI по умолчанию работает со своим сегментным регистром:

DS:BX, SS:BP, DS:SI, ES:DI

Допускается явное указание сегментного регистра, если он отличается от умалчиваемого, например:

Адресация по базе

Базовый регистр ВХ (или ВР) содержит базу (адрес начала некоторого фрагмента памяти), относительно которой ассемблер вычисляет смещение, например:

Один из индексных регистров SI или DI указывает положение элемента относительно начала некоторой области памяти. Пусть, например, АОВ — имя массива значений типа Byte. Тогда можно использовать такие фрагменты:

Адресация по базе с индексированием

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

Этот тип адресации удобен при обработке двумерных массивов. Если, например, АОВ есть массив из 10×10 байт вида

АОВ : array [0..9,0..9] of Byte;

то для доступа к элементу АОВ [2,3] можно использовать такой фрагмент

Задание 1. Подготовить измененное содержимое ds , es , ss . Написать нижеприведенную программу с именем lab 3. asm , сделать исполняемый файл, и проследить за работой в турбоотладчике.

На основе работы программы в таблице 2, в графы 2 и 3 занести ожидаемые значения операндов:

Вы можете выполнить задание с помощью программы Emu 8086. Дополнительная информация в файле ! Emu 8086. docx на сетевом диске.

Сколько режимов адресации существует, в чем разница?

Приведите общий формат команды определения данных программ на Ассемблере.

Назначение команды POP и PUSH , приведите общий формат команды, приведите пример использования этой команды.

Команды пересылки данных

Табл 2. Команды пересылки данных:

Команда

Описание

Действие

Циклы

Код операции

Флаги

ATtiny

ATmega

Move Between Registers

0010 11rd dddd rrrr

Copy Register Word

0000 0001 dddd rrrr

1110 KKKK dddd KKKK

1001 000d dddd 1100

Load Indirect and
Post-Inc.

1001 000d dddd 1101

Load Indirect and
Pre-Dec.

1001 000d dddd 1110

1000 000d dddd 1000

Load Indirect and
Post-Inc.

1001 000d dddd 1001

Load Indirect and
Pre-Dec.

1001 000d dddd 1010

Load Indirect with Displacement

10q0 qq0d dddd 1qqq

1000 000d dddd 0000

Load Indirect and
Post-Inc.

1001 000d dddd 0001

Load Indirect and
Pre-Dec.

1001 000d dddd 0010

Load Indirect with Displacement

10q0 qq0d dddd 0qqq

Load Direct from SRAM

1001 000d dddd 0000
kkkk kkkk kkkk kkkk

1001 001r rrrr 1100

Store Indirect and
Post-Inc.

1001 001r rrrr 1101

Store Indirect and
Pre-Dec.

1001 001r rrrr 1110

1000 001r rrrr 1000

Store Indirect and
Post-Inc.

1001 001r rrrr 1001

Store Indirect and
Pre-Dec.

1001 001r rrrr 1010

Store Indirect with Displacement

10q0 qq1r rrrr 1qqq

1000 001r rrrr 0000

Store Indirect and
Post-Inc.

1001 001r rrrr 0001

Store Indirect and
Pre-Dec.

1001 001r rrrr 0010

Store Indirect with Displacement

10q0 qq1r rrrr 0qqq

Store Direct to SRAM

1001 001r rrrr 0000
kkkk kkkk kkkk kkkk

Load Program Memory

1001 0101 1100 1000

Load Program Memory

1001 000d dddd 0100

Load Program Memory
and Post-Inc.

1001 000d dddd 0101

Extended Load
Program Memory

1001 0101 1101 1000

Extended Load
Program Memory

1001 000d dddd 0110

Extended Load Program Memory and Post-Inc.

1001 000d dddd 0111

Store Program Memory

1001 0101 1110 1000

1011 0PPd dddd PPPP

1011 1PPr rrrr PPPP

Push Register in Stack

1001 001r rrrr 1111

Pop Register from Stack

1001 000d dddd 1111

Группа команд пересылки данных сведена в табл.2. Под определением пересылки (перемещения) в данном случае понимается копирование содержимого источника без его изменения в приёмник. При этом ни одна из инструкций пересылок не влияет ни на какие флаги регистра состояния SREG. Множество возможностей адресации позволяют с одинаковым успехом обрабатывать как отдельные байты так и массивы данных. При этом часто существует несколько путей для реализации той или иной операции.

В пределах РОН пересылка производится с помощью команды mov Rd,Rr (Пересылка между регистрами). Кроме этого, имеется возможность перемещения двухбайтовых чисел (регистровых пар R1:R0, R3:R2,…, R29:R28, R31:R30) с помощью команды movw Rd,Rr (Пересылка между регистровыми парами), где на месте операндов Rd и Rr должны стоять младшие регистры в обозначениях регистровых парах приёмника и источника соответственно (например, movw R0, R30 для пересылки R1:R0 ← R31:R30). Обе эти команды выполняются за один машинный цикл:

Для загрузки константы в регистр служит команда с непосредственной адресацией ldi Rd,K (Загрузка константы в регистр). Она работает только со старшими РОНами (R16…R31).

Команды для работы с SRAM микроконтроллера используют, в основном, косвенную адресацию. Для этих целей применяются три 16-разрядных индексных регистра X,Y,Z, которые находятся в адресном пространстве РОН и по совместительству также являются регистровыми парами R27:R26, R29:R28, R31:R30.

Копировать байт из памяти ОЗУ в РОН можно любой из команд: ld Rd,X, ld Rd,Y, ld Rd,Z (Косвенное чтение из памяти данных). В этом случае в регистре приёмнике окажется содержимое ячейки памяти данных, адрес которой находится в одном из индексных регистров. Кроме этого, существует ещё две вариации данного действия. В одной из них после копирования производится инкрементирование регистров X,Y,Z, на что указывает знак “+” в командах: ld Rd,X+, ld Rd,Y+, ld Rd,Z+ (Косвенное чтение из памяти данных с постинкрементом). Во втором случае, перед пересылкой, содержимое индексного регистра сначала уменьшается на 1 (знак “-” в команде): ld Rd,-X, ld Rd,-Y, ld Rd,-Z (Косвенное чтение из памяти данных с преддекрементом).

Читать еще:  Какой можно написать адрес электронной почты

Команды косвенного чтения с постинкрементом/преддекрементом очень эффективны при работе с массивами однотипных данных. Для обращения же к элементам структуры (набору данных разного типа) удобно использовать ld Rd,Y+q, ld Rd,Z+q (Косвенное относительное чтение из памяти данных), в которых в качестве указателей используется Y,Z со смещением q (адрес ячейки памяти определяет сумма (Y)+q или (Z)+q). Смещение q в командах -фиксированная величина, лежащая в пределах 0…63.

Пересылка данных из РОН в ОЗУ посредством косвенной адресации реализуется с помощью команд: st X,Rr, st Y,Rr, st Z,Rr (Косвенная запись в память данных). Содержимое регистра в них копируется в ячейку памяти, адрес которой определяется указателями X,Y и Z соответственно. Точно также существуют команды загрузки с постинкрементом st X+,Rr, st Y+,Rr, st Z+,Rr (Косвенная запись в память данных с постинкрементом) и с преддекрементом индексного регистра st -X,Rr, st -Y,Rr, st -Z, Rr (Косвенная запись в память данных с преддекрементом). Ещё две команды этой группы используют косвенную адресацию со смещением: st Y+q,Rr, st Z+q,Rr (Косвенная относительная запись в память данных). Здесь смещение q может находится в пределах 0…63.

Как видно между командами выгрузки из памяти и загрузки в память существует полная симметрия. У каждой операции пересылки существует аналогичная, для пересылки в обратном направлении, причём с использованием трёх равноправных индексных регистров. Кроме того все они выполняются за один промежуток времени в 2 машинных цикла. Типичный пример их совместного использования может выглядеть следующим образом:

Копирование данных из ОЗУ в РОН и обратно может быть произведено и с использованием прямой адресации по командам lds Rd,k (Прямое чтение из памяти данных) и sts k,Rr (Прямая запись в память данных) соответственно. В этом случае двухбайтовый адрес k ячейки памяти находится в коде операции, а сами команды занимают 2 слова (4 байта) памяти программ.

Все вышеуказанные команды пересылок работают в едином адресном пространстве где под РОН отведены адреса 0x00…0x1F, под РВВ от 0x20…0x5F, остальное под ячейки ОЗУ. Поэтому, например, копирование R16←R17 может быть произведено разными путями: mov R16,R17, lds R16,0x0011, ld R16,X (в регистре X адрес 0x0011) и т.д. Первый способ здесь, конечно, более предпочтительный (использует пересылку типа регистр-регистр и выполняется быстрее), но остальные команды позволяют получить доступ к произвольному элементу любой области памяти и поэтому очень универсальны.

Для обращения к РВВ служат команды: in Rd,P (Ввод из порта), out P,Rr (Вывод в порт). Первая считывает значение РВВ в один из РОНов, а вторая производит пересылку РОН в РВВ.

Поскольку напрямую модифицировать РВВ невозможно, приходится сначала копировать их содержимое в рабочие РОН, производить необходимые изменения, а потом заносить обратно:

Тоже самое относится и к данным, расположенным в ОЗУ:

В группе команд пересылки данных имеются две, специально разработанные для работы со стеком. Это push Rr (Сохранение в стеке) и pop Rd (Извлечение из стека). Не смотря на то, что основное назначение стека это сохранение адресов возврата при вызове подпрограмм, эти инструкции позволяют использовать его и для оперативного сохранения данных, находящихся в РОН. Командой push Rr содержимое регистра копируется в ячейку памяти (вершину стека), адрес которой содержится в указателе стека SP, после чего значение SP уменьшается на 1. По команде pop Rd указатель стека возвращается на предыдущий элемент (SP+1), а значение, байта записанное по этому адресу копируется в регистр.

Таким образом реализуется память магазинного типа, где вообще не надо заботиться о задании адресов сохраняемых и восстанавливаемых из в памяти ОЗУ данных. Единственное, про что всегда необходимо помнить, — это порядок доступа к элементам стека Last In First Out (Последний Вошел Первый Вышел). Очередность, в которой регистры восстанавливаются из стека, должна быть обратной по отношению к очередности сохранения регистров:

Имеется и другая возможность программно реализовать стек данных. Команды ld Rd,X+, ld Rd,Y+, ld Rd,Z+ по сути являются иной реализацией действия push Rr, а st -X,Rd, st -Y,Rd, st -Z, Rd подобны pop Rd. Разница состоит лишь в том, что в качестве индексного регистра выступает не SP, а один из регистров–указателей (X,Y,Z) и вершина стека перемещается в сторону увеличения адресов ОЗУ:

Учитывая то, что SP расположен в пространстве РВВ, а X,Y,Z в РОН, использование эмуляции стека может быть даже более предпочтительной. Регистры X,Y,Z могут быть быстрей модифицированы и кроме того отсутствует опасность повредить их содержимое при вызове подпрограмм и возникновении прерываний.

Подобно большинству микроконтроллеров, у AVR имеется возможность хранения таблиц констант в памяти программ. Для их чтения разработаны команды lpm (Загрузка памяти программ), lpm Rd,Z (Загрузка памяти программ), lpm Rd,Z+ (Загрузка памяти программ с постинкрементом). Все они переписывают содержимое байта из FLASH памяти программ (адрес байта находится в Z) в один из РОН. С помощью первой инструкции, не имеющей параметров, копирование производится в R0. Вторая и третья модификации команды используют в качестве приёмника любой РОН. Команда lpm Rd,Z+ при этом осуществляет ещё и инкрементирование индексного регистра Z после считывания. Типичный пример копирования строки из памяти программ в ОЗУ может выглядеть следующим образом:

Здесь последовательно осуществляется считывание строки «Hello World !» (13 байт в кодировке ASCII) расположенной в памяти программ начиная с адреса 0x1000 (задан директивой .org 0x1000). Для резервирования FLASH памяти используется директива ассемблера .db, после которой непосредственно следуют данные. Строка переписывается в ОЗУ по адресу buffer.

Есть два важных момента при использовании операций такого типа. В приведённом выше фрагменте программы в качестве указателя на строку в индексный регистр Z заносится удвоенный адрес метки 2*string и это не случайность. Дело в том, что метке string соответствует адрес слова программ 0x1000. Но слово программ у AVR имеет блину 2 байта, а в указатель Z необходимо занести именно адрес байта т.е. 2*0x1000 = 0x2000. По той же причине в памяти программ необходимо выделять только чётное (кратное двум) количество байтов и если это не так, то надо добавлять незначащий байт 0 в самом конце, как это и случилось в нашем примере (строка «Hello World !» содержит 13 байт). Попутно заметим, что строки символов ASCII, как правило, и хранят в таком формате (добавляют в конце 0). Это позволяет автоматически распознавать конец строки и считывать, не зная заранее её длины.

Использование 2-байтового регистра Z позволяет адресовать только 64 кб при считывании памяти программ. Этого явно недостаточно для тех моделей AVR, которые имеют 128 и 256 кб FLASH-памяти. Для того чтобы работать во всём диапазоне адресов к указателю Z в этом случае добавляется регистр RAMPZ из пространства РВВ, в котором используются 1 или 2 младших бита. Этот 3-байтовый индексный регистр RAMPZ:ZH:ZL используют инструкции elpm (Расширенная загрузка памяти программ), elpm Rd, Z (Расширенная загрузка памяти программ), elpm Rd,Z+ (Расширенная загрузка памяти программ с постинкрементом).

Последняя инструкция в группы команд пересылки spm (Запись памяти программ). Она реализует возможность самопрограммирования микроконтроллеров AVR. Конкретное действие, которое выполняет эта команда, зависит от установок в управляющем РВВ SPMCSR. Это может быть стирание страницы памяти программ, занесение данных для записи во временный буфер или копирование буфера в память программ, а также чтение ячеек идентификаторов и защиты. В любом случае для задания адреса области используется указатель Z, а данные, если они необходимы, передаются в регистровой паре R1:R0. Так как действие данной инструкции связано с модификацией программного кода, для ее корректного применения предпринят ряд мер предосторожности, о чём подробно будет сказано в разделе “Самопрограммирование микроконтроллеров AVR”.

Ссылка на основную публикацию
Adblock
detector