risc-v 中的 lui 具有小立即数
lui in risc-v with small immediate
像lui x28 123
这样的risc-v指令,venus显示它的机器码是0x0007BE37
。
但是 lui
应该只加载立即数 123
的高 20
位。由于在十六进制中123
是0x0000007B
,我想对应的机器码应该是0x00000E37
.
我很疑惑为什么venus会产生不同的结果,是不是我的理解有问题lui
?
当您向 LUI
之类的指令提供一个数值作为文字时,一些汇编程序会将其作为您希望在操作说明。这对于生成汇编的编译器或想要使用 LUI
并为该指令中的 20 位指定确切的位模式而不受汇编器的任何干扰的汇编程序员来说非常重要和有用。
如果你想让它只占用文字的高 20 位,可以使用一些编译时函数1,比如 %hi
和 %lo
将接受,例如lui %hi(123)
— %hi
用于 lui
而 %lo
用于需要 12 个低位的指令,例如 addi
和 sw
/lw
.
1 这些可能最晚会被评估 link 时间。
这些函数(%hi
和 %lo
)由于传统选择与 lw
和 addi
等指令配对而变得复杂,其中它们的立即数组成12 位剩余 但它本身是有符号的 。因此,%hi
函数在特定情况下将值偏移 1,其中 lw
的偏移量将显示为负数,并在运行时用 1 进行符号扩展。因此,当这些配对 2 时,环境使事情正常进行,但是如果您要在 LUI
中使用 %hi()
一个随机常数而没有这样的配对,您可能没有得到您期望的确切 20 位。
2 只要函数参数匹配,多个 %lo
可以与相同的 %hi
配对。因此,例如,全局变量的 read/modify/write 序列对于 lw %lo()
和 sw %lo()
可能有一个 lui %hi()
。
像lui x28 123
这样的risc-v指令,venus显示它的机器码是0x0007BE37
。
但是 lui
应该只加载立即数 123
的高 20
位。由于在十六进制中123
是0x0000007B
,我想对应的机器码应该是0x00000E37
.
我很疑惑为什么venus会产生不同的结果,是不是我的理解有问题lui
?
当您向 LUI
之类的指令提供一个数值作为文字时,一些汇编程序会将其作为您希望在操作说明。这对于生成汇编的编译器或想要使用 LUI
并为该指令中的 20 位指定确切的位模式而不受汇编器的任何干扰的汇编程序员来说非常重要和有用。
如果你想让它只占用文字的高 20 位,可以使用一些编译时函数1,比如 %hi
和 %lo
将接受,例如lui %hi(123)
— %hi
用于 lui
而 %lo
用于需要 12 个低位的指令,例如 addi
和 sw
/lw
.
1 这些可能最晚会被评估 link 时间。
这些函数(%hi
和 %lo
)由于传统选择与 lw
和 addi
等指令配对而变得复杂,其中它们的立即数组成12 位剩余 但它本身是有符号的 。因此,%hi
函数在特定情况下将值偏移 1,其中 lw
的偏移量将显示为负数,并在运行时用 1 进行符号扩展。因此,当这些配对 2 时,环境使事情正常进行,但是如果您要在 LUI
中使用 %hi()
一个随机常数而没有这样的配对,您可能没有得到您期望的确切 20 位。
2 只要函数参数匹配,多个 %lo
可以与相同的 %hi
配对。因此,例如,全局变量的 read/modify/write 序列对于 lw %lo()
和 sw %lo()
可能有一个 lui %hi()
。