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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

我是如何学习写一个操作系统(四):操作系统之系统调用

發(fā)布時(shí)間:2023/12/20 windows 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我是如何学习写一个操作系统(四):操作系统之系统调用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

最近有點(diǎn)事情,馬上要開學(xué)了,所以學(xué)習(xí)的腳步就慢下來了。這一篇主要是來說操作系統(tǒng)的系統(tǒng)調(diào)用的,像C語言的printf深入到內(nèi)部就是一個(gè)有關(guān)屏幕輸出的系統(tǒng)調(diào)用

什么是系統(tǒng)調(diào)用

之前提過操作系統(tǒng)是對(duì)硬件的抽象,也是軟硬件之間的一層。之前比如如果我們想要在屏幕上輸出一些字符,就需要一些指令操作,然后把數(shù)據(jù)放到顯存上。但是在有了操作系統(tǒng)后,就不需要這樣做,也不能這樣做了。這時(shí)候只要操作系統(tǒng)提供一個(gè)接口來讓我們完成這個(gè)任務(wù)

由操作系統(tǒng)實(shí)現(xiàn)提供的所有系統(tǒng)調(diào)用所構(gòu)成的集合即程序接口或應(yīng)用編程接口(Application Programming Interface,API)。是應(yīng)用程序同系統(tǒng)之間的接口。

系統(tǒng)調(diào)用的實(shí)現(xiàn)

在硬件設(shè)計(jì)上,通過區(qū)分內(nèi)核態(tài)和用戶態(tài)來把內(nèi)核程序和用戶程序隔離開

CS寄存器最低的兩位為0即是內(nèi)核態(tài),為3是用戶態(tài)

但是系統(tǒng)調(diào)用的代碼是處在內(nèi)核態(tài)的,所以就需要提供一種方法來能夠讓用戶程序進(jìn)入內(nèi)核態(tài)來實(shí)現(xiàn)系統(tǒng)調(diào)用

在X86里,INT指令就是硬件用來提供由用戶態(tài)進(jìn)入內(nèi)核態(tài)的方法,所以系統(tǒng)調(diào)用的實(shí)現(xiàn)就可以變?yōu)?#xff1a;

  • 由用戶程序發(fā)起一個(gè)INT指令,指明要調(diào)用的服務(wù)
  • 在操作系統(tǒng)里寫出相應(yīng)的中斷處理
  • 由操作系統(tǒng)根據(jù)用戶指明要調(diào)用的服務(wù)取執(zhí)行相應(yīng)的代碼

內(nèi)聯(lián)匯編

稍微說一下C里的內(nèi)聯(lián)匯編,以免之后忘記。

gcc的內(nèi)聯(lián)匯編一般都是這個(gè)格式

asm ( 匯編指令: 輸出操作數(shù) // 非必需: 輸入操作數(shù) // 非必需: 其他被污染的寄存器 // 非必需);
  • 第一部分就是匯編指令

  • 第二部分是輸出操作數(shù),都是 "=?"(var) 的形式, var可以是任意內(nèi)存變量(輸出結(jié)果會(huì)存到這個(gè)變量中), ?一般是下面這些標(biāo)識(shí)符 (表示內(nèi)聯(lián)匯編中用什么來代理這個(gè)操作數(shù)):

    a,b,c,d,S,D 分別代表 eax,ebx,ecx,edx,esi,edi 寄存器
    r 上面的寄存器的任意一個(gè)(誰閑著就用誰)
    m 內(nèi)存
    i 立即數(shù)(常量,只用于輸入操作數(shù))
    g 寄存器、內(nèi)存、立即數(shù) 都行
    在匯編中用%序號(hào)來代表這些輸入/輸出操作數(shù),序號(hào)從0開始。為了與操作數(shù)區(qū)分開來,寄存器用兩個(gè)%引出,如:%%eax

  • 第三部分是是輸入操作數(shù),都是 "?"(var) 的形式, ? 除了可以是上面的那些標(biāo)識(shí)符,還可以是輸出操作數(shù)的序號(hào),表示用 var 來初始化該輸出操作數(shù),上面的程序中 %0 和 %1 就是一個(gè)東西,初始化為 1(a的值)。

  • 第四部分標(biāo)出那些在匯編代碼中修改了的、 又沒有在輸入/輸出列表中列出的寄存器, 這樣 gcc 就不會(huì)擅自使用這些"危險(xiǎn)的"寄存器。 還可以用 "memory" 表示在內(nèi)聯(lián)匯編中修改了內(nèi)存, 之前緩存在寄存器中的內(nèi)存變量需要重新讀取。

    參考鏈接

  • Linux0.11里對(duì)系統(tǒng)調(diào)用的代碼實(shí)現(xiàn)

    設(shè)置中斷

    • 首先需要對(duì)IDT設(shè)置中斷調(diào)用的處理函數(shù)
    #define set_system_gate(n,addr) \_set_gate(&idt[n],15,3,addr)#define _set_gate(gate_addr,type,dpl,addr) \ __asm__ ("movw %%dx,%%ax\n\t" \"movw %0,%%dx\n\t" \"movl %%eax,%1\n\t" \"movl %%edx,%2" \: \: "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \"o" (*((char *) (gate_addr))), \"o" (*(4+(char *) (gate_addr))), \"d" ((char *) (addr)),"a" (0x00080000))set_system_gate(0x80,&system_call);

    實(shí)現(xiàn)中斷函數(shù)

    • sys_call_table[]是一個(gè)指針數(shù)組,定義在include/linux/sys.h中,該指針數(shù)組中設(shè)置了所有72個(gè)系統(tǒng)調(diào)用C處理函數(shù)地址。
    system_call:cmpl $nr_system_calls-1,%eaxja bad_sys_callpush %dspush %espush %fspushl %edxpushl %ecx # push %ebx,%ecx,%edx as parameterspushl %ebx # to the system callmovl $0x10,%edx # set up ds,es to kernel spacemov %dx,%dsmov %dx,%esmovl $0x17,%edx # fs points to local data spacemov %dx,%fscall sys_call_table(,%eax,4)pushl %eaxmovl current,%eaxcmpl $0,state(%eax) # statejne reschedulecmpl $0,counter(%eax) # counterje reschedule

    提供接口

    • 在linux向應(yīng)用程序提供系統(tǒng)調(diào)用接口write
    • _syscall3的本質(zhì)上是一個(gè)宏
    _syscall3(int,write,int,fd,const char *,buf,off_t,count) #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) \: "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \ if (__res>=0) \return (type) __res; \ errno=-__res; \ return -1; \ }

    小結(jié)

    這樣對(duì)于一個(gè)系統(tǒng)調(diào)用就會(huì)變成

    printf 用戶調(diào)用

    ?

    int 0x80 庫函數(shù)的實(shí)現(xiàn)

    ?


    進(jìn)入內(nèi)核


    system_call 中斷調(diào)用

    ?

    sys_ 系統(tǒng)調(diào)用

    轉(zhuǎn)載于:https://www.cnblogs.com/secoding/p/11414172.html

    總結(jié)

    以上是生活随笔為你收集整理的我是如何学习写一个操作系统(四):操作系统之系统调用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。