亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 876 | 回復(fù): 0
打印 上一主題 下一主題

switch_to 宏 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2008-04-18 23:13 |只看該作者 |倒序?yàn)g覽

                switch_to宏是平臺相關(guān)的,用來切換進(jìn)程,它在調(diào)度策略決定切換的情況下被調(diào)用,當(dāng)宏完成時,執(zhí)行流已經(jīng)到了另外一個進(jìn)程了
代碼:
#define switch_to(prev,next,last) do {                                  \
        unsigned long esi,edi;                                          \
        asm volatile("pushfl\n\t"                                       \
                     "pushl %%ebp\n\t"                                  \
                     "movl %%esp,%0\n\t"        /* save ESP */          \
                     "movl %5,%%esp\n\t"        /* restore ESP */       \
                     "movl $1f,%1\n\t"          /* save EIP */          \
                     "pushl %6\n\t"             /* restore EIP */       \
                     "jmp __switch_to\n"                                \
                     "1:\t"                                             \
                     "popl %%ebp\n\t"                                   \
                     "popfl"                                            \
                     :"=m" (prev->thread.esp),"=m" (prev->thread.eip),  \
                      "=a" (last),"=S" (esi),"=D" (edi)                 \
                     :"m" (next->thread.esp),"m" (next->thread.eip),    \
                      "2" (prev), "d" (next));                          \
} while (0)
首先, 無論什么進(jìn)程執(zhí)行進(jìn)程切換,代碼都是這段,每條指令都相同, 唯一不同的就是參數(shù)不同,數(shù)據(jù)不同,我很晚才想明白這個
這個完成棧的切換,說白了,進(jìn)程切換本質(zhì)上就是棧的切換和下一條指令位置的更改
首先保存eflag
然后
"pushl %%ebp\n\t"
"movl %%esp,%0\n\t"        /* save ESP */
這兩條指令顯示的保存%ebp到棧上,%ebp 屬于local register, 也就是說函數(shù)的調(diào)用者在調(diào)用完一個函數(shù)后不能保證函數(shù)返回之后寄存器的值不會被改變,同樣的還有esi, edi, ebx,前兩個用于字符串指令,ebx用于保存全局變量的值, 如果函數(shù)需要使用更多的寄存器,編譯器/函數(shù)需要首先保存,然后返回之前恢復(fù)到調(diào)用者的初始值
這也就順便把"=S" (esi),"=D" (edi) 說了。其實(shí)這僅僅提示編譯器保存它們,然后恢復(fù)。 查看這段代碼就會發(fā)現(xiàn),編譯出來的代碼有pushl %esi; pushl %edi; 然后后面pop
接下來
"movl %%esp,%0\n\t"        /* save ESP */          \
"movl %5,%%esp\n\t"        /* restore ESP */       \
用來保存當(dāng)前進(jìn)程的棧位置%esp 到進(jìn)程描述符中,以便下次作為next的時候被恢復(fù)(即上面的后面那條指令)
到這里棧的值已經(jīng)改變到新的值了(需要注意的事進(jìn)程切換只發(fā)生在內(nèi)核態(tài),這%esp是內(nèi)核進(jìn)程的內(nèi)核棧,永遠(yuǎn)都是,因?yàn)橛脩魬B(tài)執(zhí)行的進(jìn)程不會導(dǎo)致切換,只有被中斷后才有可能)
"movl $1f,%1\n\t"          /* save EIP */          \
"pushl %6\n\t"             /* restore EIP */       \
前面這條保存EIP不用說,后面這條把下個進(jìn)程的EIP恢復(fù),而且jmp 到__switch_to函數(shù),這樣,在__switch_to返回的時候再ret(函數(shù)最后執(zhí)行一條指令)的時候,就返回到next進(jìn)程以前被替換的位置了,進(jìn)程next接著上次被調(diào)度出去的那里繼續(xù)執(zhí)行
popl %ebp也就恢復(fù)了next的%ebp了
所以switch_to比起別的宏/函數(shù)調(diào)用對編譯器并沒有什么特殊的,編譯器不知道進(jìn)程切換,它只知道指令。 它不知道這個調(diào)用會導(dǎo)致別的進(jìn)程執(zhí)行。
不過這個宏第一次看還真有點(diǎn)難理解,特別是對linux進(jìn)程的實(shí)現(xiàn)一點(diǎn)都不了解的話
               
               

本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u1/43233/showart_548861.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP