日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

系统调用(int 0x80)详解

發布時間:2023/12/19 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 系统调用(int 0x80)详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、系統調用初始化

在系統啟動時,會在sched_init(void)函數中調用set_system_gate(0x80,&system_call),設置中斷向量號0x80的中斷描述符:

#define set_system_gate(n,addr)  _set_gate(&idt[n],15,3,addr)

其中15表示此中斷號對應的是陷阱門,注意,這個中斷向量不是中斷門描述符。比如硬盤中斷(hd_interrupt)或定時器中斷(timer_interrupt)等硬件類的中斷才設置為中斷門描述符。陷阱門是可被中斷的。關于陷阱門與中斷門的區別,及陷阱門中DPL為0或3原因,請參考書本《linux 0.12》的14.19的解釋,還有第四章部分內容,這些已經解釋的很清楚了。

Int 0x80的輸入輸出參數說明:

輸入參數:eax=功能號(比如2為fork系統調用)

用功能對應sys_call_table[]的下標,比如sys_call_table[2]表示fork系統調用函數。

fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,

返回值:EAX=sys_fork函數的返回值

2、system_call的實現

當調用_system_call函數時,系統就從用戶態進入了內核態。注意,特權變化了!對于x86系統,因為所有的寄存器都只有一個物理寄存器(ARM就不一要樣了),因為內核態與用戶態共享所有寄存器(段、通用、棧寄存器),比如SS、ESP、eflags、CS、EIP這五個寄存器。為了能夠從內核態返回到調用處繼續執行,當前現場,即相關寄存器的內容都需要被保存起來。

那么,這些現場信息保存到那里呢?為什么不能保存到用戶態堆棧,如果保存了用戶態堆棧,那么,這些棧內存區域,用戶程序就可以必改定,那么,程序就很容易被攻擊了,直接修改CS:EIP對應的棧內存,那么,你懂的^_^。

現場信息是保存在當前進程的內核態堆棧中,由于已經進入了內核態,在_system_call函數中執行push操作,此時被push的數據是存儲也就在內核棧中。SS、ESP、eflags、CS、EIP這五個寄存器的內容是怎么進入內核棧的呢?是程序從用戶態進入了內核態時,即在執行_system_call函數中的指令之前,硬件已經自動把SS、ESP、eflags、CS、EIP五個寄存器壓入了內核棧,然后,根據函數的需要,再保存相關通用、段之類寄存器。當從內核返回用戶態時,這五個寄存器會自動從內核棧中恢復。

_system_call部分代碼分析:

push %ds

push %es

push %fs

pushl %eax # save the orig_eax

pushl %edx

pushl %ecx # push %ebx,%ecx,%edx asparameters

pushl %ebx # to the system call

movl $0x10,%edx // ds、es此時指向當前進程的內核態數據段

mov %dx,%ds

mov %dx,%es

movl $0x17,%edx //即使沒這二行也行吧,fs本來就指向當前進程的用戶態數據段

mov %dx,%fs //因為在fork進程時,fs已經在copy_process函數中設置了。

call_sys_call_table(,%eax,4) //根據EAX傳入的功能號,即可調用相關系統函數

pushl %eax //系統調用函數的返回值入棧

關于進程狀態的變化,參考書上的說明,這部分,理解的還不夠,后續再分析???

當在中斷處理函數(陷阱門)中執行時,是可被中斷(中斷門)的,因為eflags標志中的TF被設置為允許中斷的。因而有可能在時鐘中斷函數(do_timer)中,本進程的時間片可能被修改為0。所以,當從系統調用相關功能號對應函數返回時,需要檢查當前進程是否還在就緒態,或時間片是否用完,并確認是否需要重新執行調度程序。

2: movl _current,%eax

cmpl $0,state(%eax) # state

jne reschedule

cmpl $0,counter(%eax) # counter

je reschedule

//系統調用返回時,會處理當前任務的信號,進程的信號識別與信號處理,僅在系統調用或時鐘中斷(每10ms)返回時。就能處理信號,優先級還是蠻高的,至少在進程執行流中,到少每10m就能處理信號。

ret_from_sys_call:

movl _current,%eax

cmpl _task,%eax # task[0] cannot havesignals

je 3f

cmpw $0x0f,CS(%esp) # was old code segment supervisor?

jne 3f

cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?

jne 3f

movl signal(%eax),%ebx

movlblocked(%eax),%ecx

notl %ecx

andl %ebx,%ecx

bsfl %ecx,%ecx

je 3f

btrl %ecx,%ebx

movl %ebx,signal(%eax)

incl %ecx

pushl %ecx

call _do_signal //調用信號處理函數處理當前進程信號

popl %ecx

testl %eax, %eax

jne 2b # see if we need toswitchtasks, or do more signals

3: popl %eax

popl %ebx

popl %ecx

popl %edx

addl $4, %esp # skip orig_eax

pop %fs

pop %es

pop %ds

iret //此指令會將內核棧中的數據彈出到這5個寄存器SS、ESP、eflags、CS、EIP。

from:http://www.voidcn.com/blog/maowenl/article/p-1845345.html

總結

以上是生活随笔為你收集整理的系统调用(int 0x80)详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。