vm-ints.asm
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· 汇编 代码 · 共 258 行
ASM
258 行
; -----------------------------------------------
; $Id: vm-ints.asm,v 1.8 2004/02/15 11:06:17 epr Exp $
;
; Java VM interrupt support code
;
; Author : E. Prangsma
; -----------------------------------------------
extern VmSystem_initialized
extern SoftByteCodes_systemException
extern VmProcessor_reschedule
deadLockCounter dd 0
currentTimeMillisStaticsIdx dd -1
; -----------------------------------------------
; Low level Yield Point Handler
; This low level interrupt handler is coded
; by hand for optimal speed.
; -----------------------------------------------
stub_yieldPointHandler:
push dword 0 ; Error code
push dword 0 ; INTNO (not relevant)
push dword 0 ; Handler (not relevant)
int_entry
mov ebp,esp
call yieldPointHandler
int_exit
; -----------------------------------------------
; Yield Point Handler
; -----------------------------------------------
; Save a register
; Usage: SAVEREG VmX86Thread-offset, ebp-offset
%macro SAVEREG 2
mov ecx,[ebp+%2]
mov [edi+%1*4],ecx
%endmacro
; Restore a register
; Usage: RESTOREREG VmX86Thread-offset, ebp-offset
%macro RESTOREREG 2
mov ecx,[edi+%1*4]
mov [ebp+%2],ecx
%endmacro
yieldPointHandler_kernelCode:
mov eax,yp_kernel_msg
call sys_print_str
jmp int_die
yieldPointHandler:
cmp dword [ebp+OLD_CS],USER_CS
jne yieldPointHandler_kernelCode
; Mark switch active
or THREADSWITCHINDICATOR,VmProcessor_TSI_SWITCH_ACTIVE
and THREADSWITCHINDICATOR,~VmProcessor_TSI_SWITCH_NEEDED
mov dword [deadLockCounter], 0
; Setup the user stack to add a return address to the current EIP
; and change the current EIP to yieldPointHandler_doReschedule, which will
; save the registers and call VmScheduler.reschedule
yieldPointHandler_reschedule:
; Actually call VmScheduler.reschedule (in kernel mode!)
push ebp
xor ebp,ebp ; Make java stacktraces terminate
mov STACKEND,KERNEL_STACKEND ; Set kernel stack end for correct stackoverflow tests
mov eax,VmProcessor_reschedule ; Load reschedule method
push dword vmCurProcessor ; this
INVOKE_JAVA_METHOD
pop ebp
; Now save the current thread state
mov edi,CURRENTTHREAD
cmp edi,NEXTTHREAD
je near yieldPointHandler_done
SAVEREG VmX86Thread_EAX_OFFSET, OLD_EAX
SAVEREG VmX86Thread_EBX_OFFSET, OLD_EBX
SAVEREG VmX86Thread_ECX_OFFSET, OLD_ECX
SAVEREG VmX86Thread_EDX_OFFSET, OLD_EDX
SAVEREG VmX86Thread_EDI_OFFSET, OLD_EDI
SAVEREG VmX86Thread_ESI_OFFSET, OLD_ESI
SAVEREG VmX86Thread_EBP_OFFSET, OLD_EBP
SAVEREG VmX86Thread_ESP_OFFSET, OLD_ESP
SAVEREG VmX86Thread_EIP_OFFSET, OLD_EIP
SAVEREG VmX86Thread_EFLAGS_OFFSET, OLD_EFLAGS
mov edi,NEXTTHREAD
RESTOREREG VmX86Thread_EAX_OFFSET, OLD_EAX
RESTOREREG VmX86Thread_EBX_OFFSET, OLD_EBX
RESTOREREG VmX86Thread_ECX_OFFSET, OLD_ECX
RESTOREREG VmX86Thread_EDX_OFFSET, OLD_EDX
RESTOREREG VmX86Thread_EDI_OFFSET, OLD_EDI
RESTOREREG VmX86Thread_ESI_OFFSET, OLD_ESI
RESTOREREG VmX86Thread_EBP_OFFSET, OLD_EBP
RESTOREREG VmX86Thread_ESP_OFFSET, OLD_ESP
RESTOREREG VmX86Thread_EIP_OFFSET, OLD_EIP
RESTOREREG VmX86Thread_EFLAGS_OFFSET, OLD_EFLAGS
; Fix old stack overflows
mov ecx,[edi+VmThread_STACKOVERFLOW_OFFSET*4]
test ecx,ecx
jnz yieldPointHandler_fixStackOverflow
yieldPointHandler_afterStackOverflow:
; Set the new thread parameters
mov CURRENTTHREAD,edi
; Reload stackend
mov ebx,[edi+VmThread_STACKEND_OFFSET*4]
mov STACKEND,ebx
yieldPointHandler_done:
and THREADSWITCHINDICATOR,~VmProcessor_TSI_SWITCH_ACTIVE
ret
; Fix a previous stack overflow
; EDI contains reference the VmThread
yieldPointHandler_fixStackOverflow:
; Is the stack overflow resolved?
mov ecx,[edi+VmThread_STACKEND_OFFSET*4]
add ecx,VmThread_STACK_OVERFLOW_LIMIT
; Is current ESP not beyond limit anymore
cmp dword [edi+VmX86Thread_ESP_OFFSET*4],ecx
jle yieldPointHandler_afterStackOverflow ; No still below limit
; Reset stackoverflow flag
mov [edi+VmThread_STACKEND_OFFSET*4],ecx
mov dword [edi+VmThread_STACKOVERFLOW_OFFSET*4],0
jmp yieldPointHandler_afterStackOverflow
; -----------------------------------------------
; Handle a timer interrupt
; -----------------------------------------------
timer_handler:
mov edi,[fs:VmProcessor_STATICSTABLE_OFFSET*4]
mov eax,[currentTimeMillisStaticsIdx]
lea edi,[edi+eax*4+(VmArray_DATA_OFFSET*4)]
inc dword [edi+0]
adc dword [edi+4],0
test dword [edi+0],0x07
jnz timer_ret
; Set a thread switch needed indicator
or THREADSWITCHINDICATOR, VmProcessor_TSI_SWITCH_NEEDED
inc dword [deadLockCounter]
test dword [deadLockCounter], 0x4000
jnz timer_deadlock
timer_ret:
mov al,0x60 ; EOI IRQ0
out 0x20,al
ret
timer_deadlock:
mov eax,dword [jnodeFinished]
test eax,eax
jnz timer_ret
mov eax,deadLock_msg
call sys_print_str
jmp int_die
; -----------------------------------------------
; Handle an IRQ interrupt
; -----------------------------------------------
def_irq_handler:
cmp dword [ebp+OLD_CS],USER_CS
jne def_irq_kernel
; Increment the appropriate IRQ counter and set threadSwitch indicator.
mov eax,[ebp+INTNO]
mov edi,dword [fs:VmX86Processor_IRQCOUNT_OFFSET*4]
inc dword [edi+(VmArray_DATA_OFFSET*4)+eax*4]
; Set thread switch indicator
or THREADSWITCHINDICATOR, VmProcessor_TSI_SWITCH_NEEDED
; Done
ret
def_irq_kernel:
mov eax,irq_kernel_msg
call sys_print_str
ret
; -----------------------------------------------
; Throw a system-trapped exception. This method can only be called from an interrupt handler.
; Input:
; EAX contains exception number.
; EBX Address parameter
; EBP Old register block
; -----------------------------------------------
int_system_exception:
test THREADSWITCHINDICATOR,VmProcessor_TSI_SYSTEM_READY
jz near int_die
;jmp int_die
; Save the exception state
mov edi,CURRENTTHREAD
SAVEREG VmX86Thread_EXEAX_OFFSET, OLD_EAX
SAVEREG VmX86Thread_EXEBX_OFFSET, OLD_EBX
SAVEREG VmX86Thread_EXECX_OFFSET, OLD_ECX
SAVEREG VmX86Thread_EXEDX_OFFSET, OLD_EDX
SAVEREG VmX86Thread_EXEDI_OFFSET, OLD_EDI
SAVEREG VmX86Thread_EXESI_OFFSET, OLD_ESI
SAVEREG VmX86Thread_EXEBP_OFFSET, OLD_EBP
SAVEREG VmX86Thread_EXESP_OFFSET, OLD_ESP
SAVEREG VmX86Thread_EXEIP_OFFSET, OLD_EIP
SAVEREG VmX86Thread_EXEFLAGS_OFFSET, OLD_EFLAGS
mov ecx,cr2
mov [edi+VmX86Thread_EXCR2_OFFSET*4],ecx
; Setup the user stack to add a return address to the current EIP
; and change the current EIP to doSystemException, which will
; save the registers and call SoftByteCodes.systemException
mov edi,[ebp+OLD_ESP]
lea edi,[edi-4]
mov [ebp+OLD_EAX],eax ; Exception number
mov [ebp+OLD_EBX],ebx ; Address
mov eax,[ebp+OLD_EIP]
mov [edi+0],eax
mov [ebp+OLD_ESP],edi
mov dword [ebp+OLD_EIP],doSystemException
ret
doSystemException:
push eax ; Exception number
push ebx ; Address
mov eax,SoftByteCodes_systemException
INVOKE_JAVA_METHOD
jmp vm_athrow
; -----------------------------------------------
; Handle a stackoverflow
; -----------------------------------------------
int_stack_overflow:
cmp dword [ebp+OLD_CS],USER_CS
jne doFatal_stack_overflow
mov eax,CURRENTTHREAD
mov ecx,[eax+VmThread_STACKOVERFLOW_OFFSET*4]
jecxz int_stack_first_overflow
jmp doFatal_stack_overflow
int_stack_first_overflow:
inc dword [eax+VmThread_STACKOVERFLOW_OFFSET*4]
; Remove the stackoverflow limit
mov edx,[eax+VmThread_STACKEND_OFFSET*4]
sub edx,VmThread_STACK_OVERFLOW_LIMIT
mov [eax+VmThread_STACKEND_OFFSET*4],edx
mov STACKEND,edx
mov eax,SoftByteCodes_EX_STACKOVERFLOW
mov dword [ebp+OLD_EIP],doSystemException
jmp int_system_exception
doFatal_stack_overflow:
mov eax,fatal_so_msg
call sys_print_str
;call vmint_print_stack
jmp int_die
cli
hlt
yp_kernel_msg: db 'YieldPoint in kernel mode??? Probably a bug',0
irq_kernel_msg: db 'IRQ in kernel mode??? Probably a bug',0
fatal_so_msg: db 'Fatal stack overflow: ',0
deadLock_msg: db 'Very likely deadlock detected: ',0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?