Kernel
系統呼叫:使用者程序如何向/從核心傳遞/接收數據?
使用者和核心虛擬地址之間的關係之前已經在幾個問題中討論過(下面的連結),但據我了解,使用者程序無法讀取或寫入核心地址。
那麼,使用者程序如何從核心共享和接收數據呢?
是通過記憶嗎?如果是這樣,記憶體佈局在哪裡?也許CPU寄存器?
相關問題:
讓我們考慮一個例子:一個用於 Linux 的簡單 x86 Hello World程序,它列印一條消息
stdout
並退出。它需要將幾個數據項傳遞給核心:
- 要輸出的文本字元串,
- 退出程式碼。
這是彙編程式碼(使用 FASM 編譯):
format ELF executable segment readable executable ; system call numbers SYS_EXIT=1 SYS_WRITE=4 ; file descriptors STDOUT=1 entry $ start: mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, message mov edx, messageLength int 0x80 mov eax, SYS_EXIT xor ebx, ebx ; exit code 0 int 0x80 message: db "Hello, world!",0xa messageLength=$-message
該程序為實現其主要目標(消息輸出)所做的一切是
- 將適當的 CPU 寄存器設置為代表系統呼叫號(用於
sys_write
系統呼叫)、文件描述符 (stdout
)、消息地址和消息長度的值- 執行系統呼叫,在本例中通過軟體中斷 0x80
類似的順序是退出:將寄存器設置為系統呼叫號和退出程式碼,然後進行系統呼叫。
哪些寄存器設置為哪些值由系統呼叫呼叫約定定義。
在核心開始執行系統呼叫處理程序後,該處理程序從應用程序的上下文中讀取寄存器的值,並根據呼叫約定解釋它們。特別是,當它看到系統呼叫是
sys_write
時,它會獲取消息的長度和地址,並使用它們從使用者空間記憶體中讀取。然後這些數據(連同文件描述符)被傳遞給將執行實際工作的驅動程序。