Assembly 如何为Risc-V(汇编语言)编写旋转操作我们有没有像8086中那样的命令?

Assembly 如何为Risc-V(汇编语言)编写旋转操作我们有没有像8086中那样的命令?,assembly,riscv,Assembly,Riscv,我以前使用过8086汇编语言,8086中的旋转操作只是一个命令。但我在Risc-V汇编语言中找不到旋转操作的特定关键字。看起来扩展名“B”最终应该定义这样的指令 在那之前,你必须使用左移和右移来合成它 以下是MIPS32R2 rotrv指令的等效程序(通过变量计数向右旋转): 您可以在riscv上执行相同的操作。RISC-V基本指令集不包括旋转指令 因此,您必须使用多个基本指令执行旋转(也称为循环移位),例如: .text .balign 4 # unsigned long ro

我以前使用过8086汇编语言,8086中的旋转操作只是一个命令。但我在Risc-V汇编语言中找不到旋转操作的特定关键字。

看起来扩展名“B”最终应该定义这样的指令

在那之前,你必须使用左移和右移来合成它

以下是MIPS32R2 rotrv指令的等效程序(通过变量计数向右旋转):


您可以在riscv上执行相同的操作。

RISC-V基本指令集不包括旋转指令

因此,您必须使用多个基本指令执行旋转(也称为循环移位),例如:

    .text
    .balign 4
# unsigned long rotl(unsigned long x, unsigned long amnt);
    .global rotl
rotl:
    sll  a2,   a0, a1
    sub  a4, zero, a1
    srl  a3,   a0, a4
    or   a0,   a2, a3
    ret
# unsigned long rotr(unsigned long x, unsigned long amnt);
    .global rotr
rotr:
    srl  a2,   a0, a1
    sub  a4, zero, a1
    sll  a3,   a0, a4
    or   a0,   a2, a3
    ret
请注意,
sub a4,zero,a1
在零处环绕并向左移位逻辑(
sll
)仅使用
a4
的低六位(RV64G)或五位(RV32G)作为移位量

按立即数移位时,GNU
as
不会隐式截断移位量,因此必须显式屏蔽移位量,例如:

# unsigned long rotl3(unsigned long x);
    .global rotl3
rotl3:
    slli a2, a0,  3
    srli a3, a0, (-3 & 63) # & 31 for RV32G
    or   a0, a2, a3
    ret
# unsigned long rotr3(unsigned long x);
    .global rotr3
rotr3:
    srli a2, a0,  3 
    slli a3, a0, (-3 & 63) # & 31 for RV32G
    or   a0, a2, a3
    ret     
    .global rotl
规范草案确实包括几个额外的移位和洗牌指令,包括左旋转和右旋转:

(,第14页第2.2.1节)


当然,到2020年,由于草稿状态,bitmanip指令及其编码可能会发生变化,并且在软件工具链、模拟器和硬件中对“B”扩展的支持并不广泛。

RISC-V bitmanip扩展已经轮换如果不屏蔽即时消息会发生什么?你是否会把机器代码当作一个大的计数来处理,从而将所有的位移出?(例如x86屏蔽了与寄存器相同的立即移位计数,因此您不需要这样做。)@PeterCordes否,但GNU
as
失败,然后出现:
错误:移位量不正确(18446744073709551613)
啊,所以问题是它不会截断移位量以适应机器编码。谢谢
# unsigned long rotl3(unsigned long x);
    .global rotl3
rotl3:
    slli a2, a0,  3
    srli a3, a0, (-3 & 63) # & 31 for RV32G
    or   a0, a2, a3
    ret
# unsigned long rotr3(unsigned long x);
    .global rotr3
rotr3:
    srli a2, a0,  3 
    slli a3, a0, (-3 & 63) # & 31 for RV32G
    or   a0, a2, a3
    ret     
    .global rotl
# RV32, RV64:
ror   rd, rs1, rs2
rol   rd, rs1, rs2
rori  rd, rs1, imm

# RV64 only:
rorw  rd, rs1, rs2
rolw  rd, rs1, rs2
roriw rd, rs1, imm