System Call 專題討論, #4:x86 的 Interrupt

jollen 發表於 December 1, 2006 4:36 PM

我們由之前的 hello.S 程式範例來做切入:

movl $len,%edx
movl $msg,%ecx
movl $1,%ebx
movl $4,%eax
int $0x80

System call 編號 4(%eax = 4)為 sys_write 函數,其原型宣告如下:

ssize_t sys_write(unsigned int fd, const char * buf, size_t count)

根據 sys_write 的參數宣告,我們必須傳遞參數如下:

˙ 第 1 個參數為 unsigned int fd,透過 %ebx 暫存器傳值。
˙ 第 2 個參數 const char * buf 透過 %ecx 暫存器傳遞位址(address)。
˙ 第 3 個參數 size_t count 透過 %edx 暫存器傳值。

這個部份的話嘛,大家不妨翻閱一下 Jollen 整理的 LSCT

x86 的 Interrupt

x86的interrupt(中斷)可分別系統定義與使用者自訂:

˙ 中斷向量0~8、10~14、16~18:predefined interrupts and exceptions。
˙ 中斷向量19-31:保留。
˙ 中斷向量32-255:user-defined interrupts(maskable interrupts)。

每個中斷都有一個編號,稱為interrupt vector(中斷向量);當中斷產生後,就會跳至相對應的interrupt handler執行程式。Interrupt handler程式的所在位址經由interrupt descriptor table(IDT)來得知。

Enternal interrupt、software interrupts與exception都是透過IDT來處理,IDT裡存放的是gate descriptor,gate descriptor的種類有:

˙ interrupt gate
˙ trap gate
˙ task gate

中斷的處理過程如下:

1. 中斷產生。

2. CPU根據interrupt vector來索引IDT裡的gate descriptor。

3. 如果 gate descriptor 是 interrupt gate,trap gate則以類似call gate方式呼叫handler procedure。如果是task gate,則透過task switch 來呼叫handler。

x86_gate.JPG

Interrupt gate與task gate的主要差別在於interrupt gate會將EFLAG的IP位元清除,而task gate則不會去變更IP位元。Linux不使用task gate。

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw