riscv objdump -d 的输出不清楚

hid*_*atz 1 linux assembly elf objdump riscv

现在我正在尝试了解 RISC-V ISA,但我对机器代码和汇编有不清楚的地方。

我写了这样的C代码:

int main() {
    return 42;
}
Run Code Online (Sandbox Code Playgroud)

然后,我通过以下命令生成了 .s 文件:

$ /opt/riscv/bin/riscv64-unknown-linux-gnu-gcc -S 42.c

输出是:

        .file   "42.c"
        .option nopic
        .text
        .align  1
        .globl  main
        .type   main, @function
main:
        addi    sp,sp,-16
        sd      s0,8(sp)
        addi    s0,sp,16
        li      a5,42
        mv      a0,a5
        ld      s0,8(sp)
        addi    sp,sp,16
        jr      ra
        .size   main, .-main
        .ident  "GCC: (g5964b5cd727) 11.1.0"
        .section        .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

现在,我运行以下命令来生成一个精灵。

$ /opt/riscv/bin/riscv64-unknown-linux-gnu-gcc -nostdlib -o 42 42.s

这样,就生成了一个二进制文件。我尝试通过 objdump 读取该内容,如下所示:

$ /opt/riscv/bin/riscv64-unknown-linux-gnu-objdump -d 42

所以输出是这样的:


42:     file format elf64-littleriscv


Disassembly of section .text:

00000000000100b0 <main>:
   100b0:       1141                    addi    sp,sp,-16
   100b2:       e422                    sd      s0,8(sp)
   100b4:       0800                    addi    s0,sp,16
   100b6:       02a00793                li      a5,42
   100ba:       853e                    mv      a0,a5
   100bc:       6422                    ld      s0,8(sp)
   100be:       0141                    addi    sp,sp,16
   100c0:       8082                    ret
Run Code Online (Sandbox Code Playgroud)

我不明白的是 objdump 输出中机器代码的含义。例如,第一条指令addi被翻译为.....0010011根据此页面(虽然这不是官方规范)。然而,转储的十六进制是11411141只能表示2个字节,但指令应该是32位,4个字节。

我想我遗漏了一些点,但是我应该如何读取 riscv 的 objdump 的输出?

小智 5

您可以通过以下方式告诉 objdump 显示压缩(16 位)指令-M no-aliases

riscv64-unknown-elf-objdump -d -M no-aliases
Run Code Online (Sandbox Code Playgroud)

在这种情况下,以 开头的指令c.是压缩指令。

不幸的是,这也会禁用一些其他别名,如果您习惯了它们,则会使汇编变得不太好读。您只需查看十六进制转储中的字节数(2 与 4)即可确定它是否是压缩指令。