2017-09-12 179 views
0

我是for ***'Address use ***的新用法。我想知道這種用法有什麼限制。所以,我創建了以下程序:EXCEPTION_ACCESS_VIOLATION靜態聲明

procedure letshack (A : System.Address) is 
     My_String : String(1..100000); 
     for My_String'Address use A; 
    begin 
     Put(My_String); 
    end; 

這提出一個EXCEPTION_ACCESS_VIOLATION同時用字符串是100長度相同的代碼不養它。如果我不使用整數地址,則此代碼可以正常工作。

那麼for ***'Address use ***的用法有什麼限制。 Ps:我正在使用Ada 95,但歡迎任何信息。

編輯: 我瞭解一部分行爲。這就是我想的。 當你開始你的程序時,一個堆棧被分配,你可以寫入和讀入。事實上,我有一個整數地址

Real Addresses |----------------------------| Virtual Addresses 
     0x48000|Stack Origine    |0x00 
       |       | 
       |       | 
       |       | 
       |       | 
       |End of Stack    | 
    0x48000+range|----------------------------|0x00+range 

寫了5個字節,你會得到EXCEPTION_ACCESS_VIOLATION如果你是出棧。如果它是正確的話,那麼「強」語言似乎很奇怪。因爲這意味着你可以重寫自己的堆棧並使其行爲不當。

+0

這可能取決於呼叫 - 特別是A的實際 - 而不是程序本身。製作一個演示的[MCVE]。顯然,如果整個字符串不屬於你的過程,會發生不好的事情。如果你正在嘗試編寫病毒,那麼它的語言要比Ada更好:-) –

+1

每當你做一個Address overlay時,你也應該做一個'pragma Import(Ada,My_String);'(或等價的方面),爲了防止重疊對象的默認初始化(本例中爲My_String) – egilhh

+1

@BrianDrummond彙編語言,因爲地址計算,位大小問題,抑制檢查等的可能性在標準Ada中都是可用的和明確的,病毒可以使Ada的功能獲利。使用SPARKAda,病毒的算法甚至可能被驗證並可能被驗證。如果真的想在專業環境中編寫病毒,看起來並不那麼糟糕。 – B98

回答

0

如果您已確保您已在內存的可讀部分中分配了100_000個連續字符(從A開始),那麼它應該可以工作。

如果A是另一個Ada實體的地址,它不應該工作。

+0

我的問題是,當字符串長度爲100時,它將工作,而我給整個地址的過程。這似乎很奇怪。 96個下一個字節被分配了嗎?或者這與在非分配內存中寫入相同? –

+0

您可能很幸運,100個字符在同一個內存頁面上。如果您可以控制內存分配(在操作系統級別),則可以使用任意大的對象。我用數百萬字符的字符串完成了它。 –

+0

是的,我剛剛寫了一個答案,它似乎是關於頁面。但它似乎並沒有那麼幸運,因爲這個字符串可以在程序中放置4096。 –

0

Finnaly找到了該行爲。 當你啓動你的程序時,你使用的地址是一個頁面中的虛擬地址。 這處理虛擬ADRESS系統的一部分,使其成爲內存具有一定規模分配給你的進程取決於您的系統上顯示下面的架構中不變:

Real Addresses |----------------------------| Virtual Addresses 
     0x48000|Begin of the virtual address|0x00 
       |range      | 
       |       | 
       |       | 
       |End of the virtual address | 
       |range      | 
    0x48000+range|----------------------------|0x00+range 

你可以做任何事情,而不在其中分配變量。例如,在我的窗戶上,根據si.dwPageSize中的變量<windows.h>,此尺寸爲4096 bytes。 而我測試了我的字符串可以是4096字節長但不是4097字節。我現在必須在我的嵌入式系統上測試它,但似乎接近事實。