中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

linux怎么實現程序的執行

發布時間:2021-12-17 09:25:06 來源:億速云 閱讀:115 作者:iii 欄目:大數據

本篇內容主要講解“linux怎么實現程序的執行”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“linux怎么實現程序的執行”吧!

我們先看一下這時候的內存布局。

linux怎么實現程序的執行    

當cpu通過cs:eip執行第一條指令的時候。首先通過cs的值,在ldt中找到代碼段的基地址,然后加上eip,得到線性地址,然后通過線性地址到頁目錄和頁表項里找是否已經映射到物理地址了。這時候發現,還沒有對應的物理地址,然后就觸發缺頁中斷。  
我們看一下缺頁中斷的處理。


// 缺頁處理,進程的內容還沒有加載到內存,訪問的時候導致缺頁異常
void do_no_page(unsigned long error_code,unsigned long address)
{
    int nr[4];
    unsigned long tmp;
    unsigned long page;
    int block,i;
    // 取得線性地址對應頁的頁首地址,與0xfffff000即減去頁偏移 
    address &= 0xfffff000;
    // 算出離代碼段首地址的偏移
    tmp = address - current->start_code;
    // tmp大于等于end_data說明是訪問堆或者棧的空間時發生的缺頁,直接申請一頁
    if (!current->executable || tmp >= current->end_data) {
        get_empty_page(address);
        return;
    }
    // 是否有進程已經使用了
    if (share_page(tmp))
        return;
    // 獲取一頁,4kb
    if (!(page = get_free_page()))
        oom();
/* remember that 1 block is used for header */
    /*
     算出要讀的硬盤塊號,但是最多讀四塊。
     tmp/BLOCK_SIZE算出線性地址對應頁的
     頁首地址離代碼塊距離了多少塊,然后讀取頁首
     地址對應的塊號,所以需要加一。比如距離2塊的距離,則
     需要讀取的塊是第三塊
    */
    block = 1 + tmp/BLOCK_SIZE;
    // 查找文件前4塊對應的硬盤號
    for (i=0 ; i<4 ; block++,i++)
        // bmap算出邏輯塊號對應的物理塊號
        nr[i] = bmap(current->executable,block);
    // 從硬盤讀四塊數據進來,并且復制到物理頁中
    bread_page(page,current->executable->i_dev,nr);
    /*
     tmp是小于end_data的,因為從tmp開始加載了4kb的數據,
     所以tmp+4kb(4096)后大于end_data,所以大于的部分需要清0,
     i即超出的字節數
    */
    i = tmp + 4096 - current->end_data;
    // page是物理頁首地址,加上4kb,從后往前清0
    tmp = page + 4096;
    while (i-- > 0) {
        tmp--;
        *(char *)tmp = 0;
    }
    // 建立線性地址和物理地址的映射
    if (put_page(page,address))
        return;
    // 失敗則是否剛才申請的物理頁
    free_page(page);
    oom();
}
 

我們發現缺頁中斷有一句代碼是

// 算出離代碼段首地址的偏移
    tmp = address - current->start_code
 

start_code的值就是cs對應的基地址。即進程號*64MB。address就是剛才我們通過cs:eip算出來的值。兩個相減得到線性地址離代碼段基址的距離,即硬盤中,在代碼section中的偏移。然后算出這個偏移在硬盤中相對代碼section首地址塊偏移。因為代碼塊不是可執行文件的第一塊。所以還需要做一個處理。

/* remember that 1 block is used for header */
    /*
     算出要讀的硬盤塊號,但是最多讀四塊。
     tmp/BLOCK_SIZE算出線性地址對應頁的
     頁首地址離代碼塊距離了多少塊,然后讀取頁首
     地址對應的塊號,所以需要加一。比如距離2塊的距離,則
     需要讀取的塊是第三塊
    */
    block = 1 + tmp/BLOCK_SIZE;

就是加上可執行文件頭占據的那一塊,這樣就得出了cs:eip在硬盤中絕對偏移,最后把這塊數據讀進來。并且建立線性地址到物理地址的映射。然后重新執行cs:eip對應的指令,這時候就能找到對應的指令執行了。同理,當我們通過ds訪問數據段的時候也是這樣,在指令里,訪問數據的時候,用的地址是相對數據段的偏移,通過地址的轉換,會落到數據段對應的線性地址里。然后通過缺頁中斷加載進來。堆和棧缺頁中斷時候直接分配一頁物理內存就行。因為他的數據不在硬盤里。

到此,相信大家對“linux怎么實現程序的執行”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

通化市| 石楼县| 阳曲县| 屯留县| 巩义市| 丰都县| 靖安县| 禹城市| 慈溪市| 麦盖提县| 寻甸| 汉寿县| 义乌市| 泾川县| 宜城市| 承德县| 甘肃省| 长沙县| 凯里市| 建湖县| 芒康县| 宁都县| 广东省| 洱源县| 澎湖县| 棋牌| 信宜市| 东莞市| 壶关县| 图片| 伊宁县| 弥渡县| 奇台县| 贵港市| 五华县| 喜德县| 华池县| 通城县| 安西县| 桂阳县| 古田县|