Что делает систему порядком байтов или порядком байтов? - PullRequest
13 голосов
/ 11 февраля 2012

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

Вопрос 1

Если яиспользуйте только тип char в моей программе на C ++:

void main()
{
    char c = 'A';
    char* s = "XYZ";    
}

Затем скомпилируйте эту программу в исполняемый двоичный файл с именем a.out.
Может ли a.out работать как на младшем, так и на старшемendian systems?

Вопрос 2

Если моя система Windows XP имеет младший порядок, могу ли я установить систему Linux с прямым порядком байтов в VMWare / VirtualBox?Что делает систему с прямым порядком байтов или с прямым порядком байтов?

Вопрос 3

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

Ответы [ 6 ]

20 голосов
/ 11 февраля 2012

Может ли a.out работать как в системе с прямым порядком байтов, так и в системе с прямым порядком байтов?

Нет, потому что практически любые два ЦП настолько различны, что имеют разный порядок байтовне будет запускать тот же набор инструкций.C ++ не Java;вы не компилируете что-то, что компилируется или интерпретируется.Вы компилируете в сборку для конкретного процессора.И endian-ness является частью ЦП.

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

Что делает систему с прямым порядком байтов или с прямым порядком байтов?

КакЧто касается C или C ++, то процессор.Разные процессоры в компьютере могут на самом деле иметь разные порядки байтов (GPU может быть порядком байтов, в то время как процессоры имеют порядок байтов), но это несколько необычно.

Если я хочу записать порядок байтовНезависимая программа C ++, что мне нужно учитывать?

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

Конечно, вы также не сможете загружать файлы непосредственно в структуры POD.Или прочитайте серию байтов, представьте, что это серия шорт без знака, и затем обработайте ее как строку в кодировке UTF-16.Все эти вещи вступают в сферу поведения, определяемого реализацией.

Существует разница между поведением "неопределенное" и "определяемое реализацией".Когда в спецификациях C и C ++ говорится, что что-то «неопределено», это в основном означает, что возможны всевозможные нарушения.Если вы продолжаете делать это (и ваша программа не падает), вы можете получить противоречивые результаты.Когда говорится, что что-то определено реализацией, вы получите согласованные результаты для этой реализации .

Если вы компилируете для x86 в VC2010, то, что происходит, когда вы притворяетесь, что байтовый массив являетсякороткий массив без знака (то есть: unsigned char *byteArray = ...; unsigned short *usArray = (unsigned short*)byteArray) определяется реализацией.При компиляции для процессоров с прямым порядком байтов вы получите другой ответ, чем при компиляции для процессоров с прямым порядком байтов.

В общем, проблемы с порядком байтов - это то, что вы можете локализовать в системах ввода / вывода.Работа в сети, чтение файлов и т. Д. Об этом следует позаботиться в конечных точках вашей кодовой базы.

8 голосов
/ 11 февраля 2012

Вопрос 1:

Может ли a.out работать в системе с прямым и прямым порядком байтов?

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

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

Так что да (источник) будет работать правильно. (ну ... кроме void main(), который вы должны использовать вместо int main())

Вопрос 2:

Если моя система WindowsXP имеет порядок байтов, могу ли я установить порядок байтов Система Linux в VMWare / VirtualBox?

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

Что делает систему с прямым порядком байтов или с прямым порядком байтов?

Вот пример чего-то, что будет вести себя по-разному в сравнении со старшим и младшим порядком байтов:

uint64_t a = 0x0123456789abcdefull;
uint32_t b = *(uint32_t*)&a;
printf("b is %x",b)

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

Little Endian : b is 89abcdef
Big Endian    : b is 1234567

На младшем байте младшие биты a сохраняются по младшему адресу. Поэтому, когда вы обращаетесь к a как к 32-битному целому числу, вы читаете его младшие 32 бита. На big-endian вы будете читать старшие 32 бита.

Вопрос 3:

Если я хочу написать независимую от байтов программу C ++, что мне делать нужно учитывать?

Просто следуйте стандартным правилам C ++ и не делайте ничего уродливого, как в примере, который я показал выше. Избегайте неопределенного поведения, избегайте наказания за тип ...

3 голосов
/ 11 февраля 2012

Little-endian / big-endian - это свойство аппаратного обеспечения.Как правило, двоичный код, скомпилированный для одного оборудования, не может работать на другом оборудовании, кроме как в средах виртуализации, которые интерпретируют машинный код и эмулируют целевое оборудование для него.Существуют процессоры с прямым порядком байтов (например, ARM, IA-64), которые имеют переключатель для изменения порядка байтов.

Что касается программирования, независимого от порядка байтов, то единственный случай, когда вам действительно необходимо этоиметь дело с сетью.Существуют такие функции, как ntohl и htonl, которые помогут вам преобразовать порядок байтов вашего оборудования в порядок байтов сети.

2 голосов
/ 11 февраля 2012

1: Вывод компилятора будет зависеть от опций, которые вы ему предоставите, и от того, используете ли вы кросс-компилятор. По умолчанию он должен работать в операционной системе, в которой вы его компилируете, а не в других (возможно, даже не в тех же типах; не все бинарные файлы Linux работают, например, во всех установках Linux). В больших проектах это будет меньше всего беспокоить вас, поскольку библиотеки и т. Д. Необходимо будет по-разному создавать и связывать в каждой системе. Использование правильной системы сборки (например, make) позаботится о большинстве из этого, не беспокоясь о ней.

2: Виртуальные машины абстрагируют аппаратные средства таким образом, чтобы позволить по существу всему работать внутри чего-либо еще. То, как операционные системы управляют своей памятью, не имеет значения, если они работают на одном и том же оборудовании и поддерживают любую модель виртуализации. Endianness означает порядок байтов; если он читается слева направо или справа налево (или какой-либо другой формат). Некоторое оборудование поддерживает и то, и другое, и виртуализация позволяет сосуществовать в этом случае (хотя я не знаю, как это было бы полезно, за исключением того, что это возможно в теории). Тем не менее, Linux работает на многих различных архитектурах (и Windows, кроме Ixxx), поэтому ситуация более сложная.

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

2 голосов
/ 11 февраля 2012

Первое, что нужно уточнить, это то, что порядковый номер - это аппаратный атрибут, а не атрибут программного обеспечения / ОС, поэтому WinXP и Linux не являются порядком байтов с прямым порядком байтов или прямым порядком байтов, а скорее аппаратным обеспечением, на котором они работают, либо старшим порядковым номером, либо little endian.

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

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

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

1 голос
/ 11 февраля 2012

порядковый номер системы определяет, как интерпретируются байты, и какой бит считается «первым», а какой - «последним».

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

...