
我知道有一個約定,但是當您呼叫 to而不是 時syscall
,您將其前面的呼叫約定稱為什麼,就像這樣。int 80
syscall
mov rax,4 ; system call number (sys_write)
mov rbx,1 ; file descriptor (stdout)
mov rcx,hello ; message to write
mov rdx,12 ; message length
int 0x80 ; call kernel
我讀這裡之後的參數rdx
是esi
, edi
, ebp
(或對於 x64 rsi
, rdi
, rbp
),我沒有看到它記錄在維基百科的呼叫約定頁面, 但整數80小時似乎表明 Windows 也使用此約定?
這個約定叫什麼名字。在 Linux 核心原始碼中的哪裡可以看到它的定義?並且,rax
當您呼叫時解析過程的表在哪裡int 0x80
?對於syscall
,sys_write
是rax=1
答案1
您的問題涵蓋了許多主題,我將盡力解決所有主題。
我不確定調用系統調用的方式有一個單一的規範術語,更不用說調用系統調用的特定方式(中斷 0x80 而不是
SYSENTER
orSYSCALL
)。在 x86-64 上,有記錄的System V x86-64 ABI 中描述了使用 的系統呼叫接口SYSCALL
,但這只是提供信息,而不是規範性的。同樣,雖然如果您將其稱為“i386 Linux 核心ABI”(用您正在談論的任何架構替換“i386”),大多數人都會理解您在說什麼,但這也可能會令人困惑,因為“內核ABI」有另一個含義(在核心模組的上下文中),並且這不僅限於中斷 0x80。在實踐中,大多數人無論如何都不應該關心這種細節級別的細節,特別是因為它們可以演變:中斷 0x80
SYSCALL
等,正如您提到的,而且vDSO 也引入了自己的微妙之處,並且是首選的入口點對於現在 x86 上的所有系統呼叫...當然,這並不意味著不能有一個術語來指代特定的呼叫約定,但我不確定它是否會有那麼有用。Windows 也支援使用中斷作為其係統呼叫介面 0x2E,但其「呼叫約定」是很不一樣:參數被壓入堆疊,請求的系統呼叫由EAX給出,EBX指向堆疊上的參數。
目前的 x86 核心定義了系統呼叫介面
arch/x86/entry
:entry_32.S
包含 i386 接口,entry_64.S
x86-32 和 x86-64 接口,entry_64_compat.S
32 位元 x86-64 介面(用於向後相容),syscalls/syscall_32.tbl
i386系統呼叫表,syscalls/syscall_64.tbl
x86-32 和 x86-64 系統呼叫表。這些檔案中的註解記錄了接口,特別是如何傳遞參數:對於 32 位元調用,EAX 包含系統調用號,其參數放置在 EBX、ECX、EDX、ESI、EDI 和 EBP 中(參數本身為
SYSENTER
,指向包含中斷參數0x80 的用戶堆疊的指標);對於 64 位元調用,RAX 包含系統調用號,其參數放在 RDI、RSI、RDX、R10、R8 和 R9 中(另請參閱為什麼系統呼叫暫存器和順序從Intel 32位元變成64位元?)。有一個很好的總結,裡面有圖表calling.h
。
附帶說明一下,歷史比較通常參考 MS-DOS 呼叫接口,該接口主要使用中斷0x21;它還包括多路復用中斷,0x2F,其中提供了可擴展的機制用於新增系統服務(通常涉及 TSR;設備驅動程式大多使用不同的介面)。