如何解决如何使用RISC-V架构的C.ADDI4SPN和C.ADDI16SP指令压缩子集?
我不知道如何正确调用这两个指令。第一条指令C.ADDI4SPN
的第一个操作数应该是一个寄存器,第二条操作数(如果我是对的话)应该是一个以4缩放的数字。
但是当我尝试调用指令时,我得到的消息是操作数是非法的。
第二条指令C.ADDI16SP
也是一样,唯一的区别是数字应按16缩放。
这些是手册中说明的描述:
C.ADDI16SP添加 立即将非零符号扩展的6位扩展到堆栈指针(sp = x2)中的值,其中 立即数被缩放为代表范围(-512,496)中16的倍数。
C.ADDI4SPN是仅CIW格式的RV32C / RV64C指令,它添加了零扩展的非零 立即,按4的比例缩放到堆栈指针x2,并将结果写入rd0
这些是我如何尝试使用说明的示例:
c.addi16sp 32
c.addi4spn x10,8
解决方法
首先回退(并了解程序集是特定于工具而不是目标)。
.hword 0x110c
0: 110c addi x11,x2,160
然后再尝试一些
.hword 0x110c
addi x11,160
addi x12,160
addi x13,160
addi x14,40
addi x14,4
00000000 <.text>:
0: 110c addi x11,160
2: 110c addi x11,160
4: 1110 addi x12,160
6: 1114 addi x13,160
8: 1118 addi x14,160
a: 1038 addi x14,40
c: 0058 addi x14,4
此指令用于生成指向堆栈分配的变量的指针,并扩展为addi rd',x2,nzuimm。
这是通过gnu汇编器和binutils中的objdump完成的。
您似乎需要一个四倍的立即数:
addi x14,4
addi x14,5
addi x14,6
addi x14,7
addi x14,8
00000000 <.text>:
0: 0058 addi x14,4
2: 00510713 addi x14,5
6: 00610713 addi x14,6
a: 00710713 addi x14,7
e: 0038 addi x14,8
将其优化为该指令。
,由于某些原因,我不知道,在使用这些指令时,我们必须命名sp
寄存器:
c.addi4sp,x10,sp,8
c.addi16sp sp,16
这可能是为了与未压缩的指令扩展保持一致,在此处您还必须命名为sp
。
但是,尽管有些人可能将此视为功能,但其他人(例如我自己)最多可能将其视为错误或奇怪之处,因为隐式寄存器(您永远都不能更改)可能不应该”显式使用压缩的操作码时,不需要以汇编形式。
从机器代码的角度来看,基本指令集(即无压缩)没有隐式寄存器-所有操作数都在机器指令中指定。
某些汇编助记符允许省略寄存器,然后由汇编程序在生成机器代码时填充该寄存器:jal
和ret
(伪指令),例如,不允许或不需要汇编程序命名一个寄存器,但这些指令的机器代码有一个rd
/ rs1
寄存器字段,分别由汇编程序用x1
/ ra
填充。
要使用c.lwsp
,我们还要指定sp
寄存器,因此它看起来很像lw
指令。并且c.jal
看起来像jal
伪指令,假设x1
作为链接寄存器-尽管c.jal
确实将硬编码x1
作为隐式目标寄存器,从机器代码的角度来看,jal
的翻译不是。
所以,我想他们想要的是与未压缩的指令汇编形式的最大兼容性。而且我猜想这使反汇编更加可口,因为它无法告诉您最初使用的是压缩操作码还是汇编指令压缩指令(尽管我不确定使用未压缩的指令显示反汇编的压缩指令是多么值得可压缩形式)。
test.s:
.text
c.addi4spn a0,8 # compressed instruction,must name sp
addi a0,8 # non-compressed instruction,gets compressed to c.addi4spn
c.addi16sp sp,16 # compressed instruction,must name sp
addi sp,16 # non-compressed instruction,gets compressed to c.addi
c.addi16sp sp,128 # compressed instruction,128 # non-compressed instruction,gets compressed to c.addi16sp
Disassembly of section .text:
00000000 <.text>:
0: 0028 addi a0,8 # c.addi4spn
2: 0028 addi a0,8 # c.addi4spn
4: 6141 addi sp,16 # c.addi16sp
6: 0141 addi sp,16 # c.addi
8: 6109 addi sp,128 # c.addi16sp
a: 6109 addi sp,128 # c.addi16sp
您可以看到,即使汇编器可能已经或可能未将非压缩指令语法转换为压缩的等效语法,反汇编程序仍假定您使用(或想要查看)非压缩指令语法。
,如@Erik Eidt所述,您必须命名sp寄存器。
该选择是在riscv-opc.c中进行的。
https://github.com/riscv/riscv-binutils-gdb/blob/riscv-binutils-2.35/opcodes/riscv-opc.c
如果您看一下,您有以下两个定义:
{"c.addi4spn",INSN_CLASS_C,"Ct,Cc,CK",MATCH_C_ADDI4SPN,MASK_C_ADDI4SPN,match_c_addi4spn,0 },{"c.addi16sp","Cc,CL",MATCH_C_ADDI16SP,MASK_C_ADDI16SP,match_c_addi16sp,
Ct Cc CK和CL是操作数:
Ct:/ * RS2 x8-x15 * /
抄送:sp(这就是为什么需要sp的原因)。
RVC_ADDI4SPN_IMM和RVC_ADDI16SP_IMM的CK和CL。
在objdump中添加addi的原因是:
{"addi",INSN_ALIAS },
和
{"addi",
由于它们是在前面的声明之前声明的,因此objdump匹配一个addi。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。