Чтение онлайн

на главную - закладки

Жанры

Разработка ядра Linux (Второе издание)
Шрифт:

typedef signed long s64;

typedef unsigned long u64;

Для 32-разрядной машины их можно определить, как показано ниже.

typedef signed char s8;

typedef unsigned char u8;

typedef signed short s16;

typedef unsigned short u16;

typedef signed int s32;

typedef unsigned int u32;

typedef signed long long s64;

typedef unsigned long long u64;

Знак

типа данных
char

В стандарте языка С сказано, что тип данных

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

Для большинства аппаратных платформ тип

char
является знаковым, а диапазон значений данных этого типа от -128 до 127. Для небольшого количества аппаратных платформ, таких как ARM, тип
char
по умолчанию без знака, а возможные значения данных этого типа лежат в диапазоне от 0 до 255.

Например, для систем, на которых тип

char
без знака, выполнение следующего кода приведет к записи в переменную
i
числа 255 вместо -1.

char i = -1;

На других машинах, где тип

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

signed char i = -1;

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

char
, то следует помнить, что этот тип может на самом деле быть как
signed char
, так и
unsigned char
. Если необходим строго определенный вариант, то это нужно явно декларировать.

Выравнивание данных

Выравнивание (alignment) соответствует размещению порции данных в памяти. Говорят, что переменная имеет естественное выравнивание (naturally aligned), если она находится в памяти по адресу, значение которого кратно размеру этой переменной. Например, переменная 32-разрядного типа данных имеет естественное выравнивание, если она находится в памяти по адресу, кратному 4 байт (т.е. два младших бита адреса равны нулю). Таким образом, структура данные размером 2n байт должна храниться в памяти по адресу, младшие n битов которого равны нулю.

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

Как

избежать проблем с выравниванием

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

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

char dog[10];

char *p = &dog[1];

unsigned long l = *(unsigned long*)p;

В этом примере указатель на данные типа

unsigned char
используется, как указатель на тип
unsigned long
, что может привести к тому, что 32-разрядное значение типа
unsigned long
будет считываться из памяти по адресу, не кратному четырем.

Если вы думаете: "Зачем мне это может быть нужно?", то вы, скорее всего, правы. Тем не менее, если мы такое сделали только что, то такое можно сделать и кто-нибудь еще, поэтому необходимо быть внимательными. Примеры, которые встречаются в реальной жизни, не обязательно будут так же очевидны.

Выравнивание нестандартных типов данных

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

• Выравнивание массива выполняется так же, как и выравнивание типа данных первого элемента (все остальные элементы будут корректно выровнены автоматически).

• Выравнивание объединения (union) соответствует выравниванию самого большого, по размеру, типа данных из тех, которые включены в объединение.

• Выравнивание структуры соответствует выравниванию самого большого, по размеру, типа данных среди типов всех полей структуры.

В структурах также могут использоваться различные способы заполнения (padding).

Заполнение структур

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

struct animal_struct {

 char dog; /* 1 байт */

 unsigned long cat; /* 4 байт */

 unsigned short pig; /* 2 байт */

 char fox; /* 1 байт */

};

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

Поделиться:
Популярные книги

Законы Рода. Том 10

Андрей Мельник
10. Граф Берестьев
Фантастика:
юмористическая фантастика
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 10

Соль этого лета

Рам Янка
1. Самбисты
Любовные романы:
современные любовные романы
6.00
рейтинг книги
Соль этого лета

Доверься мне

Кажанова Юлия
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Доверься мне

Зауряд-врач

Дроздов Анатолий Федорович
1. Зауряд-врач
Фантастика:
альтернативная история
8.64
рейтинг книги
Зауряд-врач

Идеальный мир для Лекаря 29

Сапфир Олег
29. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 29

В погоне за женой, или Как укротить попаданку

Орлова Алёна
Фантастика:
фэнтези
6.62
рейтинг книги
В погоне за женой, или Как укротить попаданку

Плохой парень, Купидон и я

Уильямс Хасти
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Плохой парень, Купидон и я

Достигая Вершин

ZerKo
1. Достигая Вершин
Фантастика:
фэнтези
5.00
рейтинг книги
Достигая Вершин

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

Идеальный мир для Лекаря 12

Сапфир Олег
12. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 12

Лейтенант космического флота

Борчанинов Геннадий
1. Звезды на погонах
Фантастика:
боевая фантастика
космическая фантастика
космоопера
рпг
фэнтези
фантастика: прочее
5.00
рейтинг книги
Лейтенант космического флота

Громовая поступь. Трилогия

Мазуров Дмитрий
Громовая поступь
Фантастика:
фэнтези
рпг
4.50
рейтинг книги
Громовая поступь. Трилогия

Часовое имя

Щерба Наталья Васильевна
4. Часодеи
Детские:
детская фантастика
9.56
рейтинг книги
Часовое имя

Командир Красной Армии

Поселягин Владимир Геннадьевич
1. Командир Красной Армии
Фантастика:
попаданцы
8.72
рейтинг книги
Командир Красной Армии