2013-03-30 3 views
2

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

typedef struct 
{ 
    int b1 : 1; 
    int b2 : 1; 
    .. 
    .. 
    .. 
    int b32 : 1; 
} bitfield32; 

Мы также не можем сделать битовое поле, как это, которое больше, чем любого примитивного типа. Так почему же ограничения? Это можно сделать в сборке?

+0

Мы можем, не проблема. причина, по которой мы не являемся, потому что это непрактично. В вычислительном мире использовались 9-битные байт-байты 36-битных слов или двойных слов, все были восьмеричными людьми, которые считались в единицах из 3 бит, как обычно, сейчас в единицах из четырех бит, hex. x86 и другие аналогичные старые архитектуры выполняли бы 4-битную математику, BCD, с 4-битным переносным битом и т. д.это просто не практично. Мир действительно не байт, основанный либо на наименьших единицах памяти, которые чаще всего видны на 64 бита, а на 32 бита. байты являются иллюзией по большей части ... –

+0

Вы используете 64 или 32-битные регистры и шины данных все время, имея возможность просто не смотреть на другие 24 или 16 или любые битовые полосы. Битвые поля в C 1) настолько плохие, что вы никогда не должны их использовать 2) иллюзия. он просто создает код, который вы могли бы написать себе, переместиться и замаскировать, чтобы притворяться, что есть такая вещь, как 1-битная переменная. Даже символы и шорты на C - это иллюзия на многих процессорах, которые мы используем, например битовые поля, которые создают дополнительные инструкции для превращения большего регистра в нечто меньшее. или наоборот. –

ответ

4

Почему у нас нет данных, размер которых составляет 4 бита?

Кто сказал, что? В Intel 4004 CPU были 4-битные регистры и 4-разрядные операнды памяти. 4-битные типы данных являются естественными для этого ЦП, поскольку они поддерживаются напрямую.

Intel 8051 CPU может управлять отдельными битами памяти напрямую, и поэтому вы можете иметь на нем 1-битные переменные.

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

Почему мы не можем сделать их, если мы так склонны?

Мы можем. Вы можете либо сделать CPU с прямой поддержкой 4-битных типов данных, либо вы можете имитировать 4-битные переменные как части более крупных переменных.

Вы можете упаковать 2 4-битные переменные в 8-разрядный байт. Проблема с этим подходом заключается в том, что вам нужно использовать дополнительные инструкции для извлечения 4 битов из 8-битных регистров или мест памяти (для этого вам требуется инструкция shift и mask (AND)), и вам также понадобится больше инструкций по правильному сохранению 4 (бит 8 бит, очистить старое значение в 4-битной половине (с маской/AND), сдвинуть новое значение, объединить его с остальными и сохранить обратно). Очевидно, это негативно повлияет на размер кода вашей программы и ее скорость.Кроме того, 4-битные переменные не очень полезны, поскольку они могут хранить так мало информации. По этим причинам моделирование меньших типов не очень популярно.

Я видел бит-поля, но я слышал, что они не переносимы и, возможно, тоже не используются?

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

Они не являются полностью неспортивными. Они имеют ограниченную переносимость в C и C++, потому что языковые стандарты не определяют точное расположение и расположение бит-полей в более крупных типах данных. Это сделано намеренно, чтобы позволить авторам компилятора наиболее эффективно использовать функции ЦП при работе с битовыми полями.

6.7.2.1 Structure and union specifiersclause 10 стандарта C с 1999 года говорит, что это:

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

 

Я думаю, что это результат того, как машина интерпретирует топоним значение местоположения долота. (big-endian, little-endian)

Да, это часть причины. Но это никоим образом не характерно для бит-полей. У этой проблемы также есть обычные, небитовые типы.

Мы также не можем сделать бит-поле, подобное этому, которое больше любого примитивного типа. Так почему же ограничения? Это можно сделать в сборке?

Если ваш C (или C++) -компилятор (или интерпретатор) может имитировать типы, которые больше, чем те, которые поддерживаются ЦП, могут иметь даже 256-битные битовые поля.

Но опять же, если самый большой тип процессора, поддерживаемый напрямую, является 32-разрядным, это будет означать, что использование более крупных типов (будь то бит-полей или нет), таких как 128-битные, приведет к большему количеству кода и некоторой производительности поскольку одна команда CPU (или только пара из них) не сможет манипулировать такими большими значениями данных. Для выполнения этих дополнительных инструкций вам потребуется больше инструкций и больше времени.

Да, это можно сделать в сборке. Все, что можно сделать в сборке, пока вы готовы написать код и заставить его работать. :)

+0

Очень подробное объяснение. Но если я напишу некоторый код C для 4-битного процессора, не будет ли компилятор заботиться о количестве бит, которое имеет 'int', например, сделать его 4? Аналогично, я мог бы спросить, почему тогда нет 1-битного типа данных, и тогда ответ не сильно изменится. – Leonardo

+0

Компилятор, соответствующий стандарту, должен иметь длину 'int' не менее 16 бит. Он может предоставлять 4-битные типы в качестве расширения реализации. Стандартных (и не только стандартных, но также требуемых стандартом (например, 'uint8_t' является стандартным, но необязательным)) 1-битные типы данных в C по причинам истории, совместимости, производительности и маловероятного принятия. –

3

Почему у нас нет данных, размер которых составляет 4 бита?

Поскольку наименьшие числа, с которыми могут работать современные процессоры, такие как x86, составляют 8 бит.

Почему мы не можем сделать их, если мы так склонны?

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

Это можно сделать в сборке?

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

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

+0

Красиво положил! Чтобы добавить к тому, что написал @Mehrdad, даже доступ к 8 бит на современном процессоре x86 может быть * медленнее *, чем доступ к 32 битам, в зависимости от адреса. Вот почему большинство компиляторов вставляют поля внутри структур для выравнивания по 4 байт. –

+0

Это объясняет, почему 'int' является, по-видимому, наиболее предпочтительным типом данных, например, для переменных инкремента. Но тогда мне интересно, почему 'sizeof (int) = 4' на моем 64-битном процессоре. Я ожидал бы результата '8', если это более естественно для него. – Leonardo

+0

@ Leonardo: обратная совместимость, к сожалению. Изменение 'int' до 64-битного кода сломало бы много кода, хотя с точки зрения C это вполне допустимая реализация. – Mehrdad