4926 subscribers

Микроконтроллеры для начинающих. Часть 8. Режимы адресации операндов

771 full read
2,8k story viewsUnique page visitors
771 read the story to the endThat's 27% of the total page views
6 minutes — average reading time

В предыдущих статьях мы познакомились с тем,какие типы памяти есть в микроконтроллерах и как эта память организована. Во внеплановой статье "Микроконтроллеры для начинающих. Часть 7. Внеплановая. Адресные пространства и шины" я более подробно, чем планировал ранее, рассказал об отличиях пространства памяти данных и пространства ввода-вывода.

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

Как уже говорилось ранее, машинные команды (инструкции) выполняются над операндами. Нас пока не будет интересовать, сколько именно операндов обрабатывает инструкция процессора. Будем разбираться, как указать процессору, где именно находятся обрабатываемые инструкцией данные.

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

Я абсолютно не рассчитываю, что вы будете писать на ассемблере. Во всяком случае, большинство будет использовать языки высокого ровня. Причем скорее всего это будет С. Хотя тут и возможны варианты. Но понимание способов адресации все таки полезно. Причем не только само по себе. Вместе с знанием машинных команд это поможет вам оценить эффективность различных компиляторов, на практике. А иногда и обнаружить ошибку в компиляторе, что иногда случается, к сожалению.

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

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

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

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

Неявная адресация

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

Кстати, в предыдущей статье я уже приводил пример неявной адресации, когда говорил о командах LD, ST, IN и OUT абстрактного микроконтроллера. Эти команды использовали в качестве одного из операндов регистр-аккумулятор (ACC), хоть он и указывался явно.

Пример выполнения инструкции IJMP (неявная адресация) микроконтроллеров линейки AVR Atmel. Регистр Z состоит из пары регистров R30 и R31. Содержимое регистра Z записывается в регистр PC. Ни один из этих регистров не указывается в команде в явном виде. Иллюстрация моя
Пример выполнения инструкции IJMP (неявная адресация) микроконтроллеров линейки AVR Atmel. Регистр Z состоит из пары регистров R30 и R31. Содержимое регистра Z записывается в регистр PC. Ни один из этих регистров не указывается в команде в явном виде. Иллюстрация моя
Пример выполнения инструкции IJMP (неявная адресация) микроконтроллеров линейки AVR Atmel. Регистр Z состоит из пары регистров R30 и R31. Содержимое регистра Z записывается в регистр PC. Ни один из этих регистров не указывается в команде в явном виде. Иллюстрация моя

PIC Microchip

В качестве примера неявной адресации в 8-битных микроконтроллерах Microchip можно указать команду CLRW (запись 0 в регистр WREG), которая не имеет явно заданных операндов, но буква W в названии команды все таки дает нам подсказку.

Другим примером может служить команда ADDWF, которая складывает содержимое WREG и указанной ячейки памяти данных. Здесь тоже WREG не задается в явном виде (и его нельзя ничем заменить), хоть в названии команды и присутствует буква W.

AVR Atmel (Microchip)

В качестве примера можно привести команду IJMP, которая не имеет явно заданных операндов. Это команда выполняет переход по адресу хранящемуся в регистре Z (16 разрядный регистр). Ни регистр Z, ни регистр PC (регистр адреса команды) здесь не указываются явно.

STM8

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

Непосредственная адресация

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

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

Причем это касается и случаев не абсолютного, а относительного перехода. Просто в этом случае константой будет не полный адрес, а смещение от адреса текущей выполняемой команды (смещение относительно PC).

Непосредственная адресация используется и для указания номера бита в байте для инструкций работающих с битами. Обратите внимание, что указание полного адреса бита, как это возможно в MCS-51, не является случаем непосредственной адресации!

Пример инструкций MOVLW и CALL  (PIC Microchip) использующих непосредственную адресацию. В первом случае в регистр WREG (неявная адресация) заносится константа 24 (шестнадцатиричная) заданная с помощью НЕПОСРЕДСТВЕННОЙ адресации. Во втором случае, в регистр PC (неявная адресация) заносится адрес первой команды процедуры Subr заданный с помощью НЕПОСРЕДСТВЕННОЙ адресации. Иллюстрация моя
Пример инструкций MOVLW и CALL (PIC Microchip) использующих непосредственную адресацию. В первом случае в регистр WREG (неявная адресация) заносится константа 24 (шестнадцатиричная) заданная с помощью НЕПОСРЕДСТВЕННОЙ адресации. Во втором случае, в регистр PC (неявная адресация) заносится адрес первой команды процедуры Subr заданный с помощью НЕПОСРЕДСТВЕННОЙ адресации. Иллюстрация моя
Пример инструкций MOVLW и CALL (PIC Microchip) использующих непосредственную адресацию. В первом случае в регистр WREG (неявная адресация) заносится константа 24 (шестнадцатиричная) заданная с помощью НЕПОСРЕДСТВЕННОЙ адресации. Во втором случае, в регистр PC (неявная адресация) заносится адрес первой команды процедуры Subr заданный с помощью НЕПОСРЕДСТВЕННОЙ адресации. Иллюстрация моя

