|
MenuetOS 定时器代码分析
作者: Star
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;irq0:定时器代码
; 1)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
irq0:
;1)判断是否有中断错误
cmp [error_interrupt],-1
je no_error_in_previous_process
mov edi,[error_interrupt]
imul edi,8
mov [edi+tss0i_l +5], word 01010000b *256 +11101001b
mov edi,[error_interrupt]
imul edi,128
add edi,0x290000
mov esi,[error_interrupt_entry]
mov [edi+l.eip-tss_sceleton],esi
mov [edi+l.eflags-tss_sceleton],dword 0x11002
mov [0xffff],byte 0
mov [error_interrupt],-1
no_error_in_previous_process:
;2)恢复错误任务
mov edi,[0x3000]
imul edi,8
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
;3)更新时间
inc dword [0xfdf0]
mov eax,[0xfdf0]
cmp eax,[next_usage_update]
jb nocounter
add eax,100
mov [next_usage_update],eax
call updatecputimes
nocounter:
;4)更新计数器
mov edi,[0x3010]
mov ebx,[edi+0x18]
call _rdtsc
sub eax,ebx
add eax,[edi+0x14]
mov [edi+0x14],eax
mov ebx,[0x3000]
;判断是否转下一个任务
cmp [0xffff],byte 1
je do_not_change_task
;5)在进程链表中查找一个处于就绪态的进程接点
waiting_for_termination:
waiting_for_reuse:
add edi,0x20 ;任务链表指针+0x20
inc ebx ;转到下一个进程任务
cmp [edi+0xa],byte 3 ;进程状态:3=堵塞态,4=进程已经终止 9 = ?
je waiting_for_termination
cmp [edi+0xa],byte 4
je waiting_for_termination
cmp [edi+0xa],byte 9
je waiting_for_reuse
;6)判断当前运行态任务是否为最后一个
cmp ebx,[0x3004]
jbe nsched0
mov ebx,1 ;链表中的第一个进程接点号
mov edi,0x3020 ;链表中的第一个进程接点基地址
;7)保存当前运行态进程
nsched0:
;保存当前运行态进程的在进程链表中的任务号
mov [0x3000],ebx
;保存当前运行态进程的在进程链表中的接点基地址
mov [0x3010],edi
do_not_change_task:
;更新当前运行态任务的时间戳
call _rdtsc
mov [edi+0x18],eax
;9)改变任务转换标志
cmp [0xffff],byte 0
je nodecffff
dec byte [0xffff]
;10)计算下一个要运行的任务 = tss0+(process_slot*
nodecffff:
shl bx,3
add bx,tss0
mov [tss_s],bx
;11)
mov al,0x20
mov dx,0x20
out dx,al
;12)任务切换: jmp .. ( to gdt ) = word (tss0+(process_slot*):dword 0
db 0xea
tss_t dd 0
tss_s dw tss0t
jmp irq0
next_usage_update dd 100 |
|