2012-05-30 40 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。 :-) –