1. 程式人生 > >第三周學習筆記

第三周學習筆記

con 行數 返回 win kernel 否則 處理 內核代碼 打開

技術分享圖片

第三周學習筆記

2018-10-24

  • C代碼中嵌入匯編代碼語法
asm("statements": output_regs:input_regs:clobbered_regs);
      匯編語句模板      輸出          輸入          破壞描述部分

eg:
技術分享圖片
今日問題:

  • eax的值到底存數據還是地址 居然百度都沒搜到答案。。。反思自己連百度都不會用
  • 破壞描述部分是什麽?
    有時在進行某些操作時,除了要用到進行數據輸入和輸出的寄存器外,還要使用多個寄存器來保存中間計算結果,這樣就難免會破壞原有寄存器的內容。如果希望GCC在編譯時能夠將這一點考慮進去。那麽你就可以在“破壞描述部分”聲明這些寄存器或內存。
    這種情況一般發生在一個寄存器出現在“匯編語句模板”,但卻不是由輸入或輸出操作表達式所指定的,也不是在一些輸入或輸出操作表達式使用"r"、"g"約束時由GCC為其選擇的,同時此寄存器被“匯編語句模板”中的指令修改,而這個寄存器只是供當前內嵌匯編臨時使用的情況。比如:
    asm
    ("movl %0, %%ebx" : : "a"(foo) : "%ebx");
    寄存器%ebx出現在“匯編語句模板”中,並且被movl指令修改,但卻未被任何輸入或輸出操作表達式指定,所以你需要在“破壞描述部分”指定"%ebx",以讓GCC知道這一點。
    因為你在輸入或輸出操作表達式所指定的寄存器,或當你為一些輸入或輸出操作表達式使用"r"、"g"約束,讓GCC為你選擇一個寄存器時,GCC對這些寄存器是非常清楚的——它知道這些寄存器是被修改的,你根本不需要在“破壞描述部分”再聲明它們。但除此之外,GCC對剩下的寄存器中哪些會被當前的內嵌匯編修改一無所知。所以如果你真的在當前內嵌匯編語句中修改了它們,那麽就最好“破壞描述部分”中聲明它們,讓GCC針對這些寄存器做相應的處理。否則有可能會造成寄存器的不一致,從而造成程序執行錯誤。
    在“破壞描述部分”中指定這些寄存器的方法很簡單,你只需要將寄存器的名字使用雙引號引起來。如果有多個寄存器需要聲明,你需要在任意兩個聲明之間用逗號隔開。比如:
__asm__("movl %0, %%ebx; popl %%ecx" : : "a"(foo) : "%ebx", "%ecx" );

eg:
技術分享圖片

  • 註意:
    asm("mov %%eax, %%ebx" :)和__asm__("mov %eax, %ebx") 正確
    asm("mov %eax, %ebx" :)和__asm__("mov %%eax, %%ebx")不正確
    gcc編譯的代碼Windows可能運行有問題

    mykernel實驗和三個法寶

  • 存儲程序計算機:
    馮諾依曼體系
  • 中斷:
    多道程序設計,CPU將當前eip\esp\ebp壓到內核堆棧的另外一個堆棧裏面去,把eip指向中斷處理程序入口,保存現場,執行流的切換。CPU和內核代碼共同實現了保存現場和恢復現場,周期性時鐘中斷
  • 堆棧:
    c語言程序運行必須的記錄路徑參數的空間,可以函數調用框架、傳遞參數、提供局部變量空間、保存返回地址等等

    函數調用堆棧

    技術分享圖片
  • 建立函數調用框架
push %ebp
movl %esp,%ebp#調用者建立被調用者函數的堆棧框架

//函數體//

movl %ebp,%esp
popl %ebp
ret#拆除被調用者函數的堆棧框架

技術分享圖片

實驗樓mykernel實驗指導(操作系統是如何工作的)

cd LinuxKernel/linux-3.9.4
rm -rf mykernel
patch -p1 < ../mykernel_for_linux3.9.4sc.patch
make allnoconfig
make#當出現shiyanlou:~/ $才算編譯完成
qemu -kernel arch/x86/boot/bzImage

技術分享圖片
技術分享圖片
執行代碼效果圖:
技術分享圖片

2018-10-25

  • 立即尋址修改了寄存器的值為什麽說沒有和內存打交道?
    和同學討論後認為寄存器在CPU裏所以寄存器的值可能不在內存中。因此直接給寄存器賦值不和內存打交道。

    2018-10-26

  • 這個問題是四天前的問題,寄存器裏存的到底是數值還是地址?
    今天看《庖丁解牛》發現EBX存的值是一個內存地址,也是一個數值。也就是說寄存器存的數值可以等於地址,寄存器存數值。
    但是這樣一來,我覺得寄存器尋址和間接尋址一樣了。按說應該有區別,區別是什麽呢?。。。
  • esp指向的位置是不是就是esp存儲的值作為地址指向的位置?
    看書發現是的。寄存器存儲的數值減4=寄存器向下移一個單元
  • 銷毀棧有時是popl %ebp,有時是popl %eip什麽時候用哪個?
    ret 語句對應popl %eip,leave 語句對應popl %ebp
    movl %esp是什麽意思?
  • 進程結構體是什麽?
    進程是處於執行期的程序以及它所管理的資源(如打開的文件、掛起的信號、進程狀態、地址空間等等)的總稱。註意,程序並不是進程,實際上兩個或多個進程不僅有可能執行同一程序,而且還有可能共享地址空間等資源。
  • asm volatile("movl %1,%%esp\n\t")最後的\n\t是什麽意思?
    明天學下怎麽用百度
    技術分享圖片

第三周學習筆記