以下是链接器脚本的片段.

.data :
{
    *(.data*)
}
> ram
. = ALIGN(4);

/* Set Stack after code & data */
_stack_start = .;

我如何访问rust(没有std库)中的_stack_start(堆栈的起始地址)?

#![no_std]
#![no_main]
#![allow(dead_code)]

#[no_mangle]
pub fn _start() {
    // let sp: i32 = _stack_start; -> **This causes compilation error**

    type FnPtr = fn() -> ();
    let th: FnPtr = trap_handler;

    unsafe {
        asm!("csrw mtvec, {}" ,
            in(reg) th);
    }

    loop {}
}

推荐答案

嘿,我真的没有办法运行你的代码,但this source似乎做到了你想要实现的.我建议你通读一遍,但我会把重要的部分写在答案里.

它们在链接器脚本中创建符号:

.data : AT(ADDR(.rodata) + SIZEOF(.rodata))
{
  _sdata = .;
  *(.data .data.*);
  _edata = .;
} > RAM

随后宣布其 rust 蚀为extern "C":

extern "C" {
    static mut _sdata: u8;
    static mut _edata: u8;
}

之后,他们以这种方式使用其中的address个符号:

let count = &_edata as *const u8 as usize - &_sdata as *const u8 as usize;

至于为什么rust代码使用这些变量的地址而不是它们的值,我会把你们引向this,所以请回答.

我不知道为什么变量被声明为u8,但它们是通过其地址访问的,该地址被强制转换为usize,所以我怀疑它们的类型可能对编译器不重要.

Rust相关问答推荐

为什么是!为Rust中的RwLockReadGuard和RwLockWriteGuard实现的发送特征?

重新导出proc宏导致未解决的extern crate错误""

rust 蚀将动力特性浇到混凝土 struct 上是行不通的

关于如何初始化弱 struct 字段的语法问题

Pin<;&;mut可能将Uninit<;T>;>;合并为Pin<;&;mut T>;

使用Py03从Rust调用Python函数时的最佳返回类型

如何初始化选项<;T>;数组Rust 了?

返回Result<;(),框<;dyn错误>>;工作

如何在 Rust 中编写一个通用方法,它可以接受任何可以转换为另一个值的值?

为什么切片时需要参考?

Rust 如何将链表推到前面?

Rust中是否可以在不复制的情况下从另一个不可变向量创建不可变向量?

注释闭包参数强调使用高阶排定特征界限

为什么 File::read_to_end 缓冲区容量越大越慢?

为什么1..=100返回一个范围而不是一个整数?

如果我不想运行析构函数,如何移出具有析构函数的 struct ?

TcpStream::connect - 匹配武器具有不兼容的类型

编写 TOML 文件以反序列化为 struct 中的枚举

为什么这里需要类型注解?

令人困惑的错误消息? (解包运算符)