Sunday 16 January 2011

CS401 Assignment#04 Sol

Modify multitasking and dynamic thread registration example (11.2) such that • It displays a rotating bar on top left corner of the screen (as in Example 11.1). • Also, if we press “S (both small and caps)”, it will generate new process which will display rotating bars on screen in next column from the previous one. • And if “Q (both small and caps)” is pressed from keyboard it will restore every thing to normal as it was before the multitasking kernel was there. You can generate maximum up to 20 processes. After 20 processes no new process will be created if “S (both small and caps)” will be pressed from keyboard

Solution:

[org 0x0100]

jmp start

; Original Registers:

;ax, bx, cx, dx, si, di, bp, sp, ip, cs, ds, ss, es, flags

; 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26  

; PCB layout:

;ax, bx, cx, dx, si, di, bp, sp, ip, cs, ds, ss, es, flags, next, dummy

; 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24,    26 ,  28 ,   30

originalstate:    times 14    dw    0

oldtimer:         dd    0

pcb:        times 20*16 dw 0        ; space for 20 PCBs

stack:      times 20*256 dw 0       ; space for 20 512 byte stacks

nextpcb:    dw   1                  ; index of next free pcb

current:    dw   0                  ; index of current pcb

column_no:  dw   0                  ; column for next thread

chars:      db   '/-\|'             ; shapes to form a bar

mytask:

push bp                       ;save registers value

mov  bp, sp

push ds

push es

push di

push ax

push bx

mov  ax, 0xb800

mov  es, ax                   ; point es to video base

push cs

pop  ds                       ; point ds to current segment

mov  di, [bp+4]               ; load ax with column number

shl  di, 1                    ; turn into byte count

and  bx, 0                    ; initialize bx

mov  ah, 0x07                 ; normal attribute

rotation:

mov  al, [chars+bx]           ; read current shape

mov  [es:di], ax              ; print at specified place

inc  bx                       ; update for next shape

and  bx, 3                    ; take modulus with 4

jmp  rotation                 ; repeat infinitely

pop  di                       ; restore register values

pop  bx

pop  ax

pop  es

pop  ds

pop  bp

ret

initpcb:

push bp                       ; save registers

mov  bp, sp

push ax

push bx

push cx

push si

mov  bx, [nextpcb]            ; read next available pcb index

cmp  bx, 20                   ; are all PCBs used

je   exit                     ; yes, exit

mov  cl, 5             

shl  bx, cl                   ; multiply by 32 for pcb start

mov  ax, [bp+8]               ; read segment parameter

mov  [pcb+bx+18], ax          ; save in pcb space for cs

mov  ax, [bp+6]               ; read offset parameter

mov  [pcb+bx+16], ax          ; save in pcb space for ip

mov  [pcb+bx+22], ds          ; set stack to our segment

mov  si, [nextpcb]            ; read this pcb index

mov  cl, 9             

shl  si, cl                   ; multiply by 512

add  si, 256*2+stack          ; end of stack for this thread

mov  ax, [bp+4]               ; read parameter for subroutine

sub  si, 2                    ; decrement thread stack pointer

mov  [si], ax                 ; pushing param on thread stack

sub  si, 2                    ; space for return address

mov  [pcb+bx+14], si          ; save si in pcb space for sp

mov  word [pcb+bx+26], 0x0200 ; initialize thread flags

mov  ax, [pcb+28]             ; read next of 0th thread in ax

mov  [pcb+bx+28], ax          ; set as next of new thread

mov  ax, [nextpcb]            ; read new thread index  

mov  [pcb+28], ax             ; set as next of 0th thread

inc  word [nextpcb]           ; this pcb is now used

exit:

pop  si                       ; restore all registers

pop  cx

pop  bx

pop  ax

pop  bp

ret  6                        ;discard 3 parameters from stack

timer:

push ds

push bx

push cs

pop  ds                       ; initialize ds to data segment

mov  bx, [current]            ; read index of current in bx

shl  bx, 5                    ; multiply by 32 for pcb start

mov  [pcb+bx+0], ax           ; save ax in current pcb

mov  [pcb+bx+4], cx           ; save cx in current pcb

mov  [pcb+bx+6], dx           ; save dx in current pcb

mov  [pcb+bx+8], si           ; save si in current pcb

mov  [pcb+bx+10], di          ; save di in current pcb

mov  [pcb+bx+12], bp          ; save bp in current pcb

mov  [pcb+bx+24], es          ; save es in current pcb

pop  ax                       ; read original bx from stack

mov  [pcb+bx+2], ax           ; save bx in current pcb

pop  ax                       ; read original ds from stack

mov  [pcb+bx+20], ax          ; save ds in current pcb