Связь с языками высокого уровня

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

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

Точно так же, call subr(....) или variable=function(...) будет преобразовано в команду перехода, где адрес процедуры будет указан константой, с использованием непосредственной адресации.

PIC Microchip

В случае PIC числовая константа называется литералом. И в названии команды при этом присутствует буква L (литерал). В качестве примера приведу команду MOVLW, которая загружает литерал, явно указанный в команде, в регистр WREG (явно не указывается). Другим примером является команда RETLW, которая не просто возвращает управление в точку вызова процедуры, но и возвращает заданный литерал в регистре WREG.

Нельзя не упомянуть команду CALL, которая выполняет переход к процедуре по заданному адресу.

AVR Atmel (Microchip)

В качестве примера можно привести команду LDI, которая загружает константу в указанный регистр. Другим примером является команда ANDI, которая выполняет логическую операцию И между заданным регистром и константой.

В качестве примера команд перехода можно привести JMP (переход), CALL (вызов процедуры), RCALL (вызов процедуры относительно адреса выполняемой команды).

STM8

Непосредственную адресацию можно использовать во многих командах. Система команд у этих микроконтроллеров довольно гибкая. В качестве примера можно привести команды LD или ADD. В качестве команды перехода CALL включая (CALLR и CALLF) или BTJT.

Регистровая адресация

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

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

Пример выполнения инструкции LD (STM8), которая заносит шестнадцатиричную константу 10 (непосредственная адресация) в регистр А (аккумулятор) заданный с помощью РЕГИСТРОВОЙ адресации. Иллюстрация моя
Пример выполнения инструкции LD (STM8), которая заносит шестнадцатиричную константу 10 (непосредственная адресация) в регистр А (аккумулятор) заданный с помощью РЕГИСТРОВОЙ адресации. Иллюстрация моя
Пример выполнения инструкции LD (STM8), которая заносит шестнадцатиричную константу 10 (непосредственная адресация) в регистр А (аккумулятор) заданный с помощью РЕГИСТРОВОЙ адресации. Иллюстрация моя

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

Связь с языками высокого уровня

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

PIC Microchip

В этих микроконтроллерах даже внутренние регистры процессора отображаются на адресное пространство памяти данных. Другими словами, нет разницы между ячейками памяти данных и регистрами процессора. Исключение составляют регистры OPTION_REG и TRIS в линейке BaseLine, где для доступа к ним используют специальные команды (неявная адресация). Даже регистр WREG в линейке PIC18 получил свой адрес в пространстве памяти данных.

Получается, в этих микроконтроллерах регистровая адресация отсутствует? Не совсем так! В качестве примера приведу команду

ADDWF 0x31,W

Это команда складывает содержимое WREG и ячейки памяти с адресом 31. А вот результат операции будет помещен в регистр WREG, так как в качестве второго операнда указано W. То есть, это та самая регистровая адресацияю Но и тут не все так просто! Если вместо W, в качестве второго операнда указать F, то результат будет записан в ячейку памяти с адресом 31. То есть, регистровой адресации не будет.

Подробнее об этом будет сказано при рассмотрении системы команд PIC.

AVR Atmel (Microchip)

У этих микроконтроллеров можно указать один из регистров процессора в качестве операнда для многих команд. Например команда

SUB R3,R16

вычтет из содержимого регистра R16 содержимое регистра R3

STM8

У этих микроконтроллеров, как и у AVR Atmel, регистр в качестве операнда можно указать во многих инструкциях. Например,

SUBW X,$1234

Прямая адресация

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

В командах IN и OUT для указания номера порта (регистра) в адресном пространстве ввода-вывода тоже используется прямая адресация. Так как команды работать с содержимым указанного порта.

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

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

Пример выполнения команды MOVWF (PIC Microchip) выполняющей запись содержимого WREG (неявная адресация) в ячейку памяти с адресом 345 заданную с использованием ПРЯМОЙ адресации. Иллюстрация моя
Пример выполнения команды MOVWF (PIC Microchip) выполняющей запись содержимого WREG (неявная адресация) в ячейку памяти с адресом 345 заданную с использованием ПРЯМОЙ адресации. Иллюстрация моя
Пример выполнения команды MOVWF (PIC Microchip) выполняющей запись содержимого WREG (неявная адресация) в ячейку памяти с адресом 345 заданную с использованием ПРЯМОЙ адресации. Иллюстрация моя

