我對某個exe堆棧的位置感到有點困惑。我知道程序運行前,CRT通過分配一定數量的堆(它由分配頁面的操作系統分配)來初始化堆,但堆棧在哪裏?它是否也在一個頁面上?或者它是由用戶模式(ring3)中的所有程序通過在GDT上使用ring3描述符共享的(我認爲不是,但我不確定)?Windows上的堆棧 - 它在哪裏?
4
A
回答
5
Windows將爲每個線程保留一個連續的虛擬內存區域(默認爲1MB)。然後,它提交該內存區域的幾個最頂層頁面,並將其標記爲守護頁之下的一對。隨着線程的堆棧向下增長,如果訪問防護頁面,則會發生異常,並且Windows會提交防護頁面並將其標記爲守衛。
您可以使用出色的SysInternals實用程序VMMap探索此行爲。下面是該工具的代碼段:
3
每個線程都有自己的堆棧。這只是爲此目的分配的一塊內存。
所有內存中的頁面分配,包括堆棧(在Windows上,我相信堆棧默認爲1MB,所以它會跨越多個頁面,因爲大多數內存頁是4KB。)
但它的真的只是堆棧指針寄存器指向的一塊內存。
1
Windows中的每個程序都是一個進程。過程通常不會在彼此之間分享他們的回憶。
共享和不共享是每個進程的虛擬地址空間如何映射到物理內存的問題。
如果兩個進程將其地址空間的一部分映射到物理內存的相同頁面上,那麼這些內存就會被它們有效地共享,並且每個進程都可以讀取並可能寫入它並觀察其他進程的寫入。
共享堆棧內存沒有意義,所以每個進程都有自己的堆棧。實際上,流程更像容器。執行代碼並使用堆棧的實體是線程。每個過程至少有一個線程。線程有自己的堆棧,但由於進程的線程位於相同的虛擬地址空間,因此它們可以訪問其他堆棧。有時在線程之間共享堆棧數據很有用,但應該小心謹慎,以免破壞線程狀態並導致掛起或崩潰。
相關問題
- 1. 堆棧函數的實現在哪裏?
- 2. Linux ISR的堆棧在哪裏
- 3. 堆棧內存的說明 - 它在哪裏?
- 4. PyGTK事件堆棧在哪裏?
- 5. VISA在OSI堆棧上的位置在哪裏?
- 6. x86堆棧指針指向哪裏?
- 7. 哪裏(正好)是調用堆棧?
- 8. 哪裏變長數組/ ALLOCA堆棧
- 9. 「堆」在哪裏?
- 10. 堆在哪裏?
- 11. Windows上的「catalina.out」在哪裏?
- 12. Windows上的gitweb.conf在哪裏?
- 13. 這個內存在哪裏分配 - 堆或堆棧?
- 14. 創建線程對象在哪裏?堆棧還是堆?
- 15. 在哪裏創建動態大小數組? (堆棧或堆)
- 16. 在Windows上增加堆棧大小(GCC)
- 17. 我的Django/uWSGI vassal的堆棧跟蹤記錄在哪裏?
- 18. 在堆棧上創建對象時分配的內存在哪裏?
- 19. Android - 崩潰發生,但堆棧跟蹤沒有說明它發生在哪裏
- 20. 從Linux進程分配的堆棧內存在哪裏?
- 21. binami lampp堆棧的htdocs在哪裏?我必須做到嗎?
- 22. Bigcommerce Stencil堆棧中定義的這些scss函數在哪裏?
- 23. 哪裏在Rails 3堆棧基於cookie_store的會話驗證?
- 24. Chrome 53中的「分配堆棧」選項卡在哪裏
- 25. 堆棧跟蹤的其餘部分在哪裏?
- 26. 在MEAN.js堆棧中,我可以在哪裏配置jshint警告?
- 27. 在哪裏放置persistentStoreDescriptions?在Swift3 Coredata樣板堆棧
- 28. 在C#中分配任務堆棧在哪裏?
- 29. ASP.NET的黃色死亡屏幕 - 它從哪裏得到堆棧跟蹤?
- 30. 構造函數調用的存儲位置在哪裏?堆棧還是堆?
獲得創建線程時,因此對於單線程應用中,當應用程序啓動時創建的主線程的堆棧堆棧初始化時,應該這也是由crt完成? –
crt無法做到 - 它可能不是C程序!即使是這樣,堆棧必須在crt運行之前設置,否則crt將無法使用堆棧,即。它將無法使用任何自動變量,參數或進行任何函數調用。 Windows操作系統加載器設置初始堆棧,由EXE/DLL/SYS /任何PE頭中的數據指示。 –