Skip to content

Latest commit

 

History

History
85 lines (69 loc) · 2.11 KB

File metadata and controls

85 lines (69 loc) · 2.11 KB

rust-playground 有一个遗憾是不支持 target 切换,compiler explorer 倒是可以切换

只不过我很好奇为什么 rustc --emit=asm 输出非常多的汇编代码而 playground/explorer 倒是很整洁只有用户定义的函数相应的汇编

于是我看了下原来 compiler explorer 的 filter 选项有过滤掉 unused labels 且 Output 选项有 demangle

再看看 playground 源码 demangle_asm() 函数 rust-playground/compiler/base/asm-cleanup/src/lib.rs

内部则是调用 rust-lang/rustc-demangle,试试看 demangle 效果首先我们先生成下汇编代码

rustc --emit=asm --crate-type=lib --target=riscv64gc-unknown-none-elf s.rs

#![no_std]
pub fn a(a: isize) -> isize {
    fn b(b: isize) -> isize {
        b
    }
    b(a)
}

在 rust-playground 源码中写一个测试用例

#[test]
fn x() {
    let code = std::fs::read_to_string("/home/w/temp/s.s").unwrap();
    let code = demangle_asm(&code);
    let code = filter_asm(&code);
    println!("{code}");
}

将 compiler explorer 默认选项输出为 intel 语法去掉,于是我们输出结果就跟 playgrond/explorer 完全一致了

s::a:
        pushq   %rax
        callq   s::a::b
        // 悟了,rcx 在这里没啥用,只是随便找个寄存器存 pop 指令结果
        popq    %rcx
        retq

s::a::b:
        movq    %rdi, %rax
        retq
第一个整型参数会通过rdi寄存器传递
第二个整型参数会通过rsi寄存器传递
第三个整型参数会通过rdx寄存器传递
第四个整型参数会通过rcx寄存器传递

返回值在 rax
#include <stddef.h>
size_t b(const size_t b) { return b; }
size_t a(const size_t a) { return b(a); }
b:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        pop     rbp
        ret
a:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 8
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        mov     rdi, rax
        call    b
        leave
        ret