pop  ax                       ; read original ip from stack

mov  [pcb+bx+16], ax          ; save ip in current pcb

pop  ax                       ; read original cs from stack

mov  [pcb+bx+18], ax          ; save cs in current pcb

pop  ax                       ; read original flags from stack

mov  [pcb+bx+26], ax          ; save cs in current pcb

mov  [pcb+bx+22], ss          ; save ss in current pcb

mov  [pcb+bx+14], sp          ; save sp in current pcb

mov  bx, [pcb+bx+28]          ; read next pcb of this pcb

mov  [current], bx            ; update current to new pcb

mov  cl, 5            

shl  bx, cl                   ; multiply by 32 for pcb start

mov  cx, [pcb+bx+4]           ; read cx of new process

mov  dx, [pcb+bx+6]           ; read dx of new process

mov  si, [pcb+bx+8]           ; read si of new process

mov  di, [pcb+bx+10]          ; read di of new process

mov  bp, [pcb+bx+12]          ; read bp of new process

mov  es, [pcb+bx+24]          ; read es of new process

mov  ss, [pcb+bx+22]          ; read ss of new process

mov  sp, [pcb+bx+14]          ; read sp of new process

push word [pcb+bx+26]         ; push flags of new process

push word [pcb+bx+18]         ; push cs of new process

push word [pcb+bx+16]         ; push ip of new process

push word [pcb+bx+20]         ; push ds of new process

mov  al, 0x20

out  0x20, al                 ; send EOI to PIC

mov  ax, [pcb+bx+0]           ; read ax of new process

mov  bx, [pcb+bx+2]           ; read bx of new process

pop  ds                       ; read ds of new process

iret                          ; return to new process

start:

mov  [originalstate], ax      ; save original state

mov  [originalstate +2], bx        

mov  [originalstate +4], cx     

mov  [originalstate +6], dx    

mov  [originalstate +8], si     

mov  [originalstate +10], di 

mov  [originalstate +12], bp   

mov  [originalstate +14], sp   

mov  [originalstate +20], ds    

mov  [originalstate +22], ss     

mov  [originalstate +24], es     

pushf                         ; push flags on stack

pop  word [originalstate +26] ; save flags register in memory    

xor  ax, ax                   ; initialize ax with zero

mov  es, ax                   ; point es to IVT base

mov  bx, [es:8*4]             ; load offset of timer ISR

mov  word [oldtimer], bx      ; save original ISR offset

mov  bx, [es:8*4+2]           ; load segment of timer ISR

mov  [oldtimer +2], bx        ; save original ISR segment

cli                           ; disable all interrupts

mov  word [es:8*4], timer     ; hooking timer interrupt

mov  [es:8*4+2], cs

sti                           ; enable interrupts    

nextkey:

xor ah, ah              ; service 0 - get keystroke

int 0x16                ; bios keyboard services

cmp al, ‘s’             ; compeare if s is pressed

je  newtask             ; if s is pressed go to newtask

cmp al, ‘S’             ; compeare if S is pressed

je  newtask             ; if S is pressed go to newtask

cmp al, ‘q’             ; compeare if q is pressed

je  quit                ; if q is pressed go to quit

cmp al, ‘Q’             ; compeare if Q is pressed

je  quit                ; if Q is pressed go to quit

jmp nextkey             ; otherwise wait for next key

newtask:  

push cs                 ; use current code segment

mov  ax, mytask      

push ax                 ; use mytask as offset

push word [column_no]   ; Pushing [column_no] as thread parameter

call initpcb            ; register the thread

inc  word [column_no]   ; increment column_no by 1

jmp  nextkey            ; wait for next keypress

quit:

xor  ax, ax

mov  es, ax                   ; point es to IVT base

cli                           ; disable interrupts

mov  ax, word [oldtimer]      ; load timer offset in ax

mov  [es:8*4], ax             ; Point IVT to original timer ISR

mov  ax, word [oldtimer+2]    ; load timer segment in ax

mov  [es:8*4+2], ax           ; Point IVT to original timer ISR

sti                           ; enable interrupts

mov  ax, [originalstate]      ; restore original state

mov  bx, [originalstate +2]   

mov  cx, [originalstate +4]     

mov  dx, [originalstate +6]     

mov  si, [originalstate +8]        

mov  di, [originalstate +10]      

mov  bp, [originalstate +12]      

mov  sp, [originalstate +14]      

mov  ds, [originalstate +20]     

mov  ss, [originalstate +22]   

mov  es, [originalstate +24]  

push word [originalstate +26]     

popf                          ; restore flag register

mov  ah, 0x4c                 ; DOS service to terminate program

int  0x21

 

 

 

1 comments:

AOA
Good Program but error this program, check it.

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More