Assembly 在RISC-V汇编中数据段的地址处写入一个字节
我正在编写一个RISC-V汇编程序,该程序需要将保存在寄存器中的一个字存储到.数据段中:Assembly 在RISC-V汇编中数据段的地址处写入一个字节,assembly,riscv,illegal-instruction,Assembly,Riscv,Illegal Instruction,我正在编写一个RISC-V汇编程序,该程序需要将保存在寄存器中的一个字存储到.数据段中: .section .rodata msg: .string "Hello World\n" .section .data num: .word 97 .section .text .global _start _start: li a1, 100 sw a1, num loop: j loop 但是当程序到达sw a1,num时,我得到错
.section .rodata
msg:
.string "Hello World\n"
.section .data
num:
.word 97
.section .text
.global _start
_start:
li a1, 100
sw a1, num
loop:
j loop
但是当程序到达sw a1,num时,我得到错误非法操作数'sw a1,num'。
如何将数据存储到.data段内的内存位置?你能给我一些提示吗?作为一般的经验法则,你在汇编程序中编写的程序集是它自己的编程语言,恰好看起来有点像RISC-V ISA手册中的内容。RISC-V是一个非常简单的ISA,因此对于大多数指令来说,ISA手册的语法和汇编程序所接受的语法实际上没有区别。这种情况在引用符号时开始出现,因为虽然您可以直接在汇编代码中填写立即数,但您可能希望依靠链接器来完成此操作,因为在链接时间之前您不知道实际的符号地址,并且它可能会随着您修改程序而更改 为了使链接器能够在代码中填写符号地址,您需要从汇编程序发出重定位,以便链接器以后可以填写这些地址。我在SiFive的博客上写了一整篇关于这个如何工作的博文,但我们刚刚刷新了网站,我不知道如何找到它: 在本例中,您实际上是在尝试编写实现以下C代码的程序集
int num = 97;
void func(int val) { num = val; }
您的原始答案中的所有数据都是正确的,所以这里唯一需要担心的是如何发出正确的指令。关于如何发射这些,您有几个选项。一种选择是将每个指令和重新定位显式写入源代码,如下所示
func:
lui t0, %hi(num)
sw a0, %lo(num)(a0)
ret
通过使用-mcmodel=medlow-mexplicit relocs-O3编译,可以从上面的C代码生成此程序集。GCC手册定义了控制代码生成的其他RISC-V后端特定选项
如果您对更多细节感兴趣,我们在GitHub上提供了一本汇编程序员手册:。它还远未完成,但我们希望得到帮助,指出问题或提供更多内容。store word sw指令的语法是
sw rs2, offset(rs1)
其中,偏移量是12位立即数操作数
编写sw a1、num时,会出现语法错误,汇编程序会出现以下故障:
foo.s: : Assembler messages:
foo.s::13: Error: illegal operands `sw a1,num'
解决此问题的最简单方法可能是使用load address la伪指令:
li a1, 100
la t0, num
sw a1, 0(t0)
由于la指令将地址完全加载到寄存器中,因此我们必须使用0作为偏移量
la伪指令扩展到程序计数器PC相对寻址,即使用objdump检查:
请注意,%hi和%lo汇编程序宏将32位地址拆分为其高20位和低12位部分,即%hinum+符号\ U ext%lonum=num。使用支持伪指令的汇编程序,并将地址num的高部分加载到暂存寄存器中。或者自己做。请记住,sw机器指令只有12个位移位。谢谢你的回复,我正在使用汇编程序riscv64未知elf,我如何使用这个汇编程序?感谢在编译器输出处查看存储到全局的函数,以了解如何使用lui。RISC-V有叮当声。准确地说,当你组装你的程序时,你会得到错误,而不是“当程序到达软件时”。错误消息由GNU as发出。我如何用0填充引导扇区来实现等效的x86。乘以508-$-$$db 0 sw a0,%lonuma0应该是sw a0,%lonumt0,对吗?
00000000000100b0 <_start>:
100b0: 06400593 addi a1,zero,100
100b4: 00001297 auipc t0,0x1
100b8: 01028293 addi t0,t0,16 # 110c4 <__DATA_BEGIN__>
100bc: 00b2a023 sw a1,0(t0)
li a1, 100
lui t0, %hi(num)
sw a1, %lo(num)(t0)