解码的RISC-V汇编指令是什么:0001100 01010 11100 100 10001 1100011?从specification我知道,操作码是BLT指令,rs1 = x28,rs2 = x10。
但编码的偏移量是多少? imm[12|10:5]
是0001100 = 12而imm[4:1|11]
是10001 = -8,对吗?跳转到哪里去了?
答案 0 :(得分:2)
The RISC-V Instruction Set Manual 列出了第 19 章中的完整指令集。
opcode
(7 个最低有效位)告诉我们我们处理的是 B 类指令。
funct3
位 ([14:12]
) 指定 BLT
指令。
BLT
指令的编码如下:
这给了我们:
imm[12|10:5] | rs2 | rs1 | 函数3 | imm[4:1|11] | 操作码 | |
---|---|---|---|---|---|---|
说明 | 0001100 | 01010 | 11100 | 100 | 10001 | 1100011 |
价值 | 0xc | 0xa (x10) | 0x1c (x28) | 0x4 | 0x11 | 0x63 |
立即数是指令位[31|7|30:25|11:8]
的串联:0|1|001100|1000 = 0x4c8
。
请注意,立即数会遗漏索引 0
处的位。
The RISC-V Instruction Set Manual 状态在 2.3 Immediate Encoding Variants 中:
<块引用>基于立即数的处理,指令格式(B/J)还有两种变体,如图 2.3 所示。 S 和 B 格式之间的唯一区别是 12 位立即数字段用于在 B 格式中以 2 的倍数对分支偏移进行编码。 不是像传统那样在硬件中将指令编码的立即数中的所有位左移一,而是中间位 (imm[10:1]) 和符号位保持在固定位置,而 S 格式中的最低位 (inst[ 7]) 以 B 格式编码高位。
这是因为 RISC-V 有 16 位指令对齐约束(1.2 指令长度编码):
<块引用>基础 RISC-V ISA 具有固定长度的 32 位指令,必须在 32 位边界上自然对齐。但是,标准 RISC-V 编码方案旨在支持具有可变长度指令的 ISA 扩展,其中每条指令可以是任意数量的 16 位指令包长度,并且包在 16 位边界上自然对齐。第 12 章中描述的标准压缩 ISA 扩展通过提供压缩的 16 位指令来减少代码大小,并放宽对齐约束以允许所有指令(16 位和 32 位)在任何 16 位边界上对齐以提高代码密度。< /p>
因此,我们需要在偏移量中添加一个尾随 0
,这给我们:0|1|001100|1000|0 = 0x990
。
解码后的指令为:blt x28, x10, 0x990
答案 1 :(得分:1)
.word 0x18ae48e3
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
hello:
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
00000000 <hello-0x38>:
0: 18ae48e3 blt x28,x10,990 <hello+0x958>
4: 033e4a63 blt x28,x19,38 <hello>
8: 033e4863 blt x28,x19,38 <hello>
c: 033e4663 blt x28,x19,38 <hello>
10: 033e4463 blt x28,x19,38 <hello>
14: 033e4263 blt x28,x19,38 <hello>
18: 033e4063 blt x28,x19,38 <hello>
1c: 013e4e63 blt x28,x19,38 <hello>
20: 013e4c63 blt x28,x19,38 <hello>
24: 013e4a63 blt x28,x19,38 <hello>
28: 013e4863 blt x28,x19,38 <hello>
2c: 013e4663 blt x28,x19,38 <hello>
30: 013e4463 blt x28,x19,38 <hello>
34: 013e4263 blt x28,x19,38 <hello>
00000038 <hello>:
38: 013e4063 blt x28,x19,38 <hello>
3c: ff3e4ee3 blt x28,x19,38 <hello>
40: ff3e4ce3 blt x28,x19,38 <hello>
00000001001111100100001001100011
00000001001111100100000001100011
11111111001111100100111011100011
0 000000 1001111100100 0010 0 1100011
0 000000 1001111100100 0000 0 1100011
1 111111 1001111100100 1110 1 1100011
你确实看到如何从指令中提取这些数字,如文件所示?
0 0 000000 0010 0
0 0 000000 0000 0
1 1 111111 1110 0
0 0000 0000 0100 = 0x0004
0 0000 0000 0000 = 0x0000 (<-- hello label here)
1 1111 1111 1100 = 0x1FFC
好的,这里没有魔力,有时会有偏移,通常会有偏移。通常,下一条指令的地址是应用立即数的地方。以ARM为例,前面两条指令的地址是应用偏移量的地方。
from your instruction
0001100 01010 11100 100 10001 1100011
0 001100 01010 11100 100 1000 1 1100011
010011001000 (add implied zero for bit 0)
0 1001 1001 0000 = 0x990