let dataAddr: *const u32 = 0x10000000 as *const u32;
unsafe {
let data = core::ptr::read_volatile(dataAddr);
println!("{data}");
}
В реальном режиме процессора всё адресное пространство делится на одинаковые сегменты размером 65536 байт (
2
16
{\displaystyle 2^{16}} байт). Начало каждого последующего сегмента (так называемая База сегмента) смещено относительно базы предыдущего на минимальный размер сегмента, то есть на 16 байт (т. н. параграф). Таким образом, сегменты могут частично перекрывать друг друга. (Например, байт 17 сегмента 2 — это также и байт
1
=
17
−
16
{\displaystyle 1=17-16} сегмента 3, и байт
33
=
17
+
16
{\displaystyle 33=17+16} сегмента 1.)
База сегмента) смещено относительно базы предыдущего на минимальный размер сегмента, то есть на 16 байт (т. н. параграф). Таким образом, сегменты могут частично перекрывать друг друга.
Сам посчитай. 16 разрядный сегментный
регистр который сдвигался влево на 4 бита позволял тебе видеть только 20 бит адресов.
let TEST = 123;
let test = &TEST;
let test2 = test as *const i32;
let test3 = test2 as usize;
println!("{} {}", test3, test3);
let dataAddr: *mut u32 = usize::from_str_radix(&format!("{test3:X}"), 16).unwrap() as *mut u32;
println!("{dataAddr:?}");
unsafe {
let data = core::ptr::read_volatile(dataAddr);
println!("{data}{test3:X}");
}
да, я это изучаю как раз для ядра будущего, т.к. мне нужно будет записать загрузчик в первый сектор.
Я сейчас под aarch64, так что виндовое не сработает.
А как достать данные которыми я не владею?
Тогда тебе надо собственно без ОС запускать свою программу, раз ты хочешь напрямую с памятью работать.
#[no_std] и так далее. Segfault не будет, если не будет ос ;)
если ты собираешься делать ядро ОС, то тебя этот вопрос волновать не должен.