Связь с языками высокого уровня

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

Микроконтроллеры

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

MCS-51

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

Косвенная адресация

При косвенной адресации мы указываем в команде адрес ячейки памяти, которая содержит адрес ячейки памяти, которая содержит данные. Кажется слишком сложным? На самом деле все просто.

Представьте себе несколько пронумерованных шкатулок, это и будет наша память. Теперь помести бумажку с написанным числом, например, 25 в шкатулку, например, номер 3. При прямой адресации мы можем сказать, что нужные нам данные (бумажка с числом 25) находятся в шкатулке 3. То есть, шкатулка 3 это и есть наш адрес.

Теперь возьмите другую бумажку и напишите на ней число 3. Положите эту бумажку в шкатулку, например, 8. Теперь мы можем использовать косвенную адресацию и сказать, что косвенный адрес нужной нам информации шкатулка 8.

Как мы будем теперь добираться до нужной нам информации? Мы откроем шкатулку 8 и увидим, что там лежит бумажка с числом 3. Теперь нам нужно открыть шкатулку 3, где и будет нужная нам информация (бумажка с числом 25).

Пример использования косвенной адресации ля микроконтроллера STM8. В данном случае в команде указан адрес адреса операнда 345 (шестнадцатиричный). В результате операции в регистр А (аккумулятор) будет загружено число 1234. Иллюстрация моя
Пример использования косвенной адресации ля микроконтроллера STM8. В данном случае в команде указан адрес адреса операнда 345 (шестнадцатиричный). В результате операции в регистр А (аккумулятор) будет загружено число 1234. Иллюстрация моя
Пример использования косвенной адресации ля микроконтроллера STM8. В данном случае в команде указан адрес адреса операнда 345 (шестнадцатиричный). В результате операции в регистр А (аккумулятор) будет загружено число 1234. Иллюстрация моя

Зачем такие сложности? Сейчас объясню.

Связь с языками высокого уровня

Предположим, что у нас есть такая программа на языке С

int val=1234;
int dst;
int *ptr;
ptr=&val;
dst=*val;

Предположим теперь, что у нас компилятор разместил переменную val по адресу 0х510, а переменную ptr по адресу 0х345. Стало похоже на то, что показано на иллюстрации? Если принять, что переменная dst у нас, пусть и временно, разместилась в аккумуляторе, то мы получим полное соответствие фрагмента нашей программы и иллюстрации!

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

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

PIC Microchip

Микроконтроллеры PIC не поддерживают косвенную адресацию в том виде, как я здесь показал. Однако, они поддерживают индексную адресацию, о которой речь пойдет дальше. Правда тоже не в полном объеме.

AVR Atmel (Microchip)

Микроконтроллеры Atmel не поддерживают косвенную адресацию в том виде, как я здесь показал. Не смотря на то, что в документации термин "косвенная адресация" используется. Но, как станет видно далее, под "косвенная" подразумевается "индексная", которую я буду рассматривать следующей. Так что, как и PIC, они поддерживают индексную адресацию. Причем в более широком виде, чем PIC.

STM8

Микроконтроллеры STM8 поддерживают косвенную адресацию почти в полном объеме. Я не зря использовал этот микроконтроллер для иллюстрации. Ограничения касаются сочетаний разрядности адреса и разрядности данных. Но об этом будет отдельный разговор, и в отдельной статье.

Индексная адресация

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

Пример индексной адресации в микроконтроллере AVR Atmel. Индексный регистр Х содержит адрес ячейки памяти, содержимое которой будет загружено в регистр R1. Иллюстрация моя
Пример индексной адресации в микроконтроллере AVR Atmel. Индексный регистр Х содержит адрес ячейки памяти, содержимое которой будет загружено в регистр R1. Иллюстрация моя
Пример индексной адресации в микроконтроллере AVR Atmel. Индексный регистр Х содержит адрес ячейки памяти, содержимое которой будет загружено в регистр R1. Иллюстрация моя

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

Связь с языками высокого уровня

Пусть у нас имеется такой фрагмент программы

char str[]="test";
char *ptr;
ptr=str;
for(int i=0; i<4; i++) outch(*ptr++);

Как я показывал в выше, компилятор использует для переменной ptr косвенную адресацию. Однако, можно (возможно, но не обязательно) ускорить работу программы и уменьшить объем занимаемой программой памяти (тоже не обязательно), если поместить переменную ptr не в память данных, а в индексный регистр.

