我对%hi()
汇编程序函数有问题。这个问题是RISC-V GNU汇编程序特有的.编写此程序:
lui a4,%hi(0x0001ff00) # Does not give what I expect
lui a4,0x1f #
.word 0x0001f737 #
使用
riscv32-unknown-elf-as -o strange_lui.o strange_lui.s
riscv32-unknown-elf-objdump -D strange_lui.o
给
strange_lui.o: file format elf32-littleriscv
Disassembly of section .text:
00000000 <.text>:
0: 00020737 lui a4,0x20
4: 0001f737 lui a4,0x1f
8: 0001f737 lui a4,0x1f
我相信这三行应该编译成相同的代码。我在这里错过了什么?我在用:
riscv32-unknown-elf-as -v
GNU assembler version 2.31.1 (riscv32-unknown-elf) using BFD version (GNU Binutils) 2.31.1
发布于 2018-11-19 19:26:16
%hi(...)
函数比它看上去更聪明。它不仅返回给定参数的前20位。
%hi
希望在一个lui
指令中使用,该指令很快就会被另一个指令所遵循,比如add %lo(...)
,它将通过提供低12位来完成寄存器的32位负载。
在执行add
指令期间,将对这些低12位进行符号扩展,以生成32位值,然后将其添加到寄存器的原始内容中。当低位12的顶部位为0时,此符号扩展步骤对现有寄存器的前20位没有影响。然而,当低位12的顶部位是“1”时,符号扩展的效果是从寄存器的上20位的现有值中减去一个。
在这种情况下,%hi(0x0001ff00)
函数看到下面12的最左边是'1‘。因此,它预测将由以下add %lo(0x0001ff00)
执行的减法,并将0x00020
写入寄存器的前20位。该0x00020
将通过预期的符号扩展add
转换为所需的0001f
。
如果您希望您的程序为所有三条语句生成相同的指令,请为%hi
提供一个参数,其低12位在其最左边的位置为0。像lui %hi(0x0001f700)
这样的人就能做到这一点。
发布于 2018-12-04 20:56:32
总之,如果与"%lo()“返回的有符号值一起使用,"%hi()”宏将假定有符号int值。
我甚至不认为"lui“指令是假设的,这可能是其他任何直接价值的指令。这是您在示例中使用的内容,但是还有许多其他RV指令使用即时参数
因此,应该有另一种形式,如"%hu()",与"%lu()“一起使用,以避免使用低部分的这个符号扩展,甚至不假定将使用"%lu()”。
https://stackoverflow.com/questions/53379306
复制相似问题