x86 汇编中的 ntohl 是必需的吗?

Is ntohl in x86 assembly necessary?

我的目标是通过 TCP 将整数值作为小端字节发送到 windows 上的客户端,客户端是用 x86 程序集编写的。

如果我要向客户端发送 htonl() 编码字节,是否有必要将客户端编译为 x86?例如,在我客户的汇编代码中调用 ntohl() 不是多余的吗?

我的首要问题是我是否需要调用 htonl() 服务器端和 ntohl() 客户端(x86 windows 客户端)?或者我应该让服务器通过检查服务器的体系结构是否是大端字节序来完成工作,如果是,则通过 __builtin_bswap32() 交换整数字节并将小字节序字节发送给客户端?我问是因为我读过 x86 总是小端,所以如果我知道客户端总是要用 x86 程序集编写的话,这似乎是多余的。

htonl 函数将 32 位值从 [h]ost 字节顺序转换为 [n] 网络字节顺序。主机字节序可能是大端或小端,网络字节序是大端。 ntohl 函数执行相反的操作。

这些函数的目的是抽象出任何可能的主机字节顺序转换,并为网络提供已知格式。所以在小端系统上,这些函数反转字节顺序,而在大端系统上,它们 return 原始值不变。

我建议使用标准网络字节顺序,即大端,通过网络发送值。他们的代码将使用 htonl 来准备发送值,并使用 ntohl 来读取接收到的值,而不管主机架构如何。

My overarching question is do I need to call htonl() server-side and ntohl() client side (x86 windows client)?

不,那会转换为大端(“网络”字节顺序),但您说您想以小端格式通过网络发送数据。在 x86 上,这已经是 h(“主机”)命令。

在 x86 asm 中,内存中的数据已经是小端整数/浮点数,除非你做了一些不寻常的事情(比如使用 bswapmovbepshufb,或者一次字节移位/存储。)

为了与 C 中的兼容,使用 GCC's / BSD <endian.h> 中的 le32toh(接收时)和 htole32(发送前)而不是 ntohl / htonl.即使用 LE 作为网络格式而不是传统的 BE。

call ntohl() within my client's assembly code?

那太疯狂了。如果确实需要,只需使用 bswap or movbe 指令,而不是实际为函数调用设置参数。尽管在 libc.

中有 ntohl 的独立定义,但在 C 中使用它们时通常会内联这些函数。

另外,不,你不想那样做。您的客户不想与 big-endian 有任何关系,这就是那些传统函数所说的“网络”字节顺序。

带有 AVX2 vpshufb 的 x86 asm 可以以 memcpy 速度进行字节交换(包括适合 L1d 缓存的小缓冲区),但作为第一个的一部分,根本不需要交换更有效读取数据的步骤。