简体   繁体   English

RISC-V 汇编器正在用 bne + jal 替换 beq 指令

[英]RISC-V assembler is replacing beq instructions by bne + jal

I have this RISC-V assembly program:我有这个 RISC-V 汇编程序:

addi        x2,x0,5
addi        x3,x0,12
addi        x7,x3,-9
or          x4,x7,x2
and         x5,x3,x4
add         x5,x5,x4
beq         x5,x7,0x48

I want to get the assembled instructions in hex.我想获得十六进制的汇编指令。 format to load them in an FPGA.格式以将它们加载到 FPGA 中。 I get those values by executing the following:我通过执行以下命令获得这些值:

#!/bin/bash

# Given a source assembly file, assembly it and display
# the hex values for each instruction

SRC_FILE=$1

RV_AS=riscv64-unknown-elf-as
RV_OBJCOPY=riscv64-unknown-elf-objcopy

$RV_AS -o /tmp/gen_asm_instr.elf $SRC_FILE -march=rv32ima
$RV_OBJCOPY -O binary /tmp/gen_asm_instr.elf /tmp/gen_asm_instr.bin
xxd -e -c 4 /tmp/gen_asm_instr.bin | cut -d ' ' -f 2

If I comment out the last assembly instruction ( beq ), everything works.如果我注释掉最后一条汇编指令( beq ),一切正常。 I get the following result:我得到以下结果:

00500113
00c00193
ff718393
0023e233
0041f2b3
004282b3

Those are 6 instructions, everything fine.那是6条指令,一切都很好。 However, if I uncomment the last instruction, I get:但是,如果我取消注释最后一条指令,我会得到:

00500113
00c00193
ff718393
0023e233
0041f2b3
004282b3
00729463
0000006f

Those are 8 instructions.这是8条指令。 If I "dis-assemble" the above, I get:如果我“分解”上述内容,我会得到:

Dis-assemble拆卸

# Create a file 'template.txt' with the above instructions:
00000000: 00500113 00c00193 ff718393 0023e233
00000010: 0041f2b3 004282b3 00729463 0000006f

# Use xxd and obdjump to recover the assembly instructions
xxd -r template.txt > a.out # generate a binary file
xxd -e a.out > a-big.txt    # switch endianness
xxd -r ./a-big.txt > a2.out # generate a bin. file with the switched endianness
riscv64-unknown-elf-objdump -M no-aliases -M numeric -mabi=ilp32 -b binary -m riscv -D ./a2.out    # dis-assemble it

Result :结果

./a2.out:     file format binary


Disassembly of section .data:

0000000000000000 <.data>:
   0:   00500113            addi    x2,x0,5
   4:   00c00193            addi    x3,x0,12
   8:   ff718393            addi    x7,x3,-9
   c:   0023e233            or  x4,x7,x2
  10:   0041f2b3            and x5,x3,x4
  14:   004282b3            add x5,x5,x4
  18:   00729463            bne x5,x7,0x20
  1c:   0000006f            jal x0,0x1c

So the RISC-V assembler is transforming the beq instruction in two: bne and jal .因此 RISC-V 汇编器将beq指令转换为两个: bnejal

Why this happens?为什么会发生这种情况? How can I avoid it?我怎样才能避免它?

EDIT编辑

I have tried with this online assembler:我试过这个在线汇编器:

https://riscvasm.lucasteske.dev/ https://riscvasm.lucasteske.dev/

and the same happens.同样的事情也会发生。

The build system seems to do that when using a hard-coded numeric address for the branch target.当使用硬编码的数字地址作为分支目标时,构建系统似乎会这样做。 Can't explain why it chooses to do that but I will note that that jal has a much farther reach (20 bit immediate) than beq (12 bit immediate).无法解释为什么它选择这样做,但我会注意到jalbeq (12 位立即数)具有更远的范围(20 位立即数)。 As both bxx and jal are PC-relative, neither supports absolute addressing.由于bxxjal都是 PC 相关的,因此都不支持绝对寻址。 The assembler might not know where the code will be located, and so is giving you additional range to reach that absolute address.汇编器可能不知道代码的位置,因此为您提供了额外的范围以到达该绝对地址。

If you use a label as branch target it won't do that when within reach.如果您使用标签作为分支目标,它不会在触手可及的情况下这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM