2013-10-09 5 views
1

Итак, я пытаюсь выяснить, какой энтузиазм использует система, используя код. Я посмотрел на сети, и нашел кого-то с тем же вопросом, и один из ответов на Stack бирже имел следующий код:Как работает этот код, который проверяет работу Endianess системы?

int num = 1; 
if(*(char *)&num == 1) 
{ 
    printf("\nLittle-Endian\n"); 
} 
else 
{ 
    printf("Big-Endian\n"); 
} 

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

(*(char *)&num == 1) 

ответ

3

Я предполагаю, что вы используете C/C++

  1. &num берет адрес в память целого числа num.
  2. Он интерпретирует этот адрес как указатель на char броском (char *)
  3. Далее, значение этого указателя на полукокса считается первым в *(char *)&num звездочкой, и по сравнению с 1.

Теперь int - 4 байта. Это будет 00 00 00 01 по системе большого конца и 01 00 00 00 на маленькой системе. Символ имеет только один байт, поэтому значение литого в char будет принимать первый байт памяти, занятой num. Таким образом, на большой системе endian это будет **00** 00 00 01, а на маленькой системе - это **01** 00 00 00. Итак, теперь вы выполняете сравнение с помощью инструкции if, чтобы узнать, соответствует ли int, отлитый от char, порядку байтов, используемому в маленькой системе.

На 32-битной системе X86 это может составить до следующей сборки

mov  [esp+20h+var_4], 1  ; Moves the value of 1 to a memory address 
lea  eax, [esp+20h+var_4] ; Loads that memory address to eax register 
mov  al, [eax]    ; Takes the first byte of the value pointed to by the eax register and move that to register al (al is 1 byte) 
cmp  al, 1     ; compares that one byte of register al to the value of 1 
+0

Мне нравится ваш ответ, и теперь я понимаю, но у меня есть еще один вопрос: почему один байт представлен в виде двух нулей в вашем примере? Моя первоначальная мысль заключалась в том, что один байт будет представлен как 8 нулей? – GelatinFox

+0

@ Rouke как легко думать о байте, как в диапазоне от 00 до 0xFF в шестнадцатеричном значении. Когда вы работаете с дизассемблерами, вы видите, что регистры CPU отформатированы в шестнадцатеричном значении, а не в десятичных значениях. Поскольку CPU берет первый байт (приведение в 'char'), значения (' int'), охватывающего 4 байта, в вашем коде, легче представить, что на самом деле происходит таким образом. –

+0

@Rouke 'Моя первоначальная мысль заключалась в том, что один байт будет представлен как 8 нулей. Один байт имеет 8 бит. Поэтому, если вы укажете один байт в двоичном формате, у вас действительно будет 00000000 (восемь) позиций. Каждый 0 может быть 1, поэтому максимальное значение может быть 11111111, которое равно 0xFF в шестнадцатеричном виде и 255 в десятичном значении. Таким образом, 'int num' будет записан ** двоичным ** в 4 блоках по 8 бит, со значением 1 это будет' 00000000 00000000 00000000 00000001'. –

0
(*(char *)&num == 1) 

Примерно переводится как принять адрес переменной num. Вставьте его содержимое в символ и сравните значение с 1.

Если символ в первом адресе вашего целого числа равен 1, то это младший байт, а ваши номера - Маленькие-Endian.

Номера Big-Endian будут иметь старший байт (0, если целочисленное значение равно 1) на самом нижнем адресе, поэтому сравнение не будет выполнено.

0

все мы знаем, что тип «int» занимает 4 байта, а «char» - только 1 байт. эта строка просто преобразует целое число в char.it, эквивалентно: char c = (char) «младший байт num».

см концепцию: http://en.wikipedia.org/wiki/Endianness порядок байтов

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

пример является: предположим, что Num является 0x12345678, на тупоконечника машинах с будет 0x12, тогда как на прямой порядок байтов машин с является 0x78

0

Здесь идет.Вы присвоить значение 1 к 4 байта междунар так

01 00 00 00 на небольшой Endian x86 00 00 00 01 на большой Endian

(* (символ *) & Num == 1)

10 Если первый байт равен 1, то младший значащий бит должен быть первым и последним это немного конец.

Смежные вопросы