我正在阅读一个库(github.com/adduc/phpmodbus),这个函数用于将整数转换为little-endian或big-endian字节串:
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}
?
代码有效,这让我很困惑。是不是我理解错了?
答案 0 :(得分:0)
你是对的。功能不对,虽然它很接近。看起来你只需交换一些转换。逻辑上,little-endian转换($ endianness == 0)只是big-endian转换的反转($ 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));
}
答案 1 :(得分:0)
在查看IECType.php之后,我注意到它正在将PHP类型转换为IEC 1131类型。 小端首先存储最不重要的字节。你的描述会让我觉得系统使用的是16位地址。
如果您查看endianess函数上方注释中引用的Endianess的wiki,那么您将在Little-endian下看到一个名为Atomic element size 16-bit的部分。一个地址包含两个字节(CCDD)和(AABB)。持有(CCDD)的地址最不重要,因此它将首先列出。
如果你在8位系统中工作,那么每个字节都会被排序(DDCCBBAA),因为每个地址会有一个字节。
Wiki描述了您在endianess函数中看到的内容。
address1| address2 16-bits | 16-bits CCDD | AABB