如何提取Risc v汇编代码中的位

问题描述

寄存器x5存储0x00C0_C000,寄存器x6存储0x0000_C0000。此时,您要提取寄存器x5的位[15:8]的值,并将其放入寄存器x6的位[31:16]。完成RISC-V汇编代码以执行此操作。但是,x5和x6的其他位不应更改。

用x5寄存器中的[15:8]的8位替换x6 [31:16]位,但是将8bit与[31:16]的低位对齐。

我认为我应该使用sllisrli提取位。但是使用它们,x5和x6的其他位会改变。如何在不更改其他位的情况下提取位?

解决方法

您要执行的操作是: 如果不确定x6的高位部分是否始终等于0,则可以清除它。您可以使用遮罩进行此操作:

li x28,0xffff
and x6,x6,x28

slli x6,16
srli x6,16

由于无法修改x5,因此需要使用其他tmp寄存器:

mv x28,x5

从[15:8]位中获取8位,并将其放入[31:16]

srli x28,x28,8
andi x28,0xff
slli x28,16

最后,您将或放置在x6中:

or x6,x29

也尝试看看https://raw.githubusercontent.com/riscv/riscv-bitmanip/master/bitmanip-0.90.pdf。如果支持,则RISC-V Bitmanip Extension可能会很有趣。

,

我将提供下一个解决方案,我正在使用0x00debc00以便于查看: 对于RV64I

lui a1,0xDEB     # loads 0x00deb of 0x00debc00
li a2,0xC00      # loads 0xc00 of 0x00debc00
add a1,a1,a2     # stick together 0x00deb + c00 = 0x00debc00
slli a3,48    # took 0x00de"bc"00 and moves to left corner to clean unnecessary bits
srli a4,a3,48    # move "bc" back into 0xbc00
xor a1,a4     # use 0xbc00 for masking initial 0x00debc00 and get 0x00de0000
srli a3,32    # move 0xbc from left corner of $a3 to it's place 0x0000bc00
add a1,a3     # concatenate it all - voila! 0xbcde0000

也许更简单,但我还不是魔术师)

对于RV32I,您应该减少向左的移动:

lui a1,0xDEB
li a2,0xC00
add a1,a2
slli a3,16
srli a4,16
xor a1,a4
#srli a3,32 no need to move back its already in it's place
add a1,a3

对不起,“恭喜”。