Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly RISC-V上大端和小端的转换_Assembly_Endianness_Riscv - Fatal编程技术网

Assembly RISC-V上大端和小端的转换

Assembly RISC-V上大端和小端的转换,assembly,endianness,riscv,Assembly,Endianness,Riscv,在汇编语言级别处理RISC-V中的大端值的最简单方法是什么?也就是说,如何将大端值从内存加载到寄存器中,使用本机端(little-endian)中的寄存器值,然后将其存储回大端的内存中。16、32和64位值用于许多网络协议和文件格式 我找不到字节交换指令(相当于x86上的BSWAP或ARM上的REV),也找不到任何关于big-endian加载和存储的信息。最新版本(2.1版)中没有提到字节交换指令。但是,手册中有一个占位符,用于位操作的“B”标准扩展。该扩展工作组的一些材料草稿如下所示。特别是,

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


我找不到字节交换指令(相当于x86上的BSWAP或ARM上的REV),也找不到任何关于big-endian加载和存储的信息。

最新版本(2.1版)中没有提到字节交换指令。但是,手册中有一个占位符,用于位操作的“B”标准扩展。该扩展工作组的一些材料草稿如下所示。特别是,本文讨论了一种可以进行16、32和64位字节交换的
grev
指令(广义反向):

此指令提供一条硬件指令,可通过一条硬件指令实现所有字节顺序交换、位反转、短顺序交换、字顺序交换(RV64)、半字节顺序交换、字节位反转等。它接受一个寄存器值和一个立即数,通过控制递归树中反转发生的级别来控制哪个函数发生

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

2020年,工作组再次活跃起来,将他们的工作发布在链接的GitHub回购上。

因此,目前似乎没有什么比通常的变换面具或舞蹈更简单的了。我在GCC或clang riscv端口中找不到任何汇编语言bswap固有。例如,这里是对
riscv64 linux gnu gcc
编译器版本8.1.0-12发出的
bswapsi2
函数(字节交换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
000000000000068a:
68a:0185169b slliw a3,a0,0x18
68e:0185579b srliw a5,a0,0x18
692:8fd5或a5、a5、a3
694:66c1 lui a3,0x10
696:4085571b sraiw a4,a0,0x8
69a:f0068693 addi a3,a3,-256#ff00
69e:8f75和a4、a4、a3
6a0:8fd9或a5、a5、a4
6a2:0085151b slliw a0,a0,0x8
6a6:00ff0737 lui a4,0xff0
6aa:8d79和a0、a0、a4
6ac:8d5d或a0、a0、a5
6ae:2501十六进制带a0,a0
6b0:8082 ret

RISC-V ISA没有明确的字节交换指令。您最好使用一个C内置函数来执行此计算,在GCC语言中类似于
\uuuuuu内置函数\uBSWAP32()
。这将为编译器提供尽可能多的信息,以便它能够做出正确的决策。使用当前定义的一组ISA,您几乎肯定会最终调用例程,但如果定义了B扩展,您将透明地获得更好的生成代码。全套已定义的内置项可在线获取:

如果您在汇编程序中无法执行此操作,那么最好的办法是调用现有的字节交换例程。32位交换的标准配置是
\uu bswapsi2
,它是libgcc的一部分——您可能正在使用它,所以它就在附近。这就是编译器目前所做的,所以当有更好的实现可用时,您所失去的只是省略函数调用

作为一个具体的例子,这里是我的示例C函数

unsigned swapb(unsigned in) { return __builtin_bswap32(in); }
以及生成的程序集

swapb:
    addi    sp,sp,-16
    sd  ra,8(sp)
    call    __bswapsi2
    ld  ra,8(sp)
    sext.w  a0,a0
    addi    sp,sp,16
    jr  ra

请注意,虽然有一条指令来执行此操作非常方便,但其他答案中使用的_bswapsi2函数将在1.5 GHz HiFive上以大约400 MB/s的速度运行,这比gigE接口移动数据的速度要快得多

即使在默认256 MHz运行的HiFive1上,它也可以运行60 MB/s,并且您只有16 KB的RAM和一堆GPIO,您不会在超过几MHz或10 MHz的频率下摆动


我是比特操纵工作组的成员。完整的GREV指令需要相当多的硬件(接近乘法器),因此小型微控制器可能永远不会包含它。然而,我们计划使用相同的GREVI操作码,提供全字位反转和字节顺序反转,并将它们作为更简单的特殊情况指令来实现,不需要太多电路,希望每个人都能包括它们。

与x86不同,RISC-V没有类似于
movbe的东西。
(可以在一条指令中加载和交换字节)

因此,在RISC-V上,您像往常一样加载/存储,在加载/存储之后/之前,您必须用额外的指令交换字节

(版本0.92)包含通用位反转指令(
grev
grevi
)和几个可用于字节交换的伪指令:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
RISC-V    ARM      X86      Comment
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
rev       RBIT     ☐        bit reverse
rev8.h    REV16    ☐        byte-reverse half-word (lower 16 bit)
rev8.w    REV32    ☐        byte-reverse word (lower 32 bit)
rev8      REV      BSWAP    byte-reverse whole register
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
(表基于第18页表2.5)

截至2020-03年,“B”扩展具有草稿状态,因此硬件和模拟器的支持受到限制


没有“B”扩展您必须使用多个基本指令实现字节交换。例如,请参阅中的第16页或查看
\u内置bswap16
\u内置bswap32
\u内置bswap64
/clang intrinsic的反汇编代码。

您是否尝试过检查文档?这确实是一个需要解决的问题可以通过快速阅读相关内容来回答。是的,有多个源代码。字节交换是一种常见的操作,我想我一定错过了什么,这就是为什么我在这里提问的原因。我试图检查编译器在请求字节交换时做了什么,但Godbolt的clang risc-v安装被破坏,并尝试将x86内联asm用于
endian.h
be32toh()
。可能是编写纯C语言