Как каждый байт в целом числе хранится в CPU / памяти? - PullRequest
6 голосов
/ 03 декабря 2009

я пробовал это

char c[4];
int i=89;
memcpy(&c[0],&i,4);
cout<<(int)c[0]<<endl;
cout<<(int)c[1]<<endl;
cout<<(int)c[2]<<endl;
cout<<(int)c[3]<<endl;

вывод выглядит так:
89
0
0
0

, который довольно тренирует мой желудок, потому что я думал, что число будет сохранено в памяти, как 0x00000059 так почему же c [0] равно 89? я думал, что это должно быть в с [3] ...

Ответы [ 6 ]

32 голосов
/ 03 декабря 2009

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

12 голосов
/ 03 декабря 2009

Это потому, что вы запускаете программу на little-endian процессоре. Смотрите также endianness здесь и там .

9 голосов
/ 03 декабря 2009

Endian-ness, очевидно, является ответом, как указал Гоз.

Но для тех, кто не знает, что это значит, также важно понимать, что порядок байтов, отображаемых в примере, совпадает с порядком в оригинальном int. Memcpy не меняет порядок байтов, независимо от типа платформы edian.

6 голосов
/ 04 декабря 2009

Потому что порядок байтов - это произвольное проектное решение. В регистре нет порядка байтов 1 .

Порядок байтов возникает, когда мы обращаемся к меньшим единицам, таким как байты. Это принципиально произвольное решение, которое принимает дизайнер ЦП: с прямым или обратным порядком байтов.

Полезно упростить ситуацию и понять, что это в основном соединение с периферийными устройствами, которые упорядочены байтами. Да, это может быть обнаружено с помощью байтовой адресации, как вы уже доказали, но в целом скалярные значения загружаются и сохраняются как единицы измерения в регистры, и в этом случае порядок байтов ничего не меняет. Наиболее значимые биты находятся «слева», по крайней мере, так, как мы обычно пишем числа. И именно поэтому операторы << и >> всегда дают одинаковые результаты на машинах с прямым порядком байтов по сравнению с машинами с прямым порядком байтов при использовании в соответствии со стандартами языка.

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

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

Представьте себе ЦП, который не имеет байтов, только 32-битных слов, с адресами 0, 1, 2. Компилятор C создает char, int и long все 32-битные объекты. (Это разрешено Cx9.) Ничего себе, никаких проблем с порядком байтов! Это оба! Но .. что происходит, когда мы подключаем наше первое периферийное устройство ??


1. Ну, у x86 есть регистры, которые имеют псевдонимы регистров меньшего размера, но это другая история.

2 голосов
/ 03 декабря 2009

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

long x = 89;
short *p = (short*)&x;
short y = *p;
1 голос
/ 03 декабря 2009

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

...