如何在Rust中修改指定内存地址并读写对应值?
Rust中如何通过指针读写指定内存地址的值?
我在Rust中声明了指针(内存地址),并能够通过以下代码读取值:
let psram = 0x60000000 as *const u32; let psramh = 0x60000000 as *const u16; let psramb = 0x60000000 as *const u8; let psram0 = unsafe {psram.offset(0)}; rprintln!( "RAM[0]: 0x{:X?} (Uninitialized)\r\n", psram0 );但我不清楚如何为这些内存地址设置并显示对应的值,在C语言中我会这样实现(显示部分用Rust代码):
psram[0] = 0x01234567; psram[1] = 0x89ABCDEF; rprintln!( "RAM[0]: 0x{:#02x} (Byte)\r\n", psramb[0] ); rprintln!( "RAM[0]: 0x{:#04x}(Halfword)\r\n", psramh[0] ); rprintln!( "RAM[0]: 0x{:X?} (Word)\r\n", psram[0] ); rprintln!( "RAM[4]: 0x{:X?}\r\n", psram[1] );请问在Rust中该如何实现对应的功能?
实现方案
首先明确:Rust里要写内存必须用可变指针(*mut T),*const T是只读的;所有指针读写操作都得放在unsafe块里——毕竟Rust没法保证你指定的内存地址是合法可访问的。
1. 声明可变指针
把原来的只读指针改成可变指针,才能进行写入:
let psram = 0x60000000 as *mut u32; let psramh = 0x60000000 as *mut u16; let psramb = 0x60000000 as *mut u8;
2. 写入内存值
对应C里的数组赋值,Rust有两种等价写法:
- 解引用偏移后的指针直接赋值
- 用
write方法(语义更明确,避免潜在的未定义行为)
示例:
unsafe { // 对应C的psram[0] = 0x01234567; *psram = 0x01234567; // offset(0)可以省略,直接用原指针 // 对应C的psram[1] = 0x89ABCDEF; psram.offset(1).write(0x89ABCDEF); }
3. 读取并打印值
读取同样要在unsafe块里解引用指针,和C的数组访问逻辑一致:
unsafe { rprintln!("RAM[0]: 0x{:#02x} (Byte)", *psramb); rprintln!("RAM[0]: 0x{:#04x} (Halfword)", *psramh); rprintln!("RAM[0]: 0x{:X?} (Word)", *psram); rprintln!("RAM[4]: 0x{:X?}", *psram.offset(1)); }
完整代码
use defmt_rprintln as rprintln; // 如果你用的是defmt的打印宏,需要导入 fn main() { // 指向指定内存地址的可变指针 let psram = 0x60000000 as *mut u32; let psramh = 0x60000000 as *mut u16; let psramb = 0x60000000 as *mut u8; // 写入数据到目标内存 unsafe { *psram = 0x01234567; psram.offset(1).write(0x89ABCDEF); } // 读取并打印各粒度的内存值 unsafe { rprintln!("RAM[0]: 0x{:#02x} (Byte)", *psramb); rprintln!("RAM[0]: 0x{:#04x} (Halfword)", *psramh); rprintln!("RAM[0]: 0x{:X?} (Word)", *psram); rprintln!("RAM[4]: 0x{:X?}", *psram.offset(1)); } }
重要提示
offset方法的参数是元素数量,不是字节数:比如psram.offset(1)对应的是原地址+4字节(因为u32占4字节),和C的psram[1]完全一致。- 如果只是读取内存,用
*const T没问题,但写入必须用*mut T。 - 所有指针操作都在
unsafe块里,因为你要自己保证内存地址的合法性——比如这个地址确实是可读写的PSRAM区域,不会触发访问错误。
内容的提问来源于stack exchange,提问作者Adrien Chapelet
相关产品推荐
相关产品推荐

