问题描述
在汇编语言级别使用RISC-V中的大端值的最简单方法是什么?即,如何将内存中的大端值加载到寄存器中,如何在本机端(little-endian)中使用寄存器值,然后将其存储回大端中的内存中. 16、32和64位值用于许多网络协议和文件格式.
What is the simplest way to work with big-endian values in RISC-V at the assembly language level? That is, how to load a big-endian value from memory into a register, work with the register value in native-endian (little-endian), then store it back into memory in big-endian. 16, 32 and 64 bit values are used in many network protocols and file formats.
我找不到字节交换指令(相当于x86上的BSWAP或ARM上的REV) ,也没有关于大端存储和存储的任何内容.
I couldn't find a byte-swap instruction (equivalent to BSWAP on x86 or REV on ARM) in the manual, nor anything about big-endian loads and stores.
推荐答案
在最新的 RISC-V用户级ISA手册(2.1版).但是,该手册中有占位符,用于"B"位操作标准扩展.该扩展工作组的一些材料草案是在GitHub上收集的.特别是,草稿规范讨论了指令(通用反向):
There is no mention of a byte-swap instruction in the latest RISC-V User-Level ISA Manual (version 2.1). However, the manual has a placeholder for "B" Standard Extension for Bit Manipulation. Some draft materials from that extension's working group are collected on GitHub. In particular, the draft specification talks about a grev
instruction (generalized reverse) that can do 16, 32 and 64-bit byte-swaps:
工作组在2020年再次活跃,将其工作发布在链接的GitHub存储库中.
因此,目前似乎没有比平常的shift-mask-或dance更简单的事情了.我在GCC或clang riscv端口中找不到任何固有的汇编语言bswap.例如,下面是riscv64-linux-gnu-gcc
编译器版本8.1.0-12发出的bswapsi2
函数(该字节交换32位值)的反汇编:
As a result, there currently doesn't seem to be anything simpler than doing the usual shift-mask-or dance. I couldn't find any assembly language bswap intrinsic in the GCC or clang riscv ports. As an example, here's a disassembly of the bswapsi2
function (which byte-swaps a 32-bit value) emitted by the riscv64-linux-gnu-gcc
compiler version 8.1.0-12:
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
这篇关于在RISC-V上的大端和小端之间转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!