Розмір машинного слова та типи даних

Машинне слово (word) – це кількість даних, які процесор може обробити за одну операцію Тут можна застосувати аналогію документа, що складається зсимволів (character,8 біт) історінок(Багато слів) Слово-це деяка кількість бітів, як правило 16, 32 або 64 Коли говорять про n-бітової машині, то найчастіше мають на увазі розмір машинного словаНаприклад, коли говорять, що процесор Intel Pentium – це 32-розрядний процесор, то зазвичай мають на увазі розмір машинного слова, рівний 32 біт, або 4 байт

1 Це нормальна ситуація при розробці ядра Якщо що-небудь має бути зроблено, то це має бути зроблено добре Розробники ядра неохоче переписують великі ділянки коду навіть під імя досконалості

Розмір процесорних регістрів загального призначення дорівнює розміру машинного слова цього процесора Зазвичай розрядність інших компонентів цієї ж апаратної платформи в точності дорівнює розміру машинного слова Крім того, принаймні для апаратних платформ, які підтримуються ОС Linux, розмір адресного простору відповідає розміру машинного слова2 Отже, розмір покажчика дорівнює розміру машинного слова На додаток до цього, розмір типу long мови С також дорівнює розміру машинного слова Наприклад, для апаратної платформи Alpha розмір машинного слова дорівнює 64 біт Отже, регістри, покажчики і тип long мають розмір 64 біт Тип in t для цієї платформи має розмір 32 біт Машини платформи Alpha можуть обробити 64 біт-одне слово за допомогою однієї операції

Слова, подвійні слова і плутанина

Для деяких операційних систем і процесорів стандартну порцію даних не називають машиннимсловомЗамість цього,словомназивається деяка фіксована порція даних, назва якої вибрано випадковим чином або має історичні корені Наприклад, в деяких системах дані можуть розбиватися на байти (byte – 8 біт), слова (word – 16 біт), подвійні слова (double word – 32 біт) і четверні слова (quad word – 64 біт), незважаючи на те що насправді система є 32-розрядної У цій книзі і взагалі в контексті операційної системи Linux під машинним словом розуміють стандартну порцію даних процесора, як обговорювалося раніше

Для кожної апаратної платформи, підтримуваної операційною системою Linux, у файлі визначається константа BITTS_PER_LONG, яка дорівнює розміру типу long мови С і збігається з розміром машинного слова системи Повний список всіх підтримуваних апаратних платформ і їх розміри машинного слова наведено в табл 191

Стандарт мови С явно вказує, що розмір памяті, яку займають змінні стандартних типів даних, залежить від апаратної реалізаціі3, при цьому також визначається мінімально можливий розмір типу Невизначеність розмірів стандартних типів мови С для різних апаратних платформ має свої позитивні і негативні сторони До плюсів можна віднести те, що для стандартних типів мови С можна користуватися перевагами, повязаними з розміром машинного слова, а також відсутність необхідності явної вказівки розміру Для ОС Linux розмір типу long гарантовано дорівнює розміру машинного слова Це не зовсім відповідає стандарту ANSI С, однак є стандартною практикою в ОС Linux Як недолік можна відзначити, що при розробці коду не можна розраховувати на те, що дані певного типу займають в памяті певний розмір Більш того, не можна гарантувати, що змінні типу int займають стільки ж памяті, скільки і змінні типу long4

2 Разме р Адресуємий ї памят і Може т побут ь меньш е максімальног про значени я машінног про слова Наприклад, для 64-розрядних апаратних платформ м розмі р покажчика поранений 64 біт, однак тільки

48 біт можна використовувати для адресації На додаток е до цього, загальна кількість физическо ї памяті може бути більше максимального значени я машинного слова, як, наприклад, пов про має місце при наявності расширени я Intel PAE

3 За винятком розміру типу char, якому й завжди дорівнює 8 біт

4 Насправді, для 64-розрядних апаратних платформ, які е підтримуються ОС Linux, розміри типів in t і lon g не збігаються Розмір тип а int дорівнює 32 біт, а розмір типу lon g – 64 біт Дл я хороший про знайомих 32-раphядних апаратних платформ м обидва типи даних мають розмі р 32 біт

