Raiden
Гость
|
|
« : 09-12-2004 20:08 » |
|
Здрасьте, господа кодеры :о) Такая проблемка... Нужно написать многозадачность: четыре процедуры, выводящие четыре своих сообщения; выполняются одновременно, для чего устанавливается обработчик прерывания системного таймера, который по кадому такту должен передавать управление следующей процедуре. Я написал прогу, но она жутко глючная - ниче нормально вывести не может - какие-то каракули пишет вместо нужных сообщений, подвисает в конце, но это еще ерунда, главная проблема - процедуры выполняются почему-то последовательно, а не одновременно. По моей задумке должно быть примерно так: обработчик проверяет, какую процедуру он прервал, сохраняет ее регистры и флаги в структуру этой процедуры, после чего восстанавливает регистры следующей процедуры, в частности загружает в стек ее cs, ip и флаги, затем вызывает команду iret. Процедуры запускаются из основной программы последовательно и обработчик определяет, сколько раз он уже запускался, и если он впервые прервал данную процедуру, то сохраняет ее регистры, а управление передает в основную программу (а не в процедуру), в которой сразу же (после очистки стека от ip этой процедуры) идет вызов следующей процедуры. Если же он для данной процедуры уже вызывался (а это значит, что у него есть запись о следующей процедуре), то он входит так сказать в освной режим и выполняет загрузку регистров следующей процедуры из ее структуры, как я сказал в предыдущем абзаце. Вот мой глючный код: .model tiny .code .586p org 100h
start{
mov ax,03h int 10h
call init_threads cld
call thread1 add sp,2 call thread2 add sp,2 call thread3 add sp,2 call thread4
call shutdown_mt
int 20h
thread struc _cx dw ? _si dw ? _di dw ? _ip dw ? _cs dw ? _flags dw ? thread ends
;;;;;;;///////;;;;;инициализация обработчика init_threads proc near
pushf pusha push es mov ax,3508h int 21h mov word ptr old_int,bx mov word ptr old_int+2,es mov ax,2508h mov dx,offset new_int int 21h pop es popa popf
init_threads endp
;;;;;;;;///////;;;;;шатдаун многозадачности shutdown_mt proc near mov ax,2508h lds dx,dword ptr old_int int 21h ret shutdown_mt endp
;;;;;;////////;;;;;;;;новый обработчик new_int proc far
pushf pusha db 9ah ;код команды call far - вызываем old_int dd 0 ;старый обработчик вначале
;передаем управление нужной процедуре - в зависимости от значения ;current_thread mov bx,current_thread shl bx,1 jmp cs{jump_table[bx(
jump_table dw m1,m2,m3,m4
m1{ call n1 jmp endcase m2{ call n2 jmp endcase m3{ call n3 jmp endcase m4{ call n4 jmp endcase
n1{ mov current_thread,2 ;сохраняем регистры. С первой тройкой все просто - остальные ;берем из стека mov thread_1._cx,cx mov thread_1._si,si mov thread_1._di,di
push ax push bp mov bp,sp
mov ax,word ptr [bp+22( mov thread_1._ip,ax mov ax,word ptr [bp+26( mov thread_1._flags,ax mov ax,word ptr [bp+24( mov thread_1._cs,ax pop bp pop ax
cli ;если счетчик больше нуля, то есть, мы тут уже были, то прыжок cmp counter,0 ja next1
;если мы в этой процедуре впервые, то ;запишем в стек, на место где у нас сейчас записан адрес возврата из ;обработчика в прерванную процедуру, адрес возврата процедуры ;в главный модуль, так, чтобы команда iret вернула нас не ;в прерванную процедуру, а в главный модуль.
inc counter sti push bp push ax mov bp,sp mov ax,word ptr [bp+28( mov word ptr [bp+22(,ax pop ax pop bp ret next1{ ;если мы в этой процедуре уже были )значит у нас заполнена структура второй процедуры:{ sti
mov cx,thread_2._cx mov si,thread_2._si mov di,thread_2._di push bp push ax mov bp,sp mov ax, word ptr [bp+26( mov ax,thread_2._flags mov ax, word ptr [bp+22( mov ax,thread_2._ip mov ax, word ptr [bp+24( mov ax,thread_2._cs pop ax pop bp
ret
n2{ mov current_thread,3 mov thread_2._cx,cx mov thread_2._si,si mov thread_2._di,di
push ax push bp mov bp,sp mov ax,word ptr [bp+22( mov thread_2._ip,ax mov ax,word ptr [bp+26( mov thread_2._flags,ax mov ax,word ptr [bp+24( mov thread_2._cs,ax pop bp pop ax
cli cmp counter,1 ja next2
inc counter sti
push bp push ax mov bp,sp mov ax,word ptr [bp+28( mov word ptr [bp+22(,ax pop ax pop bp
ret next2{
sti
mov cx,thread_3._cx mov si,thread_3._si mov di,thread_3._di
push bp push ax mov bp,sp mov ax, word ptr [bp+26( mov ax,thread_3._flags mov ax, word ptr [bp+22( mov ax,thread_3._ip mov ax, word ptr [bp+24( mov ax,thread_3._cs pop ax pop bp
; mov [sp+24(,thread_3._flags ; mov [sp+20(,thread_3._ip ; mov [sp+22(,thread_3._cs
ret
n3{ mov current_thread,4 mov thread_3._cx,cx mov thread_3._si,si mov thread_3._di,di
push ax push bp mov bp,sp mov ax,word ptr [bp+22( mov thread_3._ip,ax mov ax,word ptr [bp+26( mov thread_3._flags,ax mov ax,word ptr [bp+24( mov thread_3._cs,ax pop bp pop ax
cli cmp counter,2 ja next3
inc counter sti push bp push ax mov bp,sp mov ax,word ptr [bp+28( mov word ptr [bp+22(,ax pop ax pop bp
ret next3{
sti
mov cx,thread_4._cx mov si,thread_4._si mov di,thread_4._di
push bp push ax mov bp,sp mov ax, word ptr [bp+26( mov ax,thread_4._flags mov ax, word ptr [bp+22( mov ax,thread_4._ip mov ax, word ptr [bp+24( mov ax,thread_4._cs pop ax pop bp
ret
n4{ mov current_thread,1 mov thread_4._cx,cx mov thread_4._si,si mov thread_4._di,di push ax push bp mov bp,sp mov ax,word ptr [bp+22( mov thread_4._ip,ax mov ax,word ptr [bp+26( mov thread_4._flags,ax mov ax,word ptr [bp+24( mov thread_4._cs,ax pop bp pop ax
cli cmp counter,3 ja next4
inc counter sti
push bp push ax mov bp,sp mov ax,word ptr [bp+28( mov word ptr [bp+22(,ax pop ax pop bp
ret next4{
sti
mov cx,thread_1._cx mov si,thread_1._si mov di,thread_1._di push bp push ax mov bp,sp mov ax, word ptr [bp+26( mov ax,thread_1._flags mov ax, word ptr [bp+22( mov ax,thread_1._ip mov ax, word ptr [bp+24( mov ax,thread_1._cs pop ax pop bp
ret
endcase{
popa popf iret
new_int endp ;;;;////////////;;;;; закруглили обработчик.
;--------------------------------------
;сами процедуры thread1 proc near
push 0b800h pop es xor di,di mov si,offset string1 mov cx,ml1
cy1{ movsb inc si inc di push cx
;длииииииииииинная пауза чтоб виден был процесс. mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $
pop cx
loop cy1
ret thread1 endp
thread2 proc near
push 0b800h pop es xor di,di add di,100 mov si,offset string2 mov cx,ml2 cy2{ movsb inc si inc di
push cx mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $
mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ pop cx
loop cy2 ret thread2 endp
thread3 proc near push 0b800h pop es xor di,di add di,200 mov si,offset string3 mov cx,ml3
cy3{ movsb inc si inc di
push cx
mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $
mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ pop cx
loop cy3
ret thread3 endp
thread4 proc near push 0b800h pop es xor di,di add di,300 mov si,offset string4 mov cx,ml4
cy4{ movsb inc si inc di
push cx mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $
mov cx,-1 loop $ mov cx,-1 loop $ mov cx,-1 loop $ pop cx
loop cy4
ret thread4 endp
;тут я пытался строки задавать сразу с атрибутами, и без атрибутов ;и вообще, по-всякому {о: string1 db "Y",1fh,'o',1fh,'u',1fh,'a',1fh,'r',1fh db "e",1fh,' ',1fh,'j',1fh,'u',1fh,'s',1fh db "t",1fh,' ',1fh,'0',1fh,'`',1fh,'s',1fh db "`",1fh,'a',1fh,'n',1fh,'d',1fh,'`',1fh db "1",1fh,'`',1fh,'s',1fh ml1 = $-string1 string2 db "He just only human$" ml2 = $-string2 string3 db "Knock-knock, Neo!$" ml3 = $-string3 string4 db "Follow the white rabbit$" ml4 = $-string4
current_thread dw 1
counter db 0
thread_1 thread <> thread_2 thread <> thread_3 thread <> thread_4 thread <>
end start
Заранее благодарю...
|
|
|
Записан
|
|
|
|
Xeysan
Гость
|
|
« Ответ #1 : 09-12-2004 21:16 » |
|
Минск? БГУИР? ; +---------------------------+ ; | Task sheduler for RM, DOS | ; +---------------------------+
; Struct definition CONTEXT struc _ax dw 0 ; + 00h _bx dw 0 ; + 02h _cx dw 0 ; + 04h _dx dw 0 ; + 06h _si dw 0 ; + 08h _di dw 0 ; + 0Ah _bp dw 0 ; + 0Ch _sp dw 9Ah ; + 0Eh _ds dw 0 ; + 10h _es dw 0 ; + 12h _ss dw 0 ; + 14h _cs dw 0 ; + 16h _ip dw 100h ; + 18h _flags dw 0 ; + 1Ah _res dw 2 dup)0:; Reserved ends
CR = 0Dh LF = 0Ah
.model tiny .386 .code org 80h bCmdLen db ? bCmdSpace db ? bCmdLine db ? org 100h start{ ; Save task names from command line call About call SaveNames
; Free an extra memory and set new stack frame mov ah, 4Ah mov bx, offset PRG_END mov cl, 4 shr bx, cl add bx, 10h int 21h jc Error
shl bx, cl mov sp, bx
; Prepare Return data pushf pop dx ; Now bx contains flags
; Alloc memory for three tasks mov cx, 3 mov si, offset contexts mov di, offset PB1 push es Alloc{ mov ah, 48h mov bx, 50h int 21h jc Error mov es, ax mov word ptr [si + 10h(, ax mov word ptr [si + 12h(, ax mov word ptr [si + 14h(, ax mov word ptr [si + 16h(, ax mov word ptr [si + 1Ah(, dx ; Save flags
add ax, 10h mov word ptr [di(, ax add si, type CONTEXT add di, 2*2 dec cx jnz Alloc pop es
; Load three overlays mov ax, 4B03h mov dx, offset szTask1 mov bx, offset PB1 int 21h jc Error mov ax, 4B03h mov dx, offset szTask2 mov bx, offset PB2 int 21h jc Error mov ax, 4B03h mov dx, offset szTask3 mov bx, offset PB3 int 21h jc Error
; Set new interrrupt handlers for timer and kbd mov ax, 3508h int 21h mov word ptr dwTimerVec, bx mov word ptr dwTimerVec+2, es inc al int 21h mov word ptr dwKbdVec, bx mov word ptr dwKbdVec+2, es
mov ax, 2509h mov dx, offset KbdHandler int 21h dec al mov dx, offset cs{TimerHandler int 21h
; Wait for key pushf cli mov ax, PB3 sub ax, 10h push ax push 100h iret
; Restore interrupt handler ReturnHere{ lds dx, dword ptr cs{dwKbdVec mov ax, 2509h int 21h
int 20h Error{ mov dx, offset szSomething call ErrorExit contexts CONTEXT 3 dup)<>: ; Program contexts wContexts dw 0 ; Number of contexts szTask1 db 13 dup)0: ; First task name szTask2 db 13 dup)0: ; Second task name szTask3 db 13 dup)0: ; Third task name wNames dw szTask1 dw szTask2 dw szTask3 ; Parameter blocks PB1 dw 0 dw 0 PB2 dw 0 dw 0 PB3 dw 0 dw 0
; Old interrupt vectors dwTimerVec dd 0 dwKbdVec dd 0
; Error ) and about : messages szAbout db "* Task sheduler. Sylph, Minsk 2003 *",'$' szParams db CR, LF, "--> Not enough parameters in command line.",'$' szSomething db CR, LF, "--> Something happened, during initialization", '$'
; Procedures About proc near push ax push dx mov ah, 09h mov dx, offset szAbout int 21h pop dx pop ax ret About endp SaveNames proc near pusha
mov bx, offset wNames movzx cx, bCmdLen mov dx, 3 mov si, offset bCmdLine mov di, word ptr [bx(
SN_Find{ lodsb cmp al, ' ' je SN_Find cmp al, CR je SN_Finish jcxz SN_Finish
SN_Store{ stosb jcxz SN_Finish lodsb cmp al, CR je SN_Stop cmp al, ' ' jne SN_Store add bx, 2 mov di, word ptr [bx( SN_Stop{ dec dx jz SN_Finish jmp SN_Find SN_Finish{ test dx, dx jz SN_Return mov dx, offset szParams call ErrorExit SN_Return{ popa ret SaveNames endp
; dx keeps string with error message ErrorExit proc near mov ah, 09h int 21h int 20h ErrorExit endp
; Save context proc SaveContext proc near push bx mov bx, cs{wTask shl bx, 5 add bx, offset cs{contexts ; Save registers mov word ptr cs{[bx + 00h(, ax ; load registers, see CONTEXT pop word ptr cs{[bx + 02h( mov word ptr cs{[bx + 04h(, cx mov word ptr cs{[bx + 06h(, dx mov word ptr cs{[bx + 08h(, si mov word ptr cs{[bx + 0Ah(, di mov word ptr cs{[bx + 0Ch(, bp mov word ptr cs{[bx + 0Eh(, sp mov word ptr cs{[bx + 10h(, ds mov word ptr cs{[bx + 12h(, es mov word ptr cs{[bx + 14h(, ss mov bp, sp mov ax, word ptr [bp( mov word ptr cs{[bx + 18h(, ax ; Save ip mov ax, word ptr [bp + 2( mov word ptr cs{[bx + 16h(, ax ; Save cs mov ax, word ptr [bp + 4( mov word ptr cs{[bx + 1Ah(, ax ; Save flags jmp TH_SaveRet SaveContext endp
RestoreContext proc near mov bx, cs{wTask shl bx, 5 add bx, offset cs{contexts
mov ss, word ptr cs{[bx + 14h( mov es, word ptr cs{[bx + 12h( mov ds, word ptr cs{[bx + 10h( mov sp, word ptr cs{[bx + 0Eh( mov bp, word ptr cs{[bx + 0Ch( mov di, word ptr cs{[bx + 0Ah( mov si, word ptr cs{[bx + 08h( mov dx, word ptr cs{[bx + 06h( mov cx, word ptr cs{[bx + 04h( mov ax, word ptr cs{[bx + 00h(
push ax push bp mov bp, sp mov ax, word ptr cs{[bx + 18h( mov word ptr [bp + 04h(, ax mov ax, word ptr cs{[bx + 16h( mov word ptr [bp + 06h(, ax mov ax, word ptr cs{[bx + 1Ah( mov word ptr [bp + 08h(, ax pop bp pop ax
mov bx, word ptr cs{[bx + 02h( jmp short TH_NoSwitch RestoreContext endp
; Time proc data QUANTUM = 18 ; Full second wTimeStay dw QUANTUM ; Second for each task wTask dw 2 ; Current task
; Timer handler TimerHandler proc far dec cs{wTimeStay jnz TH_NoSwitch
mov word ptr cs{wTimeStay, QUANTUM jmp SaveContext ; Save context for current task TH_SaveRet{
dec word ptr cs{wTask jns TH_Restore mov word ptr cs{wTask, 2
TH_Restore{ jmp RestoreContext
TH_NoSwitch{ jmp dword ptr cs{dwTimerVec TimerHandler endp
; Kbd proc KbdHandler proc far pushf call dword ptr cs{dwKbdVec
lds dx, dword ptr cs{dwTimerVec mov ax, 2508h int 21h
jmp ReturnHere KbdHandler endp PRG_END label byte end start
Запускается так: shed.com task1.com task2.com task3.com Задачи вот: ( в принципе, они близнецы ) ; task 1 .model tiny .386 .code org 100h start{ mov ax, 0B800h mov es, ax mov cx, 80 xor di, di mov al, '1' and ah, 7Fh cld _Loop{ stosw dec cl test cl, cl jnz _Loop xor di, di xor al, '1' mov cl, 80 jmp _Loop end start
; task 2 .model tiny .386 .code org 100h start{ mov ax, 0B800h mov es, ax mov cx, 80 mov di, 80*2 mov al, '2' inc ah and ah, 7Fh cld _Loop{ stosw dec cl test cl, cl jnz _Loop mov di, 80*2 xor al, '2' mov cl, 80 jmp _Loop end start
; task 3 .model tiny .386 .code org 100h start{ mov ax, 0B800h mov es, ax mov cx, 80 mov di, 80*4 mov al, '3' dec ah and ah, 7Fh cld _Loop{ stosw dec cl test cl, cl jnz _Loop mov di, 80*4 xor al, '3' mov cl, 80 jmp _Loop end start
Заметь в задачах используются только регистры . Это не ОС, поэтому есть ограничения... Успехов! Да...на вопросы твои ( если они будут ), ответить быстро не смогу, у меня нет времени...
|
|
|
Записан
|
|
|
|