我正在编写一个ELF分析器,但我在转换字节顺序方面遇到了一些麻烦.我有函数来确定分析器的字节顺序和目标文件的endiannness.
基本上,有四种可能的情况:
是否有一个函数我可以用来显式交换字节顺序/更改字节顺序,因为ntohs/l()和htons/l()考虑了主机的字节序,有时不转换?或者我是否需要查找/编写自己的交换字节顺序功能?
我认为值得提出的是The Byte Order Fallacy的文章,作者是Rob Pyke(Go的作者之一).
如果你做对了 - 也就是你没有假设你的平台字节顺序 - 它就会起作用.您需要关心的是ELF格式文件是以Little Endian还是Big Endian模式.
来自文章:
假设您的数据流具有小端编码的32位整数.以下是如何提取它(假设无符号字节):
i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
Run Code Online (Sandbox Code Playgroud)
如果它是big-endian,这里是如何提取它:
i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
Run Code Online (Sandbox Code Playgroud)
然后让编译器担心优化它.
在Linux中有几个转换函数中endian.h,允许任意字节序之间的转换:
uint16_t htobe16(uint16_t host_16bits);
uint16_t htole16(uint16_t host_16bits);
uint16_t be16toh(uint16_t big_endian_16bits);
uint16_t le16toh(uint16_t little_endian_16bits);
uint32_t htobe32(uint32_t host_32bits);
uint32_t htole32(uint32_t host_32bits);
uint32_t be32toh(uint32_t big_endian_32bits);
uint32_t le32toh(uint32_t little_endian_32bits);
uint64_t htobe64(uint64_t host_64bits);
uint64_t htole64(uint64_t host_64bits);
uint64_t be64toh(uint64_t big_endian_64bits);
uint64_t le64toh(uint64_t little_endian_64bits);
Run Code Online (Sandbox Code Playgroud)
编辑,不太可靠的解决方案.您可以使用union以任何顺序访问字节.这很方便:
union {
short number;
char bytes[sizeof(number)];
};
Run Code Online (Sandbox Code Playgroud)
我需要找到/编写自己的交换字节顺序函数吗?
是的你是。但是,为了简单起见,我向您推荐这个问题:How do I conversion between big-endian and Little-endian value in C++? 它给出了编译器特定的字节顺序交换函数的列表,以及字节顺序交换函数的一些实现。
| 归档时间: |
|
| 查看次数: |
23759 次 |
| 最近记录: |