我如何为 Risc-V(汇编语言)编写旋转操作 我们是否有像 8086 中那样的命令?
How do I write rotation Operation for the Risc-V(Assembly Language) Do we have any command for it like we have have in 8086?
我以前用过8086的汇编语言,8086的旋转操作只是一个命令。但是我在Risc-V汇编语言中找不到轮换操作的具体关键字。
看起来扩展 "B" 最终应该定义这样的指令。
在那之前你必须使用左移和右移来组合它。
这是 MIPS32R2 rotrv 指令的等价物(按变量计数向右循环):
rotrv:
subu neg_count, zero, count
srlv tmp1, src, count
sllv tmp2, src, neg_count
or dst, tmp1, tmp2
你可以在 riscv 上做同样的事情。
RISC-V 基本指令集不包含循环指令。
因此,您必须使用多个基本指令实现旋转(a.k.a。循环移位)例如:
.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
在零处回绕并且 shift-left-logical (sll
) 仅使用低六位 (RV64G) 或五位a4
的 (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
RISC-V Bitmanip Extension "B" 规范草案确实包括几个额外的移位和洗牌指令,包括左右旋转:
# 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
(RISV-V Bitmanip Extension V0.92,第 2.2.1 节,第 14 页)
当然,截至 2020 年,由于处于草案状态,bitmanip 指令及其编码可能会发生变化,并且软件工具链、模拟器和硬件中对 "B" 扩展的支持尚未广泛提供。
我以前用过8086的汇编语言,8086的旋转操作只是一个命令。但是我在Risc-V汇编语言中找不到轮换操作的具体关键字。
看起来扩展 "B" 最终应该定义这样的指令。
在那之前你必须使用左移和右移来组合它。
这是 MIPS32R2 rotrv 指令的等价物(按变量计数向右循环):
rotrv:
subu neg_count, zero, count
srlv tmp1, src, count
sllv tmp2, src, neg_count
or dst, tmp1, tmp2
你可以在 riscv 上做同样的事情。
RISC-V 基本指令集不包含循环指令。
因此,您必须使用多个基本指令实现旋转(a.k.a。循环移位)例如:
.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
在零处回绕并且 shift-left-logical (sll
) 仅使用低六位 (RV64G) 或五位a4
的 (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
RISC-V Bitmanip Extension "B" 规范草案确实包括几个额外的移位和洗牌指令,包括左右旋转:
# 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
(RISV-V Bitmanip Extension V0.92,第 2.2.1 节,第 14 页)
当然,截至 2020 年,由于处于草案状态,bitmanip 指令及其编码可能会发生变化,并且软件工具链、模拟器和硬件中对 "B" 扩展的支持尚未广泛提供。