Остается вопрос с операцией инкремента (++). Но и это в некоторых микроконтроллерах учтено. Так в микроконтроллерах AVR Atmel есть индексная адресация с автоинкрементом (post increment) и автодекрементом (pre decremernt). Я не буду показывать это на иллюстрации, так данная тонкость сути режима адресации не меняет.

Однако, обратите внимание! Понимание сути режимов адресации помогает писать программы на языках высокого уровня более эффективно. Так в данном случае использование ptr++ позволит компилятору сгенерировать код с использованием индексной адресации с автоматическим инкрементом, выполняемым той же самой командой. А вот использование ++ptr потребует отдельной команды для увеличения значения ptr. Причина проста, есть адресация с post increment (увеличение после использования), но не адресации с pre increment (увеличение перед использованием). С декрементом ситауция обратная.

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

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

PIC Microchip

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

В этих микроконтроллерах есть регистры с общим названием FSR (File Select Register). Одной из функций этого регистра как раз и является участие в индексной адресации. То есть, адрес нужной переменной помещается в этот регистр. Но вот для использования индексной адресации мы должны в команде указать совершенно иной регистр, INDF!

То есть, команда с индексным режимом адресации будет выглядеть, например, так

MOVWF INDF

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

Автоматического инкремента и декремента в данном случае не предусмотрено.

AVR Atmel (Microchip)

Этот микроконтроллер я не только использовал для иллюстрации, но и описал некоторые тонкости его режима индексной адресации. Поэтому добавить можно лишь то, что есть три индексных регистра Х, Y и Z. И есть возможность использовать их, в том числе, для доступа (на чтение) памяти команд.

STM8

Имеется два индексных регистра X и Y. Автоинкремент и автодекремент не предусмотрен.

Индексная адресация со смещением

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

Всем хорош индексный режим адресации, однако там требуется указывать полный адрес ячейки памяти. Не зря в примере на языке высокого уровня использовал указатель ptr для доступа к массиву символов, вместо str[i]. Это ограничение не очень критично, но хотелось бы семантической красоты... И такая возможность есть.

Пример индексной адресации со смещением для STM8. Здесь str это адрес начала массива str в памяти (адрес первого элемента массива). Индексный регистр X содержит индекс элемента в массиве (в данном случае str[2]). Иллюстрация моя
Пример индексной адресации со смещением для STM8. Здесь str это адрес начала массива str в памяти (адрес первого элемента массива). Индексный регистр X содержит индекс элемента в массиве (в данном случае str[2]). Иллюстрация моя
Пример индексной адресации со смещением для STM8. Здесь str это адрес начала массива str в памяти (адрес первого элемента массива). Индексный регистр X содержит индекс элемента в массиве (в данном случае str[2]). Иллюстрация моя

Связь с языками высокого уровня

Давайте немного изменим наш пример для индексной адресации

char str[]="test";
for(int i=0; i<4; i++) outch(str[i]);

По сути, изменилось мало что. Результат работы этого врагмента будет таким же, как и предыдущего. Но вот работа с массивом гораздо привычнее для тех, кто не привык работе с указателями. Именно этот фрагмент программы показан на иллюстрации (для момента времени, когда i=2).

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

PIC Microchip

Нечто похожее на описанный режим адресации есть только в семействе PIC18, причем только при работе в режиме расширенного набора инструкций (поддерживается далеко не всеми компиляторами, даже коммерческими, даже официальным XC8). При этом должен использоваться access банк памяти и прямой режим адресации, где адрес не превышает 5F. В этом случае итоговый адрес ячейки памяти получится сложением адреса в команды и содержимого регистра FSR. Вот такие там сложности.

AVR Atmel (Microchip)

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

STM8

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

Косвенная индексированная адресация

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

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

Связь с языками высокого уровня

Это самый сложный режим адресации из всех описанных в статье. Аналогией в языках высокого уровня является массив массивов. Например, массив строк. Более подробно я не буду описывать, статья и так получилась очень большой и тяжелой. Но те, кто писал программы на С для ПК, которые получали параметры через командную строку при запуске, без сомнения поймут, о чем идет речь.

Заключение

Поажлуй, на сегодня точно достаточно. Статья очень большая и, скорее всего, окажется трудной для понимания некоторыми читателями. При этом я впервые рассматривал не абстрактные модели, а рельные микроконтроллеры. Так что статья сугубо прикладная. И очень важная.

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

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

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

Я еще не решил, с какой именно линейки микроконтроллеров начну. Но продолжение точно будет! А после этого мы перейдем к изучения системы команд. Будет сложно, но интересно.

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

До новых встреч!