1. 程式人生 > >中斷,異常,系統呼叫,程序切換時的堆疊變化和暫存器儲存

中斷,異常,系統呼叫,程序切換時的堆疊變化和暫存器儲存

 1. 中斷,異常,系統呼叫相同:
 
  CPU自動壓入:

  ss            執行級別提升時需切換堆疊,因此多壓入使用者態的棧段ss,
  esp           執行級別提升時需切換堆疊,因此多壓入使用者態的堆疊指標esp,
  eflag
  cs
  eip
  error code

  程式壓入部分壓入如下暫存器:

  es
  ds
  ebp
  edi
  esi
  edx
  ecx
  ebx

  但是壓入的方法各不相同,見entry.S。#define SAVE_ALL,和pt_reg的關係?

  a. 異常:
ENTRY(divide_error)
    pushl$0            #no error code  Wood: 當沒有硬體錯誤碼時,在棧中墊上一個空值。
    pushl $do_divide_error    # 壓入返回地址
    ALIGN
error_code:
    pushl %ds
    pushl %eax
    xorl %eax, %eax
    pushl %ebp
    pushl %edi
    pushl %esi
    pushl %edx
    decl %eax            # eax = -1
    pushl %ecx
    pushl %ebx
    cld
    movl %es, %ecx
    movl ES(%esp),%edi        # get the functionaddress   ES = 0x20 得到異常高階處理函式地址,見 pushl $do_divide_error
    movl ORIG_EAX(%esp), %edx    # getthe error code,ORIG_EAX    = 0x24,到硬體錯誤碼,見pushl$0,如果CPU壓入,則這裡不需要壓入。這裡是為高層函式準備第二個引數error code,因為高層函式全部是fastcall型別的函式
    movl %eax, ORIG_EAX(%esp)   # 把-1存在原來放硬體錯誤碼的地方,這個值用來把0x80異常與其他異常隔離開。?????
    movl %ecx, ES(%esp)         #把 %es的值存入原來放異常高階處理函式地址的位置。
    movl $(__USER_DS), %ecx
    movl %ecx, %ds
    movl %ecx, %es
    movl%esp,%eax           # pt_regs pointer,當前棧指標,這裡是為高層函式準備第一個引數pt_regs,因為高層函式全部是fastcall型別的函式
    call *%edi
    jmp ret_from_exception

ENTRY(page_fault)
    pushl $do_page_fault
    jmp error_code

  b. 中斷:


2. 程序切換

更新中: