Якщо 32- бітний процесор може обробляти приблизно 4 ГБ оперативної пам’яті (тобто ) байтів, чому мій Arduino Mega 2560 має 8 KiB SRAM, якщо 8- бітний процесор дозволяє йому обробляти всього 256 байт ( )? Або я читаю наступну сторінку неправильно?2 8
Якщо 32- бітний процесор може обробляти приблизно 4 ГБ оперативної пам’яті (тобто ) байтів, чому мій Arduino Mega 2560 має 8 KiB SRAM, якщо 8- бітний процесор дозволяє йому обробляти всього 256 байт ( )? Або я читаю наступну сторінку неправильно?2 8
Відповіді:
Більшість 8-бітних процесорів мають 16-бітні адресні шини, що дозволяють їм адресувати 64 кбайт саме тому, що 256 байт насправді недостатньо, щоб зробити дуже багато! Це просто означає, що їм потрібно завантажити два байти замість одного, кожен раз, коли їм потрібно завантажити адресу. Трохи повільніше, але терпимо, враховуючи їх розмір.
(І так, існує багато винятків, які в основному розроблялися, коли 64k стали занадто маленькими, але тут ми говоримо про основну ідею).
Адреса шини і шини даних розділені таким чином , вони можуть мати різні розміри. Для будь-яких конкретних розмірів адресної шини існує багато методів для адреси більшої кількості пам'яті, ніж ширина біта регістра
Найпоширеніший спосіб - якось збільшити ширину адресної шини
використовуючи кілька регістрів для адреси
X
, Y
і Z
дані адресації регістрів , щоб забезпечити максимальну 64KB оперативної пам'яті. Ті , в свою чергу , можуть бути з'єднані з RAMPX
, RAMPY
, RAMPZ
щоб отримати доступ до більш високим адресами ОЗУ в ще більші версії. Він також має SPH
високі байти покажчика стека на додаток до SPL
варіантів з більш ніж 256 байтами оперативної пам’яті 1H
& L
, B
& C
, D
&, E
які можна використовувати разом як 16-бітний регістр адресвикористовуючи єдиний великий спеціальний регістр, більший за натуральний розмір для адресації
використовуючи спеціальний реєстр для високої частини адреси . Звертаючись до деякої пам’яті, за замовчуванням 8 низьких бітів адреси будуть взяті з 8-бітового негайного або 8-бітного регістра на 8-бітовому мікроконтролері, тоді як високі біти будуть замінені значенням регістра іншої адреси.
call
або goto
вказівці 8 або 9 малих бітів адреси вказується негайно, а решта береться з поточного лічильника програми. Таким чином, для доступу до чогось недалеко від поточного сегмента використовується лише 1 інструкція, тоді як для подальших адрес потрібні 2 вказівки (щоб встановити високі біти).PC
коли беззастережно стрибає.Ще один спосіб досягти цього - банкінг пам'яті . Це корисний метод, який досі використовується в деяких архітектурах. У цій моделі пам'ять поділяється на кілька банків . Щоразу можна звертатися лише до певного банку. Часто існує глобальний банк або діапазон адрес, які завжди видно в будь-який час, але для інших частин ви повинні переключити банк, коли це необхідно.
Існує також не зовсім поширена методика, але її можна знайти в Intel 8051 . Як мікроконтролер з 8-бітовою адресою даних, він може мати не більше 256 адрес. Половина простору (висока частина) використовується для реєстрів спеціальних функцій ( SFR ), обмежуючи реальну оперативну пам'ять, адресовану лише 128 байтами. Однак виробники сучасних серій 8051 знайшли розумний спосіб подолати це, розділивши доступ до пам'яті . Пряма адресація отримає доступ до SFR, тоді як непряма адресація, хоча регістри отримають доступ до високої частини ОЗУ, тобто зараз у вас 256 + 128 = 384 адресних байтів.
1 https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set#Memory_addressing_instructions
Найменші ядра мають ≤256 байт адресного простору даних (тобто ≤128 байт оперативної пам’яті після видалення портів вводу-виводу та інших зарезервованих адрес) та ≤8192 байт (8 KiB) програмного ПЗУ. Вони мають лише 8-бітний покажчик стека (у SPL) і підтримують лише 12-бітні інструкції щодо переходу / виклику RJMP / RCALL. (Оскільки лічильник програм AVR налічує 16-бітні слова, а не байти, 12-бітове зміщення достатньо для адреси 213 байт ПЗУ.)
Для доступу до наявних ресурсів наявні додаткові можливості адреси пам'яті:
- Моделі з> 256 байтами адресного простору даних (≥256 байт оперативної пам’яті) мають 16-бітний покажчик стека, з високою половиною в регістрі SPH.
- Моделі з> 8 KiB ПЗУ додають 2-слові (22-бітні) інструкції JUMP та CALL. (Деякі ранні моделі страждають від помилок, якщо за пропускною інструкцією слідує 2-словечна інструкція.)
- Моделі з> 64 KiB ПЗУ додають інструкцію ELPM та відповідний регістр RAMPZ. Інструкції LPM з нульовим розширенням адреси ROM в Z; Інструкції ELPM додають регістр RAMPZ для високих бітів. Це не те саме, що більш загальна інструкція LPM; існують "класичні" моделі з лише нульовою операндною формою ELPM (ATmega103 та at43usb320). Коли функція автоматичного збільшення (більшість моделей) доступна, вона оновлює всю 24-бітну адресу, включаючи RAMPZ.
- (Рідкісні) моделі з> 128 КБ ПЗУ мають 3-байтний програмний лічильник. Виклики та повернення підпрограми використовують додатковий байт простору стека, є новий реєстр EIND для надання додаткових високих бітів для непрямих стрибків та викликів, є нові розширені інструкції EIJMP та EICALL, які використовують EIND: Z в якості адреси призначення. (У попередніх інструкціях IJMP та ICALL використовується розширений нуль Z.)
- (Рідкісні) моделі з адресним простором> 64 KiB оперативної пам’яті RAM розширюють обмеження адресності 16-бітної оперативної пам’яті за допомогою регістрів RAMPX, RAMPY, RAMPZ та RAMPD. Вони забезпечують додаткові високі біти для адресних режимів, у яких використовуються регістри X, Y або Z відповідно або інструкції прямої адреси LDS / STS. На відміну від доступу до ROM, немає чітких "розширених" інструкцій; натомість регістри RAMP використовуються беззастережно.
Майже всі 8-бітні процесори мають певну здатність формувати 16-бітну адресу з частини низького порядку та частини високого порядку. У деяких процесорах, включаючи оригінальний 8080, є регістри, призначені для утримання верхньої та нижньої частини адреси (хоча, з точки зору програміста, можуть бути деякі регістри, наприклад, покажчик стека 8080, які не пропонують інструкцій окремо їх вирішувати). У деяких інших процесорах відсутні регістри, присвячені верхній або нижній половині адреси, але адреси збираються "на ходу". Наприклад, на 6502 інструкція "LDA $ 1234, X" завантажує акумулятор адресою, утвореною додаванням $ 1234 до 8-бітного реєстру X [припустимо, він містить $ F0]. Виконання цієї інструкції проходитиме в 4 або 5 кроків:
Передача байта читання на акумулятор перекриє отримання наступної інструкції. Крім того, для багатьох операцій, якщо на етапі 3 не було створено перенесення, на кроці 4 було б прочитано правильну адресу, а виконання могло б перейти безпосередньо з кроку 4 до наступної інструкції, минаючи етап 5.
Якщо вивчити послідовність операцій, ви помітите, що архітектура маленького ендіану має певну перевагу перед архітектурою з великим ендіаном, в тому, що в більшості випадків (хоч і не показана), хоча ALU вимагає циклу виконання Крім того, можна прочитати байт з обчисленої адреси, не чекаючи результату ALU, оскільки зазвичай високий байт, який було отримано, буде високим байтом цільового операнда. На великій ендіанській машині з 8-бітовою АЛУ індексоване навантаження зайняло б щонайменше 5 циклів (оскільки нижня половина адреси не буде прочитана до кроку 3, і, таким чином, буде обчислена на кроці 4).
Лінії шини даних (шпильки) та рядки адреси (шпильки) абсолютно окремі. Простіше кажучи, рядки шини даних визначають максимальну кількість бітів, які можна передавати по одному (і зберігати в пам'яті), тоді як адреси адрес визначають максимальну кількість "комірок" пам'яті, які можна вибрати.
Це здебільшого маркетингова річ, що 32-розрядні процесори x86 не могли зайняти більше 4 Гб оперативної пам'яті. Я десь пам’ятаю, що на процесорах Pentium 4 були штифти A33-34.
Часто буває вірно, що існує певний взаємозв'язок між розміром адресної пам'яті та розміром внутрішнього реєстру, хоча ці відносини відрізняються з різних причин. 256 байт адресного простору вважалося занадто малим ще в перші дні мікропроцесорів, тому більшість восьми бітових процесорів виробляли 16-бітові (два байтові) адреси, що стосувалися 64 кілобайт. Хоча з комутацією банків (по суті, використовуючи певні лінії вводу / виводу для отримання ще більшої кількості адресних рядків), можна було отримати набагато більше.
У перших 16 та 32-бітових процесорах не завжди було достатньо штифтів на пристрої, щоб дістати весь простір, на який могли б звертатися їхні внутрішні регістри адрес. Наприклад, у Motorola 68000 було достатньо адресних штифтів (24) для адреси 16 мегабайт оперативної пам’яті, хоча внутрішні регістри адрес були шириною 32 біти.
Я відповім на це питання спеціально для контролерів AVR, які ви згадали. Основний принцип справедливий і для багатьох інших 8-бітних архітектур.
AVR - це 8-бітні ядра. Це означає, що у них є 8-бітні регістри. Однак 8 біт недостатньо для доступу до потрібного обсягу пам'яті. Отже, ядро AVR здатне використовувати певний набір регістрів, об'єднаних як 16-бітові регістри вказівників. Приклади для цього є регістри r30 та r31 (також відомі як ZL та ZH). Разом вони утворюють покажчик Z.
Зчитування байта за адресою 0x1234 виглядатиме так:
ldi ZL, 0x34 ; Load r30 (ZL) with low byte of address
ldi ZH, 0x12 ; Load r31 (ZH) with high byte of address
ld r16, Z ; Load byte to r16
Сім'я AVR має 3 регістрові пари, які можна використовувати для цього. Вони спеціально розроблені в апараті, щоб дозволити такі операції.
Під час програмування на мові вищого рівня, як на C, компілятор обробляє цей матеріал.
Примітка: Деякі AVR підтримують навіть більші розміри пам'яті, ніж 64 Кб. Ці контролери мають спеціальний регістр функцій, в який записуються додаткові біти адреси перед доступом. Тому адреса складається з наступних бітів (MSB до LSB):
Реєстр спеціальних функцій (зазвичай 1 байт), ZH (8 біт), ZL (8 біт).
8-бітний AVR Atmel фактично використовує 16-бітну адресу даних. Є безліч інших 16-бітових регістрів і навіть 16-бітових таймерів. Оскільки це лише 8-бітний процесор, він зазвичай використовує два тактових цикли для завантаження 16-бітного регістра.
Вікіпедія пояснює це досить добре:
Вісім-бітні процесори використовують 8-бітну шину даних і тому можуть отримати доступ до 8 бітів даних в одній машинній інструкції. Адресна шина, як правило, подвійний октет шириною (тобто 16-бітною) через практичні та економічні міркування. Це означає, що для більшості 8-бітних процесорів прямий адресний простір становить всього 64 Кб.
Поняття про те, що "бітова ширина" процесора встановлює максимальний об'єм оперативної пам'яті, на який процесор може звернутися, є одним з найбільш розповсюджених міфів в обчислювальних технологіях. Насправді галузева історія просто всіяна процесорами, для яких такі відносини не дотримувалися.
HP 21MX, HP 1000: 16-бітний процесор, пам'ять до 16 Мб
PDP-11: 16-бітний процесор, пам'ять до 4 Мб
VAX-11/780: 32-бітний процесор, пам'ять до 512 Мб
тощо, тощо.