在汇编语言级别处理 RISC-V 中大端值的最简单方法是什么?也就是说,如何将一个 big-endian 值从内存加载到一个寄存器中,在 native-endian(little-endian)中使用该寄存器值,然后将它以 big-endian 存储回内存中。 16、32 和 64 位值用于许多网络协议(protocol)和文件格式。

我找不到字节交换指令(相当于 x86 上的 BSWAP 或 ARM 上的 REV) in the manual ,也没有任何关于大端加载和存储的信息。

最佳答案

在最新的 RISC-V User-Level ISA Manual(2.1 版)中没有提到字节交换指令。但是,该手册有一个占位符,用于表示位操作的“B”标准扩展。该扩展工作组的一些草稿 Material 是 collected on GitHub 。特别是,draft specification 谈到了可以进行 16、32 和 64 位字节交换的 grev 指令(广义反向):



扩展 B 工作组在最终确定规范之前“因官僚主义原因于 2017 年 11 月解散”。

2020 年,工作组再次活跃,在链接的 GitHub 存储库中发布他们的工作。

因此,目前似乎没有什么比做通常的换挡面具或跳舞更简单的了。我在 GCC 或 clang riscv 端口中找不到任何内在的汇编语言 bswap。例如,下面是 bswapsi2 编译器版本 8.1.0-12 发出的 riscv64-linux-gnu-gcc 函数(它对 32 位值进行字节交换)的反汇编:

000000000000068a <__bswapsi2>:
 68a:   0185169b                slliw   a3,a0,0x18
 68e:   0185579b                srliw   a5,a0,0x18
 692:   8fd5                    or      a5,a5,a3
 694:   66c1                    lui     a3,0x10
 696:   4085571b                sraiw   a4,a0,0x8
 69a:   f0068693                addi    a3,a3,-256 # ff00 <__global_pointer$+0xd6a8>
 69e:   8f75                    and     a4,a4,a3
 6a0:   8fd9                    or      a5,a5,a4
 6a2:   0085151b                slliw   a0,a0,0x8
 6a6:   00ff0737                lui     a4,0xff0
 6aa:   8d79                    and     a0,a0,a4
 6ac:   8d5d                    or      a0,a0,a5
 6ae:   2501                    sext.w  a0,a0
 6b0:   8082                    ret

关于assembly - 在 RISC-V 上在大端和小端之间转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52099612/

10-11 19:13