【问题标题】:RISC-V branch offset machine instruction encodingRISC-V 分支偏移机器指令编码
【发布时间】:2018-05-23 21:25:15
【问题描述】:

0001100 01010 11100 100 10001 1100011 解码后的 RISC-V 汇编指令是什么?从specification 我知道,操作码是 BLT 指令,rs1 = x28, rs2 = x10。

但是编码的偏移量是多少? imm[12|10:5] 是 0001100 = 12 和 imm[4:1|11] 是 10001 = -8,对吗?跳到哪里去?

【问题讨论】:

  • 您可以使用反汇编程序为您完成。我认为 GNU binutils 有一个 RISC-V 后端。
  • 是的,binutils 支持 risc-v。
  • 遗憾的是,指令集文档通常没有完全或正确地涵盖偏移量。发现有一个假定的偏移量并不少见,或者立即是指令数与字节数或类似的东西......所以你通常必须使用现有工具来解决这个问题,或者这可能意味着你工作在那里,您只需走到一个薯条人立方体并问...
  • 创建一个包含 .word 0x18ae48e3 的文件,组装然后反汇编。将其链接到某个非零地址,然后再次反汇编。
  • 感谢您的帮助@old_timer。我用 riscv64-unknown-elf-gcc 组装了一个包含main: word .0x18ae48e3 的文件。通过反汇编二进制文件,gdb 给了我0x0000000000000000 <+0>: blt t3,a0,0x990。所以我假设解码后的偏移量是 0x990。

标签: assembly machine-code riscv


【解决方案1】:

The RISC-V Instruction Set Manual 列出了第 19 章中的完整指令集。 opcode(7 个最低有效位)告诉我们我们处理的是 B 类指令。 funct3 位 ([14:12]) 指定 BLT 指令。

BLT指令编码如下:

这给了我们:

imm[12|10:5] rs2 rs1 funct3 imm[4:1|11] opcode
instruction 0001100 01010 11100 100 10001 1100011
value 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 Manual2.3 立即编码变体中声明

还有两种基于立即数处理的指令格式 (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 位边界上对齐以提高代码密度。

因此,我们需要在偏移量中添加一个尾随 0,这给了我们:0|1|001100|1000|0 = 0x990

解码指令为:blt x28, x10, 0x990

【讨论】:

    【解决方案2】:
    .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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-27
      • 2018-11-22
      • 2023-03-22
      • 2023-04-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多