2014-12-19 2 views
5

나는 도서관 (github.com/adduc/phpmodbus)를 통해 읽고 있어요 및 바이트 - 리틀 엔디안 또는 빅 엔디안 문자열로 정수를 변환하는이 기능이있다 :엔디안 변환이 맞습니까?

private static function endianness($value, $endianness = 0) { 
    if ($endianness == 0) 
     return 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)) . 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF); 
    else 
     return 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)); 
} 

iecBYTE 기능은 단지 chr($value & 0xFF)입니다.

어쩌면 나는 두껍지만 리틀 엔디안 문자열이 잘못되었습니다.
예를 들어 0xAABBCCDD을 입력하면 {CC}{DD}{AA}{BB}이 표시됩니다.

나는 심지어 위키 백과에서 그것을 찾았다. {DD}{CC}{BB}{AA}이 아니어야합니까?

코드 이지만 실제로 혼란 스럽습니다. 맞습니까? 잘못 이해합니까?

+1

작동한다는 것은 무엇을 의미합니까? 아마도 "일하고"있을 수 있지만 제대로 작동하지 않을 수 있습니까? – imtheman

+0

어쩌면 나는 그 방법이 무엇을하고 있는지 오해했을지도 모릅니다. 이 방법은 라이브러리에서 상당히 많이 사용되며 올바르게 작동합니다. – MightyPork

답변

0

IECType.php을보고 나면 PHP 유형을 IEC 1131 유형으로 변환하고있는 것으로 나타났습니다. 리틀 엔디안은 최하위 바이트를 먼저 저장합니다. 귀하의 설명에 따라 시스템이 16 비트 주소를 사용한다고 생각하게됩니다.

endianess 함수 위의 주석에서 참조되는 Endianess에 대한 wiki을 보면, 리틀 엔디안 아래에 Atomic element size 16-bit라는 섹션이 표시됩니다. 하나의 주소는 2 바이트 (CCDD)와 (AABB)를 보유합니다. (CCDD)를 보유하는 주소는 가장 중요하지 않으므로 먼저 나열됩니다.

8 비트 시스템에서 작업하는 경우 주소 당 1 바이트가 있기 때문에 각 바이트가 정렬됩니다 (DDCCBBAA).

위키는 endianess 기능에서보고있는 것을 설명합니다.

 
address1| address2 
16-bits | 16-bits 
CCDD | AABB 
0

정확합니다. 이 기능은 옳지는 않지만 가까이 있습니다. 몇 가지 전환을 교환해야하는 것 같습니다. 논리적으로 리틀 엔디안 변환 ($ endianness == 0)은 빅 엔디안 변환 ($ endianness! = 0)의 역입니다.

private static function endianness($value, $endianness = 0) { 
    if ($endianness == 0) //little-endian 
     return 
       self::iecBYTE($value & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 24) & 0x000000FF); 
    else //big-endian 
     return 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)); 
}