kolibrios/kernel/trunk/core/taskman.inc

1077 lines
25 KiB
PHP
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
GREEDY_KERNEL equ 0
struct APP_HEADER_00_
banner dq ?
version dd ? ;+8
start dd ? ;+12
i_end dd ? ;+16
mem_size dd ? ;+20
i_param dd ? ;+24
ends
struct APP_HEADER_01_
banner dq ?
version dd ? ;+8
start dd ? ;+12
i_end dd ? ;+16
mem_size dd ? ;+20
stack_top dd ? ;+24
i_param dd ? ;+28
i_icon dd ? ;+32
ends
struct APP_HDR
cmdline rd 1 ;0x00
path rd 1 ;0x04
eip rd 1 ;0x08
esp rd 1 ;0x0C
_edata rd 1 ;0x10
_emem rd 1 ;0x14
img_base rd 1 ;0x18
img_size rd 1
filename_size rd 1
cmdline_size rd 1
ends
macro _clear_ op
{ mov ecx, op/4
xor eax, eax
cld
rep stosd
}
align 4
_strnlen:
mov edx, ecx
xor eax, eax
repne scasb
jne @F
inc ecx
@@:
mov eax, edx
sub eax, ecx
retn
fs_execute_from_sysdir:
xor ebx, ebx
fs_execute_from_sysdir_param:
xor edx, edx
align 4
proc fs_execute
; ebx - cmdline
; edx - flags
; ebp - full filename
locals
filename rd 1
cmdline rd 1
flags rd 1
slot rd 1
slot_base rd 1
;app header data
hdr_cmdline rd 1 ;0x00
hdr_path rd 1 ;0x04
hdr_eip rd 1 ;0x08
hdr_esp rd 1 ;0x0C
hdr_edata rd 1 ;0x10
hdr_emem rd 1 ;0x14
file_base rd 1 ;0x18
file_size rd 1 ;0x1c
filename_size rd 1 ;0x20
cmdline_size rd 1 ;0x24
endl
mov eax, [ebp]
mov [flags], edx
mov [cmdline], ebx
mov [filename], eax
mov eax, [filename]
stdcall load_file, eax
mov esi, -ERROR_FILE_NOT_FOUND
test eax, eax
jz .err_file
mov [file_base], eax
mov [file_size], ebx
lea ebx, [hdr_cmdline]
call test_app_header
mov esi, -0x1F
test eax, eax
jz .err_hdr
call lock_application_table
call alloc_thread_slot
mov esi, -0x20 ; too many processes
test eax, eax
jz .err_0
mov [slot], eax
shl eax, 8
lea edi, [SLOT_BASE+eax]
mov [slot_base], edi
;clean extended information about process
mov ecx, 256/4
xor eax, eax
cld
rep stosd
; write application name
stdcall strrchr, [filename], '/' ; now eax points to name without path
lea esi, [eax+1]
test eax, eax
jnz @F
mov esi, [filename]
@@:
mov ecx, 11 ; 11 chars for name! 8 - is old value!
mov edi, [slot_base]
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov edi, [cmdline]
xor eax, eax
test edi, edi
jz @F
mov ecx, 65535
call _strnlen
cmp eax, 256
jb @F
lea ebx, [eax+1]
add [hdr_emem], ebx
@@:
mov [cmdline_size], eax
stdcall create_process, [hdr_emem]
mov esi, -30; no memory
test eax, eax
jz .err_hdr
mov ebx, [sys_proc+LHEAD.prev]
__list_add eax, ebx, sys_proc
mov ebx, [hdr_emem]
mov [eax+PROC.mem_used], ebx
mov ebx, [slot_base]
mov [ebx+APPDATA.process], eax
lea edx, [ebx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail edx, ecx
mov esi, sizeof.APP_HDR
add esi, [cmdline_size]
mov edi, [filename]
mov ecx, 1023
call _strnlen
add esi, eax
mov [filename_size], eax
stdcall kernel_alloc, esi
mov [ebx+APPDATA.exec_params], eax
mov edi, eax
lea esi, [hdr_cmdline]
mov ecx, sizeof.APP_HDR/4
rep movsd
mov esi, [filename]
mov ecx, [filename_size]
rep movsb
mov ecx, [cmdline_size]
mov esi, [cmdline]
rep movsb
lea eax, [hdr_cmdline]
stdcall set_app_params , [slot], eax, [flags]
mov eax, [process_number] ;set result
call unlock_application_table
ret
.err_0:
call unlock_application_table
.err_hdr:
stdcall kernel_free, [file_base]
.err_file:
mov eax, esi
ret
endp
align 4
test_app_header:
virtual at eax
APP_HEADER_00 APP_HEADER_00_
end virtual
virtual at eax
APP_HEADER_01 APP_HEADER_01_
end virtual
cmp dword [eax], 'MENU'
jne .fail
cmp word [eax+4], 'ET'
jne .fail
cmp [eax+6], word '00'
jne .check_01_header
mov ecx, [APP_HEADER_00.start]
mov [ebx+APP_HDR.eip], ecx
mov edx, [APP_HEADER_00.mem_size]
mov [ebx+APP_HDR._emem], edx
shr edx, 1
sub edx, 0x10
mov [ebx+APP_HDR.esp], edx
mov ecx, [APP_HEADER_00.i_param]
mov [ebx+APP_HDR.cmdline], ecx
mov [ebx+APP_HDR.path], 0
mov edx, [APP_HEADER_00.i_end]
mov [ebx+APP_HDR._edata], edx
ret
.check_01_header:
cmp [eax+6], word '01'
je @f
cmp [eax+6], word '02'
jne .fail
@@:
mov ecx, [APP_HEADER_01.start]
mov [ebx+0x08], ecx
mov edx, [APP_HEADER_01.mem_size]
; \begin{diamond}[20.08.2006]
; sanity check (functions 19,58 load app_i_end bytes and that must
; fit in allocated memory to prevent kernel faults)
cmp edx, [APP_HEADER_01.i_end]
jb .fail
; \end{diamond}[20.08.2006]
mov [ebx+APP_HDR._emem], edx
mov ecx, [APP_HEADER_01.stack_top]
mov [ebx+APP_HDR.esp], ecx
mov edx, [APP_HEADER_01.i_param]
mov [ebx+APP_HDR.cmdline], edx
mov ecx, [APP_HEADER_01.i_icon]
mov [ebx+APP_HDR.path], ecx
mov edx, [APP_HEADER_01.i_end]
mov [ebx+APP_HDR._edata], edx
ret
.fail:
xor eax, eax
ret
align 4
alloc_thread_slot:
;input:
; none
;result:
; eax=[new_thread_slot]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov edx, thr_slot_map
pushfd
cli
.l1:
bsf eax, [edx]
jnz .found
add edx, 4
cmp edx, thr_slot_map+32
jb .l1
popfd
xor eax, eax
ret
.found:
btr [edx], eax
sub edx, thr_slot_map
lea eax, [eax+edx*8]
popfd
ret
align 4
proc create_process stdcall, app_size:dword
locals
process dd ?
app_tabs dd ?
endl
push ebx
push esi
push edi
xor eax, eax
mov [process], eax
mov eax, [app_size]
add eax, 0x3FFFFF
shr eax, 22
mov [app_tabs], eax
stdcall kernel_alloc, 0x2000
test eax, eax
jz .fail
mov [process], eax
lea edi, [eax+PROC.heap_lock]
mov ecx, (PROC.ht_free-PROC.heap_lock)/4
list_init eax
add eax, PROC.thr_list
list_init eax
xor eax, eax
cld
rep stosd
mov [edi], dword (PROC.pdt_0 - PROC.htab)/4 - 3
mov [edi+4], dword 3 ;reserve handles for stdin stdout and stderr
mov ecx, (PROC.pdt_0 - PROC.htab)/4
add edi, 8
inc eax
@@:
stosd
inc eax
cmp eax, ecx
jbe @B
mov eax, edi
call get_pg_addr
mov [edi-4096+PROC.pdt_0_phys], eax
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
rep stosd
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20)
rep movsd
mov eax, [edi-8192+PROC.pdt_0_phys]
or eax, PG_SWR
mov [edi-4096+(page_tabs shr 20)], eax
lea edx, [edi-4096]
mov esi, [app_tabs]
.alloc_page_dir:
call alloc_page
test eax, eax
jz .fail
or eax, PG_UWR
mov [edx], eax
mov edi, [tmp_task_ptab]
stdcall map_page, edi, eax, PG_SWR
mov ecx, 1024
xor eax, eax
rep stosd
add edx, 4
dec esi
jnz .alloc_page_dir
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
mov eax, [process]
pop edi
pop esi
pop ebx
ret
.fail:
mov ecx, [process]
jcxz @F
call destroy_process
@@:
xor eax, eax
pop edi
pop esi
pop ebx
ret
endp
align 4
proc destroy_page_table stdcall, pg_tab:dword
push esi
mov esi, [pg_tab]
mov ecx, 1024
.free:
mov eax, [esi]
test eax, 1
jz .next
test eax, 2
jz .next
test eax, 1 shl 9
jnz .next ;skip shared pages
call free_page
.next:
add esi, 4
dec ecx
jnz .free
pop esi
ret
endp
align 4
destroy_process: ;fastcall ecx= ptr to process
lea eax, [ecx+PROC.thr_list]
cmp eax, [eax+LHEAD.next]
jne .exit
align 4
.internal:
push ecx
mov esi, ecx
list_del esi
mov esi, [esi+PROC.dlls_list_ptr]
call destroy_all_hdlls
mov esi, [esp]
add esi, PROC.pdt_0
mov edi, (0x80000000 shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page, [tmp_task_ptab], eax, PG_SWR
stdcall destroy_page_table, [tmp_task_ptab]
mov eax, [esi]
call free_page
.next:
add esi, 4
dec edi
jnz .destroy
call kernel_free ;ecx still in stack
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
.exit:
ret
align 4
get_pid:
mov eax, [TASK_BASE]
mov eax, [eax+TASKDATA.pid]
ret
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx, [TASK_COUNT]
shl ebx, 5
mov ecx, 2*32
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [CURRENT_TASK+ecx+0xa], 9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4], eax;check PID
jz .pid_found
.endloop:
add ecx, 32
cmp ecx, ebx
jle .loop
pop ecx
pop ebx
xor eax, eax
ret
.pid_found:
shr ecx, 5
mov eax, ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
check_region:
;input:
; esi - start of buffer
; edx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax, 1
ret
if 0
mov eax, [CURRENT_TASK]
; jmp check_process_region
;-----------------------------------------------------------------------------
;check_process_region:
;input:
; eax - slot
; esi - start of buffer
; edx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
test edx, edx
jle .ok
shl eax, 5
cmp word [CURRENT_TASK+eax+0xa], 0
jnz .failed
shl eax, 3
mov eax, [SLOT_BASE+eax+0xb8]
test eax, eax
jz .failed
mov eax, 1
ret
.ok:
mov eax, 1
ret
.failed:
xor eax, eax
ret
end if
align 4
proc read_process_memory
;Input:
; eax - process slot
; ecx - buffer address
; edx - buffer size
; esi - start address in other process
;Output:
; eax - number of bytes read.
locals
slot dd ?
buff dd ?
r_count dd ?
offset dd ?
tmp_r_cnt dd ?
endl
mov [slot], eax
mov [buff], ecx
and [r_count], 0
mov [tmp_r_cnt], edx
mov [offset], esi
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_r_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov ebx, [offset]
push ecx
stdcall map_memEx, [proc_mem_map], \
[slot], ebx, ecx, PG_READ
pop ecx
mov esi, [offset]
and esi, 0xfff
sub eax, esi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_r_cnt], eax
@@:
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
add [r_count], edx
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [r_count]
ret
endp
align 4
proc write_process_memory
;Input:
; eax - process slot
; ecx - buffer address
; edx - buffer size
; esi - start address in other process
;Output:
; eax - number of bytes written
locals
slot dd ?
buff dd ?
w_count dd ?
offset dd ?
tmp_w_cnt dd ?
endl
mov [slot], eax
mov [buff], ecx
and [w_count], 0
mov [tmp_w_cnt], edx
mov [offset], esi
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_w_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov ebx, [offset]
push ecx
stdcall map_memEx, [proc_mem_map], \
[slot], ebx, ecx, PG_SWR
pop ecx
mov edi, [offset]
and edi, 0xfff
sub eax, edi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_w_cnt], eax
@@:
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
add [w_count], edx
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [w_count]
ret
endp
;ebx = 1 - kernel thread
;ecx=thread entry point
;edx=thread stack pointer
;creation flags 0x01 - debugged
; 0x02 - kernel
align 4
proc new_sys_threads
locals
slot dd ?
flags dd ?
app_cmdline dd ? ;0x00
app_path dd ? ;0x04
app_eip dd ? ;0x08
app_esp dd ? ;0x0C
app_mem dd ? ;0x10
endl
shl ebx, 1
mov [flags], ebx
xor eax, eax
mov [app_eip], ecx
mov [app_cmdline], eax
mov [app_esp], edx
mov [app_path], eax
call lock_application_table
call alloc_thread_slot
test eax, eax
jz .failed
mov [slot], eax
mov esi, [current_slot]
mov ebx, esi ;ebx=esi - pointer to extended information about current thread
mov edi, eax
shl edi, 8
add edi, SLOT_BASE
mov edx, edi ;edx=edi - pointer to extended infomation about new thread
mov ecx, 256/4
xor eax, eax
cld
rep stosd ;clean extended information about new thread
mov esi, ebx
mov edi, edx
mov ecx, 11
rep movsb ;copy process name
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
push edx
stdcall user_alloc, 4096
pop edx
test eax, eax
jz .failed1;eax=0
@@:
mov [edx+APPDATA.tls_base], eax
mov eax, [ebx+APPDATA.process]
mov [edx+APPDATA.process], eax
lea ebx, [edx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail ebx, ecx ;add thread to process child's list
lea eax, [app_cmdline]
stdcall set_app_params , [slot], eax, [flags]
mov eax, [process_number] ;set result
call unlock_application_table
ret
.failed:
xor eax, eax
.failed1:
call unlock_application_table
dec eax ;-1
ret
endp
proc map_process_image stdcall, img_size:dword, file_base:dword, file_size:dword
mov edx, [img_size]
mov esi, [file_base]
mov ecx, [file_size]
add edx, 4095
add ecx, 4095
shr edx, 12 ; total pages
shr ecx, 12 ; image pages
mov edi, page_tabs
shr esi, 10
add esi, edi
.map_image:
lodsd
and eax, -4096
or eax, PG_UWR
stosd
dec edx
loop .map_image
test edx, edx
jz .done
.map_bss:
call alloc_page
test eax, eax
jz .fail
or eax, PG_UWR
stosd
dec edx
jnz .map_bss
mov edi, [file_size]
mov ecx, [img_size]
add edi, 4095
and edi, -4096
add ecx, 4095
and ecx, -4096
sub ecx, edi
shr ecx, 2
xor eax, eax
rep stosd
.done:
.fail:
ret
endp
align 4
common_app_entry:
mov ebp, [current_slot]
mov ebp, [ebp+APPDATA.exec_params]
test ebp, ebp
jz .exit
stdcall map_process_image, [ebp+APP_HDR._emem],\
[ebp+APP_HDR.img_base], [ebp+APP_HDR.img_size]
xor eax, eax
mov edi, [ebp+APP_HDR.path]
lea esi, [ebp+sizeof.APP_HDR]
mov ecx, [ebp+APP_HDR.filename_size]
test edi, edi
jnz .copy_filename
add esi, ecx
jmp .check_cmdline
.copy_filename:
rep movsb
stosb
.check_cmdline:
mov edi, [ebp+APP_HDR.cmdline]
mov ecx, [ebp+APP_HDR.cmdline_size]
test edi, edi
jz .check_tls_header
cmp ecx, 256
jb .copy_cmdline
mov edi, [ebp+APP_HDR._emem]
add edi, 4095
and edi, -4096
sub edi, ecx
dec edi
cmp word [6], '00'
jne @F
mov [APP_HEADER_00_.i_param], edi
jmp .copy_cmdline
@@:
mov [APP_HEADER_01_.i_param], edi
.copy_cmdline:
rep movsb
stosb
.check_tls_header:
cmp word [6], '02'
jne .cleanup
call init_heap
stdcall user_alloc, 4096
mov edx, [current_slot]
mov [edx+APPDATA.tls_base], eax
mov [tls_data_l+2], ax
shr eax, 16
mov [tls_data_l+4], al
mov [tls_data_l+7], ah
mov dx, app_tls
mov fs, dx
.cleanup:
stdcall free_kernel_space, [ebp+APP_HDR.img_base]
stdcall kernel_free, ebp
.exit:
popad
iretd
EFL_IF equ 0x0200
EFL_IOPL1 equ 0x1000
EFL_IOPL2 equ 0x2000
EFL_IOPL3 equ 0x3000
align 4
proc set_app_params stdcall,slot:dword, params:dword, flags:dword
locals
pl0_stack dd ?
endl
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [pl0_stack], eax
lea edi, [eax+RING0_STACK_SIZE]
mov eax, [slot]
mov ebx, eax
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
mov [eax+SLOT_BASE+APPDATA.terminate_protection], 80000001h
;set default io permission map
mov ecx, [SLOT_BASE+256+APPDATA.io_map]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [SLOT_BASE+256+APPDATA.io_map+4]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
mov esi, fpu_data
mov ecx, 512/4
rep movsd
cmp ebx, [TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
shl ebx, 8
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
mov [SLOT_BASE+APPDATA.fd_ev+ebx], edx
mov [SLOT_BASE+APPDATA.bk_ev+ebx], edx
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [SLOT_BASE+APPDATA.fd_obj+ebx], edx
mov [SLOT_BASE+APPDATA.bk_obj+ebx], edx
mov ecx, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor+ebx], ecx
mov eax, [pl0_stack]
mov [SLOT_BASE+APPDATA.pl0_stack+ebx], eax
add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
push ebx
stdcall kernel_alloc, 0x1000
pop ebx
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov ecx, 0x1000/4
mov edi, eax
mov [ebx+SLOT_BASE+APPDATA.cur_dir], eax
rep movsd
shr ebx, 3
mov dword [CURRENT_TASK+ebx+0x10], 0
mov ebx, [slot]
mov eax, ebx
shl ebx, 5
lea ecx, [draw_data+ebx];ecx - pointer to draw data
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx, CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number], al;set window number on screen = process slot
mov [ebx+TASKDATA.event_mask], dword 1+2+4;set default event flags (see 40 function)
inc dword [process_number]
mov eax, [process_number]
mov [ebx+4], eax ;set PID
;set draw data to full screen
xor eax, eax
mov [ecx+0], dword eax
mov [ecx+4], dword eax
mov eax, [screen_workarea.right]
mov [ecx+8], eax
mov eax, [screen_workarea.bottom]
mov [ecx+12], eax
mov ebx, [pl0_stack]
mov esi, [params]
lea ecx, [ebx+REG_EIP]
xor eax, eax
mov [ebx+REG_RET], dword common_app_entry
mov [ebx+REG_EDI], eax
mov [ebx+REG_ESI], eax
mov [ebx+REG_EBP], eax
mov [ebx+REG_ESP], ecx;ebx+REG_EIP
mov [ebx+REG_EBX], eax
mov [ebx+REG_EDX], eax
mov [ebx+REG_ECX], eax
mov [ebx+REG_EAX], eax
mov eax, [esi+APP_HDR.eip]
mov [ebx+REG_EIP], eax
mov [ebx+REG_CS], dword app_code
mov ecx, USER_PRIORITY
test byte [flags], 2
jz @F
mov [ebx+REG_CS], dword os_code ; kernel thread
mov ecx, MAX_PRIORITY
@@:
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
mov eax, [esi+APP_HDR.esp]
mov [ebx+REG_APP_ESP], eax
mov [ebx+REG_SS], dword app_data
lea edx, [ebx+REG_RET]
mov ebx, [slot]
shl ebx, 5
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], edx
xor edx, edx; process state - running
; set if debuggee
test byte [flags], 1
jz .no_debug
inc edx ; process state - suspended
mov eax, [CURRENT_TASK]
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot], eax
.no_debug:
mov [CURRENT_TASK+ebx+TASKDATA.state], dl
lea edx, [SLOT_BASE+ebx*8]
call scheduler_add_thread
ret
endp
align 4
get_stack_base:
mov eax, [current_slot]
mov eax, [eax+APPDATA.pl0_stack]
ret
include "debug.inc"