我懷疑任何人都可以很有信心地告訴你,但我會採取刺。
我的猜測是,在技術上沒有堆棧運行是可行的,但獲得正確的細節將是非常困難的。
中斷和異常(例如,頁面錯誤)應將寄存器保存到內核堆棧而不是用戶空間堆棧,因此這沒有問題。如果直接在彙編中編碼,系統調用甚至應該可以工作(除非你在32位模式下運行並且使用5個以上的參數,在這種情況下,第六個在用戶堆棧上,但你仍然可以很容易地修復它)。 gdb希望你的堆棧安排如此。
其他事情要考慮:
通常,您被分配在啓動時堆棧區域。不確定;你可以通過適當的鏈接器指令來改變它。堆棧區域通常配置爲向下生長。當地址不在任何當前分配的區域中時出現頁面錯誤時,假定要生成堆棧區域。錯誤地址不得少於sp
(即esp/rsp
)(少於64K軟件)的值。我想這不是一個問題,如果你不使用堆棧。
當您調用clone
系統調用來創建一個新任務(線程)時,您爲新任務提供了一個堆棧指針。我不確定內核究竟做了什麼,看起來只是填入新任務中的sp
寄存器(如果它不爲零)。這導致我...
clone
系統調用和其他一些沒有很好地指定。 libc中嵌入了許多魔術來正確處理fork
,pthread_create
等等。如果你想創建額外的線程,你必須知道這個魔法並自己實現它。
信號處理希望能夠將參數推送到用戶空間堆棧。我不認爲你可以在沒有堆棧的情況下使用信號 - 或者至少它會非常複雜。
爲什麼你認爲堆棧這樣的負擔? *「如果我要編寫一個程序......」* - 爲什麼不嘗試編寫這樣一個不重要的程序來查看這是否可能? *「我安全地將堆棧指針設置爲0 ...」* - 除非你破解內核,否則*你希望這樣做?僅供參考許多處理器體系結構和C語言(以及其他高級語言)都需要堆棧,因此它不僅僅是Linux操作系統。 IOW C和Linux通常僅用於具有硬件堆棧支持的處理器。 – sawdust
@sawdust在評論中很難回答你所有的問題。我不能僅僅測試它,因爲這並不能保證我所做的事實際上是允許的;它可能恰好適用於我的測試,並打破下一個內核版本或體系結構。堆棧指針可以通過'movq $ 0,%rsp'進行簡單的修改,不需要內核入侵。 x86只需要一個用於ISR的堆棧,這與用戶空間無關(當然,您不能推/ pop/call/ret)。另外,我知道C,但那不是我的問題。我詢問_kernel_是否需要一個有效的_user space_堆棧。 –
爲了給出更多的上下文:我不一定要完全避免堆棧(儘管這將是一個有趣的實驗)。我正在考慮使用適合當前線程/光纖的最大調用圖的正確大小的非常小的堆棧。這意味着堆棧有時可能完全滿,並且不一定在頁面邊界上結束。我想確定內核可以處理這種情況。也許用不同的方式來解釋這個問題:Linux內核是否需要用戶空間來遵循特定的ABI? –