Таблиця 191 Підтримувані апаратні платформи

Апаратна платформа Опис Розмір машинного слова

alpha arm cris h8300

I386

ia64 m68k m86knommu mips

mips64 parisc ppc ppc64 s390

sh spare sparc64 um

v850

x8_ 64

Digital Alpha

ARM і StrongARM CRIS

H8/300

Intel x86

IA-64

Motorola 68k

m68k без пристрою MMU MIPS

64-розрядна MIPS

HP PA-RISC PowerPC POWER

IBM S/390

Hitachi SH SPARC UltraSPARC Usermode Linux v850

X86-64

64 біт

32 біт

32 біт

32 біт

32 біт

64 біт

32 біт

32 біт

32 біт

64 біт

32 біт, або 64 біт

32 біт

64 біт

32 біт, або 64 біт

32 біт

32 біт

64 біт

32 біт, або 64 біт

32 біт

64 біт

Ситуація ще більше заплутується тим, що одні й ті ж типи даних в просторі користувача і в просторі ядра не обовязково повинні відповідати один одному Апаратна платформа sparc64 надає 32-розрядне простір користувача, а тому покажчики, типи in t і long мають розмір 32 біт Однак у просторі ядра для апаратної платформи розмір типу in t дорівнює 32 біт, а розмір покажчиків і типу long дорівнює 64 біт Проте така ситуація не є звичайною

Завжди необхідно памятати про наступне

• Як і вимагає стандарт мови С, розмір типу char завжди дорівнює 8 біт (1 байт),

• Немає ніякої гарантії, що розмір типу in t для всіх підтримуваних апаратних платформ буде дорівнює 32 біт, хоча зараз для всіх платформ він дорівнює саме цьому числу

• Те ж стосується і типу short, який для всіх підтримуваних апаратних платформ зараз дорівнює 16 біт

• Ніколи не можна сподіватися, що тип long або покажчик має деякий заданий розмір Цей розмір для підтримуваних апаратних платформ може дорівнювати 32, або 64 біт

• Оскільки розмір типу lon g різний для різних апаратних платформ, ніколи не можна припускати, що sizeo f (int) == sizeo f (long)

• Точно так само не можна припускати, що розмір типу int і розмір покажчика збігаються

Приховані типи даних

Приховані (opaque) типи даних – це ті типи, для яких не розкривається їх внутрішня структура, або формат Вони схожі начорний ящик,наскільки це можна реалізувати в мові програмування С У цій мові програмування немає будь-якої особливої ​​підтримки для цих типів Замість цього, розробники визначають новий тип даних через оператор typedef, називають його прихованим і сподіваються на те, що ніхто не буде перетворювати цей тип в стандартний тип даних мови С Будь-які використання даних цих типів можливі тільки через спеціальні інтерфейси, які також створюються розробником Прикладом може бути тип даних pid_t, в якому зберігається інформація про ідентифікатор процесу Розмір цього типу даних не розкривається, хоча кожен може смошеннічать, використовувати розмір по максимуму і працювати з цим типом, як з типом int Якщо ніде явно не використовується розмір прихованого типу даних, то розмір цього типу може бути змінений, і це не викличе жодних проблем Насправді так вже одного разу сталося: у старих Unix-подібних операційних системах тип pid_ t був визначений як ahort

Ще один приклад прихованого типу даних – це тип atomic_t Як вже обговорювалося в розділі 9, Засоби синхронізації в ядрі, цей тип містить дані целочисленного типу, з якими можна виконувати атомарні операції Хоча цей тип і відповідає типу int, використання прихованого типу даних дозволяє гарантувати, що дані цього типу будуть використовуватися тільки в спеціальних функціях, які виконують атомарні операції Приховані типи дозволяють приховати розмір типу даних, який не завжди дорівнює повним 32 розрядам, як у випадку платформи SPARC

Інші приклади прихованих типів даних в ядрі – це dev_t, gi d _t і uid_t При роботі з прихованими типами даних необхідно памятати про наступне

• Не можна припускати, що дані прихованого типу мають деякий певний розмір в памяті

• Не можна перетворювати прихований тип назад в стандартний тип даних

Розробляти код необхідно з урахуванням того, що розмір і внутрішнє подання прихованого типу даних можуть змінюватися

Спеціальні типи даних

Деякі дані в ядрі, крім того, що представляються за допомогою прихованих типів, вимагають ще й спеціальних типів даних Два приклади – лічильник імпульсів системного таймера jiffie s і параметр flags, використовуваний для обробки переривань Для зберігання цих даних завжди повинен використовуватися тип unsigne d long

При зберіганні і використанні специфічних даних завжди необхідно звертати особливу увагу на той тип даних, який представляє ці дані, і використовувати саме його Часто зустрічається помилкою є використання іншого типу, наприклад типу unsigne d int Хоча для 32-розрядних апаратних платформ це не призведе до проблем, на 64-розрядних системах виникнуть проблеми

Типи з явним зазначенням розміру

Часто при програмуванні необхідні типи даних заданого розміру Зазвичай це необхідно для задоволення деяких зовнішніх вимог, повязаних з апаратним забезпеченням, мережею або бінарної сумісністю Наприклад, звуковий адаптер може мати 32-розрядний регістр, пакет мережевого протоколу – 16-розрядне поле даних, а виконуваний файл 8 бітовий ідентифікатор cookie У цих випадках тип, який представляє дані, повинен мати точно заданий розмір

У ядрі типи даних явно заданого розміру визначені у файлі , який включається з файлу У табл 192 наведено повний список таких типів даних

Таблиця 192 Типи даних явно заданого розміру

Тип Опис

s8 u8 s16 ul6 s32 u32 s64 u64

байт зі знаком байт без знака

16-розрядне ціле число зі знаком

16-розрядне ціле число без знака

32-розрядне ціле число зі знаком

32-розрядне ціле число без знака

64-розрядне ціле число зі знаком

64-розрядне ціле число без знака

Варіанти сo знаком використовуються рідко

Ці типи даних, з явно заданим розміром, просто визначені за допомогою оператора typedef через стандартні типи даних мови С Для 64-розрядної машини вони можуть бути визначені таким чином

typedef signed char s8 typedef unsigned char u8 typedef signed short s16 typedef unsigned short ul6 typedef signed int s32 typedef unsigned int u32 typedef signed long s64 typedef unsigned long u64

Для 32-розрядної машини їх можна визначити, як показано нижче typedef signed char s8

typedef unsigned char u8 typedef signed short s16 typedef unsigned short ul6 typedef signed int s32 typedef unsigned int u32 typedef signed long long s64

typedef unsigned long long u64

Знак типу даних cha r

У стандарті мови С сказано, що тип даних cha r може бути зі знаком або без знаку Відповідальність за визначення того, який варіант типу даних cha r використовувати за замовчуванням, лежить на компіляторі, препроцесорів або на обох

Для більшості апаратних платформ тип cha r є знаковим, а діапазон значень даних цього типу від -128 до 127 Для невеликої кількості апаратних платформ, таких як ARM, тип cha r по замовчуванням без знака, а можливі значення даних цього типу лежать в діапазоні від 0 до 255

Наприклад, для систем, на яких тип cha r без знака, виконання наступного коду призведе до запису в змінну i числа 255 замість -1

char i = -1

На інших машинах, де тип cha r є знаковим, цей код виконається правильно і в змінну i запишеться значення -1 Якщо дійсно потрібно, щоб у будь-якому випадку було записано значення -1, То попередній код повинен виглядати наступним чином

signed char i = -1

Якщо у вашому коді використовується тип даних char, то слід памятати, що цей тип може насправді бути як signe d char, так і unsigne d char Якщо необхідний строго певний варіант, то це потрібно явно декларувати

Джерело: Лав, Роберт Розробка ядра Linux, 2-е видання : Пер з англ – М: ТОВ «ІД Вільямс »2006 – 448 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*