首页 > 解决方案 > 高效的大端字节数组到 C 中的本机整数转换

问题描述

1) 是否有任何编译器内置指令,或用于 x86、ARM 或其他架构的汇编指令,它们将采用大端字节数组(2 字节 -> uint16_t,4 字节 -> uint32_t,8 字节 -> uint64_t)并将其转换为本机字节序的无符号整数(大、小、混合)。

2)是否还有任何内置函数或指令来执行逆转换(整数到大端字节数组)。

天真的原生 C 函数将是:

static inline void put_be16(uint8_t a[static sizeof(uint16_t)], uint16_t val)
{
    a[0] = (val >> 8) & 0xff;
    a[1] = val & 0xff;
}

static inline uint16_t get_be16(uint8_t const a[static sizeof(uint16_t)])
{
    return (a[0] << 8) | a[1];
}

这些用于从入站网络数据包中读取无符号整数,并对无符号整数进行编码以用于出站网络数据包。

解决方案必须防止或减轻未对齐的内存访问。

编辑:并且希望高效,所以直接在输入/输出缓冲区上运行的东西是我真正想要的。

标签: cassemblyx86arm

解决方案


至于C方面,我想这已经被问过了。我通过快速搜索找到了这个: 将 Little Endian 转换为 Big Endian

您可以使用 htonl()、htons() 和相关的,它们将与已知的大端格式相互转换。您还可以使用联合从 int 或 long 等中提取单个字节,如下所示:

union extract_byte_val {
    long long_val;
    uint8_t bytes_val[sizeof(long)];
}

例如:

long x = 128;
union extract_byte_val eb;
eb.long_val = htonl(x);

eb.bytes_val 现在是 {0, 0, 0, 128},因为 eb.long_val 是 bug-endian。


推荐阅读