原文地址:http://blog.csdn.net/geekcome/article/details/6398414
系統(tǒng)調(diào)用是一個(gè)軟中斷莽使,中斷號(hào)是0x80惫皱,它是上層應(yīng)用程序與Linux系統(tǒng)內(nèi)核進(jìn)行交互通信的唯一接口臀栈。
這個(gè)中斷的設(shè)置在kernel/sched.c中441行函數(shù)中
[cpp]view plaincopy
void?sched_init(void)??
{??
int?i;??
struct?desc_struct?*?p;??
if?(sizeof(struct?sigaction)?!=?16)??
panic("Struct?sigaction?MUST?be?16?bytes");??
????set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));??
????set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));??
????p?=?gdt+2+FIRST_TSS_ENTRY;??
for(i=1;i
????????task[i]?=?NULL;??
????????p->a=p->b=0;??
????????p++;??
????????p->a=p->b=0;??
????????p++;??
????}??
/*?Clear?NT,?so?that?we?won't?have?troubles?with?that?later?on?*/??
__asm__("pushfl?;?andl?$0xffffbfff,(%esp)?;?popfl");??
????ltr(0);??
????lldt(0);??
outb_p(0x36,0x43);/*?binary,?mode?3,?LSB/MSB,?ch?0?*/??
outb_p(LATCH?&?0xff?,?0x40);/*?LSB?*/??
outb(LATCH?>>?8?,?0x40);/*?MSB?*/??
????set_intr_gate(0x20,&timer_interrupt);??
????outb(inb_p(0x21)&~0x01,0x21);??
????set_system_gate(0x80,&system_call);??
}??
最后一句就將0x80中斷與system_call(系統(tǒng)調(diào)用)聯(lián)系起來隅居。
通過int 0x80祖灰,就可使用內(nèi)核資源尿招。不過诀豁,通常應(yīng)用程序都是使用具有標(biāo)準(zhǔn)接口定義的C函數(shù)庫間接的使用內(nèi)核的系統(tǒng)調(diào)用窄刘,即應(yīng)用程序調(diào)用C函數(shù)庫中的函數(shù),C函數(shù)庫中再通過int 0x80進(jìn)行系統(tǒng)調(diào)用舷胜。
所以娩践,系統(tǒng)調(diào)用過程是這樣的:
應(yīng)用程序調(diào)用libc中的函數(shù)->libc中的函數(shù)引用系統(tǒng)調(diào)用宏->系統(tǒng)調(diào)用宏中使用int 0x80完成系統(tǒng)調(diào)用并返回
下面是sys_call_table的定義文件
位于./include/sys.h
[cpp]view plaincopy
extern?int?sys_setup?();????//?系統(tǒng)啟動(dòng)初始化設(shè)置函數(shù)。?(kernel/blk_drv/hd.c,71)??
extern?int?sys_exit?();?????//?程序退出烹骨。?(kernel/exit.c,?137)??
extern?int?sys_fork?();?????//?創(chuàng)建進(jìn)程翻伺。?(kernel/system_call.s,?208)??
extern?int?sys_read?();?????//?讀文件。?(fs/read_write.c,?55)??
extern?int?sys_write?();????//?寫文件沮焕。?(fs/read_write.c,?83)??
extern?int?sys_open?();?????//?打開文件吨岭。?(fs/open.c,?138)??
extern?int?sys_close?();????//?關(guān)閉文件。?(fs/open.c,?192)??
extern?int?sys_waitpid?();??//?等待進(jìn)程終止峦树。?(kernel/exit.c,?142)??
extern?int?sys_creat?();????//?創(chuàng)建文件辣辫。?(fs/open.c,?187)??
extern?int?sys_link?();?????//?創(chuàng)建一個(gè)文件的硬連接旦事。?(fs/namei.c,?721)??
extern?int?sys_unlink?();???//?刪除一個(gè)文件名(或刪除文件)。?(fs/namei.c,?663)??
extern?int?sys_execve?();???//?執(zhí)行程序急灭。?(kernel/system_call.s,?200)??
extern?int?sys_chdir?();????//?更改當(dāng)前目錄姐浮。?(fs/open.c,?75)??
extern?int?sys_time?();?????//?取當(dāng)前時(shí)間。?(kernel/sys.c,?102)??
extern?int?sys_mknod?();????//?建立塊/字符特殊文件葬馋。?(fs/namei.c,?412)??
extern?int?sys_chmod?();????//?修改文件屬性卖鲤。?(fs/open.c,?105)??
extern?int?sys_chown?();????//?修改文件宿主和所屬組。?(fs/open.c,?121)??
extern?int?sys_break?();????//?(-kernel/sys.c,?21)??
extern?int?sys_stat?();?????//?使用路徑名取文件的狀態(tài)信息畴嘶。?(fs/stat.c,?36)??
extern?int?sys_lseek?();????//?重新定位讀/寫文件偏移扫尖。?(fs/read_write.c,?25)??
extern?int?sys_getpid?();???//?取進(jìn)程id。?(kernel/sched.c,?348)??
extern?int?sys_mount?();????//?安裝文件系統(tǒng)掠廓。?(fs/super.c,?200)??
extern?int?sys_umount?();???//?卸載文件系統(tǒng)。?(fs/super.c,?167)??
extern?int?sys_setuid?();???//?設(shè)置進(jìn)程用戶id甩恼。?(kernel/sys.c,?143)??
extern?int?sys_getuid?();???//?取進(jìn)程用戶id蟀瞧。?(kernel/sched.c,?358)??
extern?int?sys_stime?();????//?設(shè)置系統(tǒng)時(shí)間日期。?(-kernel/sys.c,?148)??
extern?int?sys_ptrace?();???//?程序調(diào)試条摸。?(-kernel/sys.c,?26)??
extern?int?sys_alarm?();????//?設(shè)置報(bào)警悦污。?(kernel/sched.c,?338)??
extern?int?sys_fstat?();????//?使用文件句柄取文件的狀態(tài)信息。(fs/stat.c,?47)??
extern?int?sys_pause?();????//?暫停進(jìn)程運(yùn)行钉蒲。?(kernel/sched.c,?144)??
extern?int?sys_utime?();????//?改變文件的訪問和修改時(shí)間切端。?(fs/open.c,?24)??
extern?int?sys_stty?();?????//?修改終端行設(shè)置。?(-kernel/sys.c,?31)??
extern?int?sys_gtty?();?????//?取終端行設(shè)置信息顷啼。?(-kernel/sys.c,?36)??
extern?int?sys_access?();???//?檢查用戶對(duì)一個(gè)文件的訪問權(quán)限踏枣。(fs/open.c,?47)??
extern?int?sys_nice?();?????//?設(shè)置進(jìn)程執(zhí)行優(yōu)先權(quán)。?(kernel/sched.c,?378)??
extern?int?sys_ftime?();????//?取日期和時(shí)間钙蒙。?(-kernel/sys.c,16)??
extern?int?sys_sync?();?????//?同步高速緩沖與設(shè)備中數(shù)據(jù)茵瀑。?(fs/buffer.c,?44)??
extern?int?sys_kill?();?????//?終止一個(gè)進(jìn)程。?(kernel/exit.c,?60)??
extern?int?sys_rename?();???//?更改文件名躬厌。?(-kernel/sys.c,?41)??
extern?int?sys_mkdir?();????//?創(chuàng)建目錄马昨。?(fs/namei.c,?463)??
extern?int?sys_rmdir?();????//?刪除目錄。?(fs/namei.c,?587)??
extern?int?sys_dup?();??????//?復(fù)制文件句柄扛施。?(fs/fcntl.c,?42)??
extern?int?sys_pipe?();?????//?創(chuàng)建管道鸿捧。?(fs/pipe.c,?71)??
extern?int?sys_times?();????//?取運(yùn)行時(shí)間。?(kernel/sys.c,?156)??
extern?int?sys_prof?();?????//?程序執(zhí)行時(shí)間區(qū)域疙渣。?(-kernel/sys.c,?46)??
extern?int?sys_brk?();??????//?修改數(shù)據(jù)段長(zhǎng)度匙奴。?(kernel/sys.c,?168)??
extern?int?sys_setgid?();???//?設(shè)置進(jìn)程組id。?(kernel/sys.c,?72)??
extern?int?sys_getgid?();???//?取進(jìn)程組id昌阿。?(kernel/sched.c,?368)??
extern?int?sys_signal?();???//?信號(hào)處理饥脑。?(kernel/signal.c,?48)??
extern?int?sys_geteuid?();??//?取進(jìn)程有效用戶id恳邀。?(kenrl/sched.c,?363)??
extern?int?sys_getegid?();??//?取進(jìn)程有效組id。?(kenrl/sched.c,?373)??
extern?int?sys_acct?();?????//?進(jìn)程記帳灶轰。?(-kernel/sys.c,?77)??
extern?int?sys_phys?();?????//?(-kernel/sys.c,?82)??
extern?int?sys_lock?();?????//?(-kernel/sys.c,?87)??
extern?int?sys_ioctl?();????//?設(shè)備控制谣沸。?(fs/ioctl.c,?30)??
extern?int?sys_fcntl?();????//?文件句柄操作。?(fs/fcntl.c,?47)??
extern?int?sys_mpx?();??????//?(-kernel/sys.c,?92)??
extern?int?sys_setpgid?();??//?設(shè)置進(jìn)程組id笋颤。?(kernel/sys.c,?181)??
extern?int?sys_ulimit?();???//?(-kernel/sys.c,?97)??
extern?int?sys_uname?();????//?顯示系統(tǒng)信息乳附。?(kernel/sys.c,?216)??
extern?int?sys_umask?();????//?取默認(rèn)文件創(chuàng)建屬性碼。?(kernel/sys.c,?230)??
extern?int?sys_chroot?();???//?改變根系統(tǒng)伴澄。?(fs/open.c,?90)??
extern?int?sys_ustat?();????//?取文件系統(tǒng)信息赋除。?(fs/open.c,?19)??
extern?int?sys_dup2?();?????//?復(fù)制文件句柄。?(fs/fcntl.c,?36)??
extern?int?sys_getppid?();??//?取父進(jìn)程id非凌。?(kernel/sched.c,?353)??
extern?int?sys_getpgrp?();??//?取進(jìn)程組id举农,等于getpgid(0)。(kernel/sys.c,?201)??
extern?int?sys_setsid?();???//?在新會(huì)話中運(yùn)行程序敞嗡。?(kernel/sys.c,?206)??
extern?int?sys_sigaction?();????//?改變信號(hào)處理過程颁糟。?(kernel/signal.c,?63)??
extern?int?sys_sgetmask?();?//?取信號(hào)屏蔽碼。?(kernel/signal.c,?15)??
extern?int?sys_ssetmask?();?//?設(shè)置信號(hào)屏蔽碼喉悴。?(kernel/signal.c,?20)??
extern?int?sys_setreuid?();?//?設(shè)置真實(shí)與/或有效用戶id棱貌。?(kernel/sys.c,118)??
extern?int?sys_setregid?();?//?設(shè)置真實(shí)與/或有效組id。?(kernel/sys.c,?51)??
//?系統(tǒng)調(diào)用函數(shù)指針表箕肃。用于系統(tǒng)調(diào)用中斷處理程序(int?0x80)婚脱,作為跳轉(zhuǎn)表。??
fn_ptr?sys_call_table[]?=?{?sys_setup,?sys_exit,?sys_fork,?sys_read,??
??sys_write,?sys_open,?sys_close,?sys_waitpid,?sys_creat,?sys_link,??
??sys_unlink,?sys_execve,?sys_chdir,?sys_time,?sys_mknod,?sys_chmod,??
??sys_chown,?sys_break,?sys_stat,?sys_lseek,?sys_getpid,?sys_mount,??
??sys_umount,?sys_setuid,?sys_getuid,?sys_stime,?sys_ptrace,?sys_alarm,??
??sys_fstat,?sys_pause,?sys_utime,?sys_stty,?sys_gtty,?sys_access,??
??sys_nice,?sys_ftime,?sys_sync,?sys_kill,?sys_rename,?sys_mkdir,??
??sys_rmdir,?sys_dup,?sys_pipe,?sys_times,?sys_prof,?sys_brk,?sys_setgid,??
??sys_getgid,?sys_signal,?sys_geteuid,?sys_getegid,?sys_acct,?sys_phys,??
??sys_lock,?sys_ioctl,?sys_fcntl,?sys_mpx,?sys_setpgid,?sys_ulimit,??
??sys_uname,?sys_umask,?sys_chroot,?sys_ustat,?sys_dup2,?sys_getppid,??
??sys_getpgrp,?sys_setsid,?sys_sigaction,?sys_sgetmask,?sys_ssetmask,??
??sys_setreuid,?sys_setregid??
};??
其中sys_call_table的類型是fn_ptr類型勺像,其中sys_call_table[0]元素為sys_setup,它的類型是fn_ptr類型障贸,它實(shí)際上是函數(shù)sys_setup的
入口地址。
它的定義如下:
typedef int (*fn_ptr) (); // 定義函數(shù)指針類型吟宦。
下面的實(shí)例代碼有助于理解函數(shù)指針:
[cpp]view plaincopy
#include??
typedef?int?(*MyFunc)();??
MyFunc?Func1;??
int?Func2()??
{??
????printf("This?is?a?sample?output!/n");??
????return?0;??
}??
int?main()??
{??
????Func1=Func2;??
????//Func2();??
????//(*Func1)();??
????printf("%x/n",(*Func1));??
????printf("%x/n",Func2);??
????return?0;??
}??
system_call系統(tǒng)調(diào)用入口函數(shù)
[cpp]view plaincopy
####?int?0x80?--linux?系統(tǒng)調(diào)用入口點(diǎn)(調(diào)用中斷int?0x80惹想,eax?中是調(diào)用號(hào))。??
.align?2??
_system_call:??
cmpl?$nr_system_calls-1,%eax?#?調(diào)用號(hào)如果超出范圍的話就在eax?中置-1?并退出督函。??
ja?bad_sys_call??
push?%ds?#?保存原段寄存器值嘀粱。??
push?%es??
push?%fs??
pushl?%edx?#?ebx,ecx,edx?中放著系統(tǒng)調(diào)用相應(yīng)的C?語言函數(shù)的調(diào)用參數(shù)。??
pushl?%ecx?#?push?%ebx,%ecx,%edx?as?parameters??
pushl?%ebx?#?to?the?system?call??
movl?$0x10,%edx?#?set?up?ds,es?to?kernel?space??
mov?%dx,%ds?#?ds,es?指向內(nèi)核數(shù)據(jù)段(全局描述符表中數(shù)據(jù)段描述符)辰狡。??
mov?%dx,%es??
movl?$0x17,%edx?#?fs?points?to?local?data?space??
mov?%dx,%fs?#?fs?指向局部數(shù)據(jù)段(局部描述符表中數(shù)據(jù)段描述符)锋叨。??
#?下面這句操作數(shù)的含義是:調(diào)用地址?=?_sys_call_table?+?%eax?*?4。參見列表后的說明宛篇。??
#?對(duì)應(yīng)的C?程序中的sys_call_table?在include/linux/sys.h?中娃磺,其中定義了一個(gè)包括72?個(gè)??
#?系統(tǒng)調(diào)用C?處理函數(shù)的地址數(shù)組表。??
call?_sys_call_table(,%eax,4)??
pushl?%eax?#?把系統(tǒng)調(diào)用號(hào)入棧叫倍。??
movl?_current,%eax?#?取當(dāng)前任務(wù)(進(jìn)程)數(shù)據(jù)結(jié)構(gòu)地址??eax偷卧。??
#?下面97-100?行查看當(dāng)前任務(wù)的運(yùn)行狀態(tài)豺瘤。如果不在就緒狀態(tài)(state?不等于0)就去執(zhí)行調(diào)度程序。??
#?如果該任務(wù)在就緒狀態(tài)但counter[??]值等于0听诸,則也去執(zhí)行調(diào)度程序坐求。??
cmpl?$0,state(%eax)?#?state??
jne?reschedule??
cmpl?$0,counter(%eax)?#?counter??
je?reschedule??
#?以下這段代碼執(zhí)行從系統(tǒng)調(diào)用C?函數(shù)返回后,對(duì)信號(hào)量進(jìn)行識(shí)別處理晌梨。??
ret_from_sys_call:??
#?首先判別當(dāng)前任務(wù)是否是初始任務(wù)task0桥嗤,如果是則不必對(duì)其進(jìn)行信號(hào)量方面的處理,直接返回仔蝌。??
#?103?行上的_task?對(duì)應(yīng)C?程序中的task[]數(shù)組泛领,直接引用task?相當(dāng)于引用task[0]。??
movl?_current,%eax?#?task[0]?cannot?have?signals??
cmpl?_task,%eax??
je?3f?#?向前(forward)跳轉(zhuǎn)到標(biāo)號(hào)3敛惊。??
#?通過對(duì)原調(diào)用程序代碼選擇符的檢查來判斷調(diào)用程序是否是超級(jí)用戶渊鞋。如果是超級(jí)用戶就直接??
#?退出中斷,否則需進(jìn)行信號(hào)量的處理瞧挤。這里比較選擇符是否為普通用戶代碼段的選擇符0x000f??
#?(RPL=3篓像,局部表,第1?個(gè)段(代碼段))皿伺,如果不是則跳轉(zhuǎn)退出中斷程序。??
cmpw?$0x0f,CS(%esp)?#?was?old?code?segment?supervisor????
jne?3f??
#?如果原堆棧段選擇符不為0x17(也即原堆棧不在用戶數(shù)據(jù)段中)盒粮,則也退出鸵鸥。??
cmpw?$0x17,OLDSS(%esp)?#?was?stack?segment?=?0x17????
jne?3f??
#?下面這段代碼(109-120)的用途是首先取當(dāng)前任務(wù)結(jié)構(gòu)中的信號(hào)位圖(32?位,每位代表1?種信號(hào))丹皱,??
#?然后用任務(wù)結(jié)構(gòu)中的信號(hào)阻塞(屏蔽)碼妒穴,阻塞不允許的信號(hào)位,取得數(shù)值最小的信號(hào)值摊崭,再把??
#?原信號(hào)位圖中該信號(hào)對(duì)應(yīng)的位復(fù)位(置0)讼油,最后將該信號(hào)值作為參數(shù)之一調(diào)用do_signal()。??
#?do_signal()在(kernel/signal.c,82)中呢簸,其參數(shù)包括13?個(gè)入棧的信息矮台。??
movl?signal(%eax),%ebx?#?取信號(hào)位圖??ebx,每1?位代表1?種信號(hào)根时,共32?個(gè)信號(hào)瘦赫。??
movl?blocked(%eax),%ecx?#?取阻塞(屏蔽)信號(hào)位圖??ecx。??
notl?%ecx?#?每位取反蛤迎。??
andl?%ebx,%ecx?#?獲得許可的信號(hào)位圖确虱。??
bsfl?%ecx,%ecx?#?從低位(位0)開始掃描位圖,看是否有1?的位替裆,??
#?若有校辩,則ecx?保留該位的偏移值(即第幾位0-31)窘问。??
je?3f?#?如果沒有信號(hào)則向前跳轉(zhuǎn)退出。??
btrl?%ecx,%ebx?#?復(fù)位該信號(hào)(ebx?含有原signal?位圖)宜咒。??
movl?%ebx,signal(%eax)?#?重新保存signal?位圖信息??current->signal惠赫。??
incl?%ecx?#?將信號(hào)調(diào)整為從1?開始的數(shù)(1-32)。??
pushl?%ecx?#?信號(hào)值入棧作為調(diào)用do_signal?的參數(shù)之一荧呐。??
call?_do_signal?#?調(diào)用C?函數(shù)信號(hào)處理程序(kernel/signal.c,82)??
popl?%eax?#?彈出信號(hào)值汉形。??
3:?popl?%eax??
popl?%ebx??
popl?%ecx??
popl?%edx??
pop?%fs??
pop?%es??
pop?%ds??
iret??
./include/unistd.h文件中系統(tǒng)調(diào)用符號(hào)和調(diào)用號(hào)的對(duì)應(yīng)定義
[cpp]view plaincopy
//?以下是內(nèi)核實(shí)現(xiàn)的系統(tǒng)調(diào)用符號(hào)常數(shù),用于作為系統(tǒng)調(diào)用函數(shù)表中的索引值倍阐。(?include/linux/sys.h?)??
#define?__NR_setup?0????????/*?used?only?by?init,?to?get?system?going?*/??
/*?__NR_setup?僅用于初始化概疆,以啟動(dòng)系統(tǒng)?*/??
#define?__NR_exit?1??
#define?__NR_fork?2??
#define?__NR_read?3??
#define?__NR_write?4??
#define?__NR_open?5??
#define?__NR_close?6??
#define?__NR_waitpid?7??
#define?__NR_creat?8??
#define?__NR_link?9??
#define?__NR_unlink?10??
#define?__NR_execve?11??
#define?__NR_chdir?12??
#define?__NR_time?13??
#define?__NR_mknod?14??
#define?__NR_chmod?15??
#define?__NR_chown?16??
#define?__NR_break?17??
#define?__NR_stat?18??
#define?__NR_lseek?19??
#define?__NR_getpid?20??
#define?__NR_mount?21??
#define?__NR_umount?22??
#define?__NR_setuid?23??
#define?__NR_getuid?24??
#define?__NR_stime?25??
#define?__NR_ptrace?26??
#define?__NR_alarm?27??
#define?__NR_fstat?28??
#define?__NR_pause?29??
#define?__NR_utime?30??
#define?__NR_stty?31??
#define?__NR_gtty?32??
#define?__NR_access?33??
#define?__NR_nice?34??
#define?__NR_ftime?35??
#define?__NR_sync?36??
#define?__NR_kill?37??
#define?__NR_rename?38??
#define?__NR_mkdir?39??
#define?__NR_rmdir?40??
#define?__NR_dup?41??
#define?__NR_pipe?42??
#define?__NR_times?43??
#define?__NR_prof?44??
#define?__NR_brk?45??
#define?__NR_setgid?46??
#define?__NR_getgid?47??
#define?__NR_signal?48??
#define?__NR_geteuid?49??
#define?__NR_getegid?50??
#define?__NR_acct?51??
#define?__NR_phys?52??
#define?__NR_lock?53??
#define?__NR_ioctl?54??
#define?__NR_fcntl?55??
#define?__NR_mpx?56??
#define?__NR_setpgid?57??
#define?__NR_ulimit?58??
#define?__NR_uname?59??
#define?__NR_umask?60??
#define?__NR_chroot?61??
#define?__NR_ustat?62??
#define?__NR_dup2?63??
#define?__NR_getppid?64??
#define?__NR_getpgrp?65??
#define?__NR_setsid?66??
#define?__NR_sigaction?67??
#define?__NR_sgetmask?68??
#define?__NR_ssetmask?69??
#define?__NR_setreuid?70??
#define?__NR_setregid?71??
這是一系列宏,它們的定義在unistd.h中峰搪,基本形式為#define _NR_name value岔冀,name為系統(tǒng)函數(shù)名字,value是一個(gè)整數(shù)值概耻,是name所對(duì)應(yīng)的系統(tǒng)函數(shù)指針在sys_call_table中的偏移量使套。
系統(tǒng)調(diào)用宏也在本文件內(nèi)定義,采用內(nèi)聯(lián)匯編鞠柄,如下:
[cpp]view plaincopy
//?以下定義系統(tǒng)調(diào)用嵌入式匯編宏函數(shù)侦高。??
//?不帶參數(shù)的系統(tǒng)調(diào)用宏函數(shù)。type?name(void)厌杜。??
//?%0?-?eax(__res)奉呛,%1?-?eax(__NR_##name)。其中name?是系統(tǒng)調(diào)用的名稱夯尽,與?__NR_?組合形成上面??
//?的系統(tǒng)調(diào)用符號(hào)常數(shù)瞧壮,從而用來對(duì)系統(tǒng)調(diào)用表中函數(shù)指針尋址。??
//?返回:如果返回值大于等于0匙握,則返回該值咆槽,否則置出錯(cuò)號(hào)errno,并返回-1圈纺。??
#define?_syscall0(type,name)?/??
type?name(void)?/??
{?/??
long?__res;?/??
__asm__?volatile?(?"int?$0x80"?/????//?調(diào)用系統(tǒng)中斷0x80秦忿。??
:"=a"?(__res)?/?????//?返回值??eax(__res)。??
:""?(__NR_##name));?/???????????//?輸入為系統(tǒng)中斷調(diào)用號(hào)__NR_name蛾娶。??
??????if?(__res?>=?0)?/??????//?如果返回值>=0小渊,則直接返回該值。??
??????return?(type)?__res;?errno?=?-__res;?/????//?否則置出錯(cuò)號(hào)茫叭,并返回-1酬屉。??
??????return?-1;}??
//?有1?個(gè)參數(shù)的系統(tǒng)調(diào)用宏函數(shù)。type?name(atype?a)??
//?%0?-?eax(__res),%1?-?eax(__NR_name)呐萨,%2?-?ebx(a)杀饵。??
#define?_syscall1(type,name,atype,a)?/??
type?name(atype?a)?/??
{?/??
long?__res;?/??
__asm__?volatile?(?"int?$0x80"?/??
:?"=a"?(__res)?/??
:?""?(__NR_##name),?"b"?((long)(a)));?/??
if?(__res?>=?0)?/??
return?(type)?__res;?/??
errno?=?-__res;?/??
return?-1;?/??
}??
//?有2?個(gè)參數(shù)的系統(tǒng)調(diào)用宏函數(shù)。type?name(atype?a,?btype?b)??
//?%0?-?eax(__res)谬擦,%1?-?eax(__NR_name)切距,%2?-?ebx(a),%3?-?ecx(b)惨远。??
#define?_syscall2(type,name,atype,a,btype,b)?/??
type?name(atype?a,btype?b)?/??
{?/??
long?__res;?/??
__asm__?volatile?(?"int?$0x80"?/??
:?"=a"?(__res)?/??
:?""?(__NR_##name),?"b"?((long)(a)),?"c"?((long)(b)));?/??
if?(__res?>=?0)?/??
return?(type)?__res;?/??
errno?=?-__res;?/??
return?-1;?/??
}??
//?有3?個(gè)參數(shù)的系統(tǒng)調(diào)用宏函數(shù)谜悟。type?name(atype?a,?btype?b,?ctype?c)??
//?%0?-?eax(__res),%1?-?eax(__NR_name)北秽,%2?-?ebx(a)葡幸,%3?-?ecx(b),%4?-?edx(c)贺氓。??
#define?_syscall3(type,name,atype,a,btype,b,ctype,c)?/??
type?name(atype?a,btype?b,ctype?c)?/??
{?/??
long?__res;?/??
__asm__?volatile?(?"int?$0x80"?/??
:?"=a"?(__res)?/??
:?""?(__NR_##name),?"b"?((long)(a)),?"c"?((long)(b)),?"d"?((long)(c)));?/??
if?(__res>=0)?/??
return?(type)?__res;?/??
errno=-__res;?/??
return?-1;?/??
} ?