当我编译下面的rust代码时:
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
loop {}
}
fn mult(a: u32, b: u32) -> u32 {
return a * b;
}
#[no_mangle]
fn main() -> u32 {
return mult(3, 4);
}
通过命令
rustc --target riscv32i-unknown-none-elf -Ctarget-feature=+m -O simple.rs
然后运行
llvm-objdump -d simple
我得到以下输出,没有任何指示:
simple: file format ELF32-riscv
但是当我做
rustc --target riscv32i-unknown-none-elf -Ctarget-feature=+m -O --emit asm simple.rs
然后查看生成的simple.s
文件:
.text
.attribute 4, 16
.attribute 5, "rv32i2p0_m2p0"
.file "simple.5d8cddf570d1dcfb-cgu.0"
.section .text.rust_begin_unwind,"ax",@progbits
.hidden rust_begin_unwind
.globl rust_begin_unwind
.p2align 2
.type rust_begin_unwind,@function
rust_begin_unwind:
.LBB0_1:
j .LBB0_1
.Lfunc_end0:
.size rust_begin_unwind, .Lfunc_end0-rust_begin_unwind
.section .text.main,"ax",@progbits
.globl main
.p2align 2
.type main,@function
main:
li a0, 12
ret
.Lfunc_end1:
.size main, .Lfunc_end1-main
.section ".note.GNU-stack","",@progbits
我试过安装RISC-V GNU Toolchain并编译类似的C程序,然后运行llvm-objdump
,这样我就得到了预期的指令输出。
我还试图在二进制文件中通过它们的操作码以编程方式找到这些存在于simple.s
中的指令,但无济于事。
我做错了什么?为什么反汇编与simple.s
不同?我如何让rustc编译一个实际指令的二进制文件?
1条答案
按热度按时间pepwfjgg1#
默认链接器脚本可能使用符号
_start
作为程序入口点,而不是main
。(我无法在RISC-V目标上验证这一点。)如果缺少_start
符号,则传统链接器的行为是使用最低的文本地址(即使没有代码,也由节位置确定)。Rust与--gc-sections
链接,因此最终的二进制文件不包含您的main
代码,即使它包含在程序集中。如果我将
main
重命名为_start
,我将在输出二进制文件中获得一些机器码,但当然这不太可能工作,因为缺少所需的初始化。Rust RISC-V团队建议使用
riscv-rt
crate和[#entry]
macro。