我們由之前的 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 整理的 !
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。
Interrupt gate與task gate的主要差別在於interrupt gate會將EFLAG的IP位元清除,而task gate則不會去變更IP位元。Linux不使用task gate。
--jollen