2012-05-30 42 views
3

所以我是Ada的新手,我试图编写一个内核,但我似乎无法找到任何有关如何正确执行此操作的良好信息。在C中,我会写:如何直接在Ada中访问内存地址?

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

直接访问视频ram并写入'a'。我听说我需要使用Ada数组和其他编译指令在Ada中以类型安全的方式执行此操作。这种Ada编程有没有很好的资源?

+0

oenones的进一步思考答案(和我的贡献) - 如果您只进行文本处理并知道屏幕边界,则可以将您的数组定义为2D数组,并且能够直接访问行和列位置而无需计算内存偏移每次。 (只是要小心行或列的主要问题(先到先得以及如何映射到你的内存段) – NWS

回答

4

可以使用'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范围之外进行编写。

+0

有没有类型安全的方式来定义一个2字节类型的第一个字节是一个字符,第二个彩色字节?因为这是视频内存每个字符的实际格式。 – MarkHammons

+0

@MarkHammons我有点困惑。你的意思是“视频内存每个字符_pair_”? (上次我检查了一个字节是一个字符的大小!) – NWS

+0

@NWS是的,每个字符,videoram需要一对字节。第一个字节是实际字符,第二个字节定义背景和前景色。例如,0x00是黑色的。在C中,“ videoram [0] = 65; videoram [1] = 0x00; videoram [2] = 66; videoram [3] = 0x00;”用黑色背景打印黑色的ab。 – MarkHammons

1

实际上有两种方法。

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

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中的任何字段都将重新初始化。此外,人们很容易滥用(滥用)该功能,以便在整个地方使用别名对象,这对优化器来说都很难,对维护程序员来说也很难。

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

2

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

“地址是一个明确的,nonlimited型与preelaborable初始化”

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

“Integer_Address是(签名或模块化)整数子类型To_Address和To_Integer在此类型和地址之间来回转换。“

所以,你应该使用:

为Object'Address使用To_Address(16#B8000#);

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

+0

这可能是作为对其他两个答案的评论完成的。然而,你是新的,可以使用代表,所以+1。 :-) –