?? asm.s
字號:
;/* passed;* linux/kernel/asm.s;*;* (C) 1991 Linus Torvalds;*/.386p
.model flat
;/*;* asm.s contains the low-level code for most hardware faults.;* page_exception is handled by the mm, so that isn't here. This;* file also handles (hopefully) fpu-exceptions due to TS-bit, as;* the fpu must be properly saved/resored. This hasn't been tested.;* eax = -1;* 系統中斷調用(eax=調用號);* ebx,ecx,edx 中放有調用參數;* 調用號超范圍?;* 中斷返回;* 寄存器入棧;* ds,es 指向內核代碼段;* fs 指向局部數據段(用戶數據);* 調用對應的C 處理函數;* 任務狀態?;* 調用schedule() 時間片=0?;* 初始任務?;* 彈出入棧的寄存器;* 超級用戶程序?;* 用戶堆棧?;* 根據進程信號位圖取進程的最;* 小信號量,調用do signal();*/;/*;* asm.s 程序中包括大部分的硬件故障(或出錯)處理的底層次代碼。頁異常是由內存管理程序;* mm 處理的,所以不在這里。此程序還處理(希望是這樣)由于TS-位而造成的fpu 異常,;* 因為fpu 必須正確地進行保存/恢復處理,這些還沒有測試過。;*/;// 本代碼文件主要涉及對Intel 保留的中斷int0--int16 的處理(int17-int31 留作今后使用)。;// 以下是一些全局函數名的聲明,其原形在traps.c 中說明。
extrn _do_divide_error:far, _do_int3:far, _do_nmi:far, _do_overflow:far
extrn _do_bounds:far, _do_invalid_op:far, _do_coprocessor_segment_overrun:far
extrn _do_reserved:far, _coprocessor_error:far ptr, _do_double_fault:far
extrn _do_invalid_TSS:far, _do_segment_not_present:far
extrn _do_stack_segment:far, _do_general_protection:far
public _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_oppublic _double_fault,_coprocessor_segment_overrunpublic _invalid_TSS,_segment_not_present,_stack_segmentpublic _general_protection,_irq13,_reserved;// int0 -- (下面這段代碼的含義參見圖4.1(a))。;// 下面是被零除出錯(divide_error)處理代碼。標號'_divide_error'實際上是C 語言函;// 數divide_error()編譯后所生成模塊中對應的名稱。'_do_divide_error'函數在traps.c 中。
.code
_divide_error: push dword ptr _do_divide_error ;// 首先把將要調用的函數地址入棧。這段程序的出錯號為0。no_error_code: ;// 這里是無出錯號處理的入口處,見下面第55 行等。 xchg [esp],eax ;// _do_divide_error 的地址 -> eax,eax 被交換入棧。 push ebx push ecx push edx push edi push esi push ebp push ds ;// !!16 位的段寄存器入棧后也要占用4 個字節。 push es push fs push 0 ;// "error code" ;// 將出錯碼入棧。 lea edx,[esp+44] ;// 取原調用返回地址處堆棧指針位置,并壓入堆棧。 push edx mov edx,10h ;// 內核代碼數據段選擇符。 mov ds,dx mov es,dx mov fs,dx call eax ;// 調用C 函數do_divide_error()。 add esp,8 ;// 讓堆棧指針重新指向寄存器fs 入棧處。 pop fs pop es pop ds pop ebp pop esi pop edi pop edx pop ecx pop ebx pop eax ;// 彈出原來eax 中的內容。 iretd;// int1 -- debug 調試中斷入口點。處理過程同上。_debug: push _do_int3 ;// _do_debug C 函數指針入棧。以下同。 jmp no_error_code;// int2 -- 非屏蔽中斷調用入口點。_nmi: push _do_nmi jmp no_error_code;// int3 -- 同_debug。_int3: push _do_int3 jmp no_error_code;// int4 -- 溢出出錯處理中斷入口點。_overflow: push _do_overflow jmp no_error_code;// int5 -- 邊界檢查出錯中斷入口點。_bounds: push _do_bounds jmp no_error_code;// int6 -- 無效操作指令出錯中斷入口點。_invalid_op: push _do_invalid_op jmp no_error_code;// int9 -- 協處理器段超出出錯中斷入口點。_coprocessor_segment_overrun: push _do_coprocessor_segment_overrun jmp no_error_code;// int15 – 保留。_reserved: push _do_reserved jmp no_error_code;// int45 -- ( = 0x20 + 13 ) 數學協處理器(Coprocessor)發出的中斷。;// 當協處理器執行完一個操作時就會發出IRQ13 中斷信號,以通知CPU 操作完成。_irq13: push eax xor al,al ;// 80387 在執行計算時,CPU 會等待其操作的完成。 out 0F0h,al ;// 通過寫0xF0 端口,本中斷將消除CPU 的BUSY 延續信號,并重新;// 激活80387 的處理器擴展請求引腳PEREQ。該操作主要是為了確保;// 在繼續執行80387 的任何指令之前,響應本中斷。 mov al,20h out 20h,al ;// 向8259 主中斷控制芯片發送EOI(中斷結束)信號。 jmp l1 ;// 這兩個跳轉指令起延時作用。l1: jmp l2l2: out 0A0h,al ;// 再向8259 從中斷控制芯片發送EOI(中斷結束)信號。 pop eax jmp _coprocessor_error ;// _coprocessor_error 原來在本文件中,現在已經放到 ;// (kernel/system_call.s, 131);// 以下中斷在調用時會在中斷返回地址之后將出錯號壓入堆棧,因此返回時也需要將出錯號彈出。;// int8 -- 雙出錯故障。(下面這段代碼的含義參見圖4.1(b))。_double_fault: push _do_double_fault ;// C 函數地址入棧。error_code: xchg [esp+4],eax ;// error code <-> %eax,eax 原來的值被保存在堆棧上。 xchg [esp],ebx ;// &function <-> %ebx,ebx 原來的值被保存在堆棧上。 push ecx push edx push edi push esi push ebp push ds push es push fs push eax ;// error code ;// 出錯號入棧。 lea eax,[esp+44] ;// offset ;// 程序返回地址處堆棧指針位置值入棧。 push eax mov eax,10h ;// 置內核數據段選擇符。 mov ds,ax mov es,ax mov fs,ax call ebx ;// 調用相應的C 函數,其參數已入棧。 add esp,8 ;// 堆棧指針重新指向棧中放置fs 內容的位置。 pop fs pop es pop ds pop ebp pop esi pop edi pop edx pop ecx pop ebx pop eax iretd;// int10 -- 無效的任務狀態段(TSS)。_invalid_TSS: push _do_invalid_TSS jmp error_code;// int11 -- 段不存在。_segment_not_present: push _do_segment_not_present jmp error_code;// int12 -- 堆棧段錯誤。_stack_segment: push _do_stack_segment jmp error_code;// int13 -- 一般保護性出錯。_general_protection: push _do_general_protection jmp error_code;// int7 -- 設備不存在(_device_not_available)在(kernel/system_call.s,148);// int14 -- 頁錯誤(_page_fault)在(mm/page.s,14);// int16 -- 協處理器錯誤(_coprocessor_error)在(kernel/system_call.s,131);// 時鐘中斷int 0x20 (_timer_interrupt)在(kernel/system_call.s,176);// 系統調用int 0x80 (_system_call)在(kernel/system_call.s,80)
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -