2

是否有任何关于 htonll、ntohll、ntohl、htonl 的书面函数,例如我在论坛上找到的这个函数:

uint32_t ntohl(uint32_t const net) {
    uint8_t data[4] = {};
    memcpy(&data, &net, sizeof(data));

    return ((uint32_t) data[3] << 0)
         | ((uint32_t) data[2] << 8)
         | ((uint32_t) data[1] << 16)
         | ((uint32_t) data[0] << 24);
}

或者你能告诉我每一个的数据转移方案,然后像上面这个一样写吗?

编辑:

这些是否正确:

uint32_t htonl(uint32_t const net) {
    uint8_t data[4] = {};
    memcpy(&data, &net, sizeof(data));

    return ((uint32_t) data[0] << 0)
         | ((uint32_t) data[1] << 8)
         | ((uint32_t) data[2] << 16)
         | ((uint32_t) data[3] << 24);
}

uint64_t htonll(uint64_t const net) {
    uint8_t data[4] = {};
    memcpy(&data, &net, sizeof(data));

    return ((uint64_t) data[0] << 0)
         | ((uint64_t) data[1] << 8)
         | ((uint64_t) data[2] << 16)
         | ((uint64_t) data[3] << 24);
}

uint64_t ntohll(uint64_t const net) {
    uint8_t data[4] = {};
    memcpy(&data, &net, sizeof(data));

    return ((uint64_t) data[3] << 0)
         | ((uint64_t) data[2] << 8)
         | ((uint64_t) data[1] << 16)
         | ((uint64_t) data[0] << 24);
}
4

1 回答 1

3

这不是 STM32 特定的,但可以为所有 ARM MCU 一般回答。假设您使用的是gcc,则有内置函数,例如__builtin_bswap32.

因此,您可以将其实现为:

uint32_t htonl(uint32_t net)
{
    return __builtin_bswap32(net);
}

uint16_t htons(uint16_t net)
{
    return __builtin_bswap16(net);
}

uint64_t htonll(uint64_t net)
{
    return __builtin_bswap64(net);
}

生成的汇编代码非常高效:

htonl:
        rev     r0, r0
        bx      lr
htons:
        rev16   r0, r0
        uxth    r0, r0
        bx      lr
htonll:
        rev     r3, r0
        rev     r0, r1
        mov     r1, r3
        bx      lr

如果将函数声明为inline,甚至可以保存函数调用。

顺便说一句:在您的代码中,64 位版本可能不正确,因为它们只返回 32 位数量。

于 2019-12-11T09:26:32.613 回答