rust - 删除内联 mips 程序集中附加的 "break"指令

标签 rust mips inline-assembly

我有以下(简化的)函数,使用内联汇编,目标是 mips:

#[naked]
pub unsafe extern "C" fn test() {
    asm!(
        ".set noreorder",
        "jr $ra",
        "li $v0, 0x123",
        options(noreturn),
    )
}

我希望它只编译成 2 条指定的指令(在 Release模式下),因为它是一个裸函数,但是 break 指令被附加在最后:

00000000 <test>:
   0:   03e00008        jr      ra
   4:   24020123        li      v0,291
   8:   0000000d        break

我假设这是针对 rustc 或 llvm 未定义行为的对策,但我需要生成我在函数中指定的确切程序集。

有什么方法可以防止 rustc、llvm 或汇编器生成这条额外的指令?

我在现有目标上测试了它,例如 mipsel-unknown-none 并且它还生成了一个 break 指令,但我正在编译以下自定义目标,如果它事项:

{
    "arch": "mips",
    "cpu": "mips1",
    "data-layout": "e-m:m-p:32:32-i8:8:32-i16:16:32-i32:32-n32-S32",
    "emit-debug-gdb-scripts": false,
    "executables": false,
    "features": "+mips32,+soft-float,+noabicalls",
    "linker": "rust-lld",
    "linker-flavor": "ld.lld",
    "llvm-target": "mipsel-unknown-linux-gnu",
    "relocation-model": "static",
    "target-pointer-width": "32",
    "panic-strategy": "abort",
    "singlethread": true,
    "dynamic-linking": false,
    "function-sections": true
}

我还使用了一个 #![no_std]#![no_core] staticlib crate 实现了所需的 lang 项目和只需使用 cargo build --release --target=my-target.json

进行编译

编辑:根据 Peter Cordes 的建议,我在 C 中尝试了同样的方法

__attribute__((naked)) void test() {
    __asm__(
        ".set noreorder\n"
        "jr $ra\n"
        "li $v0, 0x123\n"
    );
}

编译使用

clang -O3 test.c -c -o test.o -target mips-unknown-none

结果是

00000000 <test>:
   0:   03e00008    jr  ra
   4:   24020123    li  v0,291

没有 break,所以它似乎被 rust 编译器包含了。

最佳答案

是的!执行以下操作之一:

  • "trap_unreachable": false 添加到您的 target.json
  • 使用 RUSTFLAGS=-Ztrap-unreachable=no 构建。 (但仅限夜间)

不幸的是,它没有很好的文档记录。进一步阅读:PR where the trap instruction generation was added PR where trap-unreachable=no was added

关于rust - 删除内联 mips 程序集中附加的 "break"指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69712756/

相关文章:

visual-studio-code - 如何在 Visual Studio Code 中禁用 Rust 变量及其方法的下划线?

macros - 在语法扩展中使用程序标识符

gcc - 如何在 ARM GCC 内联汇编中指定单个寄存器作为约束?

c++ - 内联 assembly 约束修饰符 = 和 +

rust - LLVM 优化器不尊重使用 Rust 内联 asm 设置非默认舍入模式?

c++ - 仅当对象不存在于 map 中时,如何使用 Rust 将新对象插入到 map 中?

opencv - 为 mips 处理器交叉编译 opencv

assembly - MIPS 中的整数绝对值?

arrays - Mips,如何读取数组并打印它们?

c++ - 在什么情况下我想在 C/C++ 代码中使用内联汇编代码