如何直接在 Ada 中访问内存地址



所以我是 Ada 的新手,我正在尝试在其中编写一个内核,但我似乎找不到任何关于如何正确执行此操作的好信息。在 C 中,我会写:

unsigned char* videoram = (char*) 0xB8000;
videoram[0] = 65;

直接访问视频RAM并向其写入"a"。我听说我需要使用 Ada 数组和其他编译指示才能在 Ada 中以类型安全的方式执行此操作。这种 Ada 编程有什么好的资源吗?

您可以使用

'Address 属性:

Videoram : String (1 .. Videoram_Size);
for Videoram'Address use 16#B8000#;
-- ...
Videoram (1) := 'a';

如果你不想使用字符串和字符,你可以定义你自己的数据类型,比如:

type Byte is mod 2**8; -- unsigned char
type Byte_Array is array (Natural range <>) of Byte;
Videoram : Byte_Array (0 .. Videoram_Size - 1);
for Videoram'Address use 16#B8000#;
-- ...
Videoram (0) := 65;
顺便说一句,您

甚至可以对索引进行范围检查,因此您不能在 Videoram 范围之外写入。

如果使用地址属性(即用于 Object'Address 使用 ...),则应使用 System.Storage_Elements 中的 To_Address() 函数,因为地址类型不必是整数。Ada 参考手册仅指出:

"地址是一个确定的、非限制的类型,具有可预先阐述的初始化"

而对于 System.Storage_Elements 中的Integer_Address类型,它指出:

"Integer_Address是一个(有符号或模块化)整数子类型。To_Address和To_Integer在此类型和地址之间来回转换。

因此,您确实应该使用:

对于对象'地址使用 To_Address( 16#B8000# );

从 T.E.D 的回答中要指出的最后一件事是,如果您担心使用此方法进行对象初始化,只需在声明后添加一个杂注 Import( Ada, your_object ),以便禁止默认初始化。

实际上有两种方法。

一种是设置指向要使用的地址的指针,并通过指针访问对象。

type Video_RAM_Pointer is access all My_Video_Ram_Struct;
package Convert is new System.Address_To_Access_Conversions (Video_RAM_Pointer);
Video_RAM : constant Video_RAM_Pointer := Convert.To_Access (16#B8000#);

另一种是将数据直接叠加在位置顶部。

Video_RAM : My_Video_RAM_Struct;
for Video_RAM'address use at 16#B8000#;

一般来说,我更喜欢使用前者。除其他问题外,后者算作声明,这意味着每次声明覆盖时,My_Video_RAM_Struct中具有初始化代码的任何字段都将重新初始化。此外,人们很容易过度使用(滥用)该功能来到处为对象着色,这对优化器和维护程序员来说既困难又困难。

指针方法只是告诉编译器假设给定的地址包含您告诉它的结构,恕我直言,这正是您想要发生的。

相关内容

  • 没有找到相关文章

最新更新