ZeePedia Add to Favourites   |   Contact us


Assembly Language Programming

<<< Previous Multitasking: Concept, Elaborate, Multitasking Kernel as TSR Next >>>
 
img
11
Multitasking
11.1. CONCEPTS OF MULTITASKING
To experience the power of assembly language we introduce how to
implement multitasking. We observed in the debugger that our thread of
instructions was broken by the debugger; it got the control, used all
registers, displayed an elaborate interface, waited for the key, and then
restored processor state to what was immediately before interruption. Our
program resumed as if nothing happened. The program execution was in the
same logical flow.
If we have two different programs A and B. Program A is broken, its state
saved, and returned to B instead of A. By looking at the instruction set, we
can immediately say that nothing can stop us from doing that. IRET will
return to whatever CS and IP it finds on the stack. Now B is interrupted
somehow, its state saved, and we return back to A. A will have no way of
knowing that it was interrupted as its entire environment has been restored.
It never knew the debugger took control when it was debugged. It sill has no
way of gaining this knowledge. If this work of breaking and restoring
programs is done at high speed the user will feel that all the programs are
running at the same time where actually they are being switched to and forth
at high speed.
In essence multitasking is simple, even though we have to be extremely
careful when implementing it. The environment of a program in the very
simple case is all its registers and stack. We will deal with stack later. Now to
get control from the program without the program knowing about it, we can
use the IRQ 0 highest priority interrupt that is periodically coming to the
processor.
Now we present a very basic example of multitasking. We have two
subroutines written in assembly language. All the techniques discussed here
are applicable to code written in higher level languages as well. However the
code to control this multitasking cannot be easily written in a higher level
language so we write it in assembly language. The two subroutines rotate
bars by changing characters at the two corners of the screen and have
infinite loops. By hooking the timer interrupt and saving and restoring the
registers of the tasks one by one, it appears that both tasks are running
simultaneously.
Example 11.1
001
; elementary multitasking of two threads
002
[org 0x0100]
003
jmp start
004
005
;
ax,bx,ip,cs,flags storage area
006
taskstates:
dw
0, 0, 0, 0, 0
; task0 regs
007
dw
0, 0, 0, 0, 0
; task1 regs
008
dw
0, 0, 0, 0, 0
; task2 regs
009
010
current:
db
0
; index of current task
011
chars:
db
'\|/-'
; shapes to form a bar
012
013
; one task to be multitasked
014
taskone:
mov  al, [chars+bx]
; read the next shape
015
mov  [es:0], al
; write at top left of screen
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
016
inc
bx
; increment to next shape
017
and
bx, 3
; taking modulus by 4
018
jmp
taskone
; infinite task
019
020
; second task to be multitasked
021
tasktwo:
mov  al, [chars+bx]
;
read the next shape
022
mov  [es:158], al
;
write at top right of screen
023
inc  bx
;
increment to next shape
024
and  bx, 3
;
taking modulus by 4
025
jmp  tasktwo
;
infinite task
026
027
; timer interrupt service routine
028
timer:
push ax
029
push bx
030
031
mov
bl, [cs:current]
;
read index of current task
032
mov
ax, 10
;
space used by one task
033
mul
bl
;
multiply to get start of task
034
mov
bx, ax
;
load start of task in bx
035
036
pop
ax
; read original value of bx
037
mov
[cs:taskstates+bx+2], ax ; space for current task
038
pop
ax
; read original value of ax
039
mov
[cs:taskstates+bx+0], ax ; space for current task
040
pop
ax
; read original value of ip
041
mov
[cs:taskstates+bx+4], ax ; space for current task
042
pop
ax
; read original value of cs
043
mov
[cs:taskstates+bx+6], ax ; space for current task
044
pop
ax
; read original value of flags
045
mov
[cs:taskstates+bx+8], ax ; space for current task
046
047
inc
byte [cs:current]
;
update current task index
048
cmp
byte [cs:current],
3
; is task index out of range
049
jne
skipreset
;
no, proceed
050
mov
byte [cs:current],
0
; yes, reset to task 0
051
052
skipreset:
mov
bl, [cs:current]
;
read index of current task
053
mov
ax, 10
;
space used by one task
054
mul
bl
;
multiply to get start of task
055
mov
bx, ax
;
load start of task in bx
056
057
mov
al, 0x20
058
out
0x20, al
; send EOI to PIC
059
060
push
word [cs:taskstates+bx+8] ;
flags of new task
061
push
word [cs:taskstates+bx+6] ;
cs of new task
062
push
word [cs:taskstates+bx+4] ;
ip of new task
063
mov
ax, [cs:taskstates+bx+0]  ;
ax of new task
064
mov
bx, [cs:taskstates+bx+2]  ;
bx of new task
065
iret
; return
to new task
066
067
start:
mov
word [taskstates+10+4],
taskone ; initialize ip
068
mov
[taskstates+10+6], cs
; initialize cs
069
mov
word [taskstates+10+8],
0x0200 ; initialize flags
070
mov
word [taskstates+20+4],
tasktwo ; initialize ip
071
mov
[taskstates+20+6], cs
; initialize cs
072
mov
word [taskstates+20+8],
0x0200 ; initialize flags
073
mov
word [current], 0
; set current task index
074
075
xor
ax, ax
076
mov
es, ax
; point es to IVT base
077
cli
078
mov
word [es:8*4], timer
079
mov
[es:8*4+2], cs
; hook timer interrupt
080
mov
ax, 0xb800
081
mov
es, ax
; point es to video base
082
xor
bx, bx
; initialize bx for tasks
083
sti
084
085
jmp $
; infinite loop
The space where all registers of a task are stored is called the process
control block or PCB. Actual PCB contains a few more things that are not
132
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
relevant to us now. INT 08 that is saving and restoring the registers is called
the scheduler and the whole event is called a context switch.
11.2. ELABORATE MULTITASKING
In our next example we will save all 14 registers and the stack as well. 28
bytes are needed by these registers in the PCB. We add some more space to
make the size 32, a power of 2 for easy calculations. One of these words is
used to form a linked list of the PCBs so that strict ordering of active PCBs is
not necessary. Also in this example we have given every thread its own stack.
Now threads can have function calls, parameters and local variables etc.
Another important change in this example is that the creation of threads is
now dynamic. The thread registration code initializes the PCB, and adds it to
the linked list so that the scheduler will give it a turn.
Example 11.2
001
; multitasking and dynamic thread registration
002
[org 0x0100]
003
jmp start
004
005
; PCB layout:
006
; ax,bx,cx,dx,si,di,bp,sp,ip,cs,ds,ss,es,flags,next,dummy
007
;  0, 2, 4, 6, 8,10,12,14,16,18,20,22,24,  26 , 28 ,  30
008
009
pcb:
times 32*16 dw 0
;
space for 32 PCBs
010
stack:
times 32*256 dw 0
;
space for 32 512 byte stacks
011
nextpcb:
dw
1
;
index of next free pcb
012
current:
dw
0
;
index of current pcb
013
lineno:
dw
0
;
line number for next thread
014-057
058
;;;;; COPY LINES 028-071 FROM EXAMPLE 10.1 (printnum) ;;;;;
059
060
; mytask subroutine to
be run as a thread
061
; takes line number as
parameter
062
mytask:
push bp
063
mov  bp,
sp
064
sub  sp,
2
; thread local variable
065
push ax
066
push bx
067
068
mov
ax, [bp+4]
; load line number parameter
069
mov
bx, 70
; use column number 70
070
mov
word [bp-2], 0
; initialize local variable
071
072
printagain:
push
ax
;
line number
073
push
bx
;
column number
074
push
word [bp-2]
;
number to be printed
075
call
printnum
;
print the number
076
inc
word [bp-2]
;
increment the local variable
077
jmp
printagain
;
infinitely print
078
079
pop
bx
080
pop
ax
081
mov
sp, bp
082
pop
bp
083
ret
084
085
; subroutine to register a new thread
086
; takes the segment, offset, of the thread routine and a parameter
087
; for the target thread subroutine
088
initpcb:
push bp
089
mov  bp, sp
090
push ax
091
push bx
092
push cx
093
push si
094
095
mov
bx, [nextpcb]
; read next available pcb index
096
cmp
bx, 32
; are all PCBs used
097
je
exit
; yes, exit
098
133
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
099
mov
cl, 5
100
shl
bx, cl
; multiply by 32 for pcb start
101
102
mov
ax, [bp+8]
;
read
segment parameter
103
mov
[pcb+bx+18], ax
;
save
in pcb space for cs
104
mov
ax, [bp+6]
;
read
offset parameter
105
mov
[pcb+bx+16], ax
;
save
in pcb space for ip
106
107
mov
[pcb+bx+22], ds
; set stack to our segment
108
mov
si, [nextpcb]
; read this pcb index
109
mov
cl, 9
110
shl
si, cl
;
multiply by 512
111
add
si, 256*2+stack
;
end of stack for this thread
112
mov
ax, [bp+4]
;
read parameter for subroutine
113
sub
si, 2
;
decrement thread stack pointer
114
mov
[si], ax
;
pushing param on thread stack
115
sub
si, 2
;
space for return address
116
mov
[pcb+bx+14], si
;
save si in pcb space for sp
117
118
mov
word [pcb+bx+26], 0x0200 ; initialize thread flags
119
mov
ax, [pcb+28]
; read next of 0th thread in ax
120
mov
[pcb+bx+28], ax
; set as next of new thread
121
mov
ax, [nextpcb]
; read new thread index
123
mov
[pcb+28], ax
; set as next of 0th thread
124
inc
word [nextpcb]
; this pcb is now used
125
126
exit:
pop
si
127
pop
cx
128
pop
bx
129
pop
ax
130
pop
bp
131
ret
6
132
133
; timer interrupt service routine
134
timer:
push ds
135
push bx
136
137
push cs
138
pop  ds
; initialize ds to data segment
139
140
mov
bx, [current]
; read index of current in bx
141
shl
bx, 1
142
shl
bx, 1
143
shl
bx, 1
144
shl
bx, 1
145
shl
bx, 1
;
multiply by 32 for
pcb start
146
mov
[pcb+bx+0], ax
;
save ax in current
pcb
147
mov
[pcb+bx+4], cx
;
save cx in current
pcb
148
mov
[pcb+bx+6], dx
;
save dx in current
pcb
149
mov
[pcb+bx+8], si
;
save si in current
pcb
150
mov
[pcb+bx+10], di
;
save di in current
pcb
151
mov
[pcb+bx+12], bp
;
save bp in current
pcb
152
mov
[pcb+bx+24], es
;
save es in current
pcb
153
154
pop
ax
;
read
original bx from stack
155
mov
[pcb+bx+2], ax
;
save
bx in current pcb
156
pop
ax
;
read
original ds from stack
157
mov
[pcb+bx+20], ax
;
save
ds in current pcb
158
pop
ax
;
read
original ip from stack
159
mov
[pcb+bx+16], ax
;
save
ip in current pcb
160
pop
ax
;
read
original cs from stack
161
mov
[pcb+bx+18], ax
;
save
cs in current pcb
162
pop
ax
;
read
original flags from stack
163
mov
[pcb+bx+26], ax
;
save
cs in current pcb
164
mov
[pcb+bx+22], ss
;
save
ss in current pcb
165
mov
[pcb+bx+14], sp
;
save
sp in current pcb
166
167
mov
bx, [pcb+bx+28]
; read next pcb of this pcb
168
mov
[current], bx
; update current to new pcb
169
mov
cl, 5
170
shl
bx, cl
; multiply by 32 for pcb start
171
172
mov
cx,
[pcb+bx+4]
;
read
cx of new process
173
mov
dx,
[pcb+bx+6]
;
read
dx of new process
174
mov
si,
[pcb+bx+8]
;
read
si of new process
175
mov
di,
[pcb+bx+10]
;
read
diof new process
134
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
176
mov
bp,
[pcb+bx+12]
;
read
bp
of
new
process
177
mov
es,
[pcb+bx+24]
;
read
es
of
new
process
178
mov
ss,
[pcb+bx+22]
;
read
ss
of
new
process
179
mov
sp,
[pcb+bx+14]
;
read
sp
of
new
process
180
181
push
word
[pcb+bx+26]
;
push
flags
of new process
182
push
word
[pcb+bx+18]
;
push
cs of
new process
183
push
word
[pcb+bx+16]
;
push
ip of
new process
184
push
word
[pcb+bx+20]
;
push
ds of
new process
185
186
mov
al, 0x20
187
out
0x20, al
; send EOI to PIC
188
189
mov  ax, [pcb+bx+0]
;
read ax of new process
190
mov  bx, [pcb+bx+2]
;
read bx of new process
191
pop  ds
;
read ds of new process
192
iret
;
return to new process
193
194
start:
xor
ax, ax
195
mov
es, ax
; point es to IVT base
196
197
cli
198
mov
word [es:8*4], timer
199
mov
[es:8*4+2], cs
; hook timer interrupt
200
sti
201
202
nextkey:
xor ah, ah
; service 0 ­ get keystroke
203
int 0x16
; bios keyboard services
204
205
push
cs
; use current code segment
206
mov
ax, mytask
207
push
ax
; use mytask as offset
208
push
word [lineno]
; thread parameter
209
call
initpcb
; register the thread
210
211
inc
word [lineno]
; update line number
212
jmp
nextkey
; wait for next keypress
When the program is executed the threads display the numbers
independently. However as keys are pressed and new threads are registered,
there is an obvious slowdown in the speed of multitasking. To improve that,
we can change the timer interrupt frequency. The following can be used to
set to an approximately 1ms interval.
mov
ax, 1100
out
0x40, al
mov
al, ah
out
0x40, al
This makes the threads look faster. However the only real change is that
the timer interrupt is now coming more frequently.
11.3. MULTITASKING KERNEL AS TSR
The above examples had the multitasking code and the multitasked code
in one program. Now we separate the multitasking kernel into a TSR so that
it becomes an operation system extension. We hook a software interrupt for
the purpose of registering a new thread.
Example 11.3
001
; multitasking kernel as a TSR
002
[org 0x0100]
003
jmp start
004
005
; PCB layout:
006
; ax,bx,cx,dx,si,di,bp,sp,ip,cs,ds,ss,es,flags,next,dummy
007
;  0, 2, 4, 6, 8,10,12,14,16,18,20,22,24,  26 , 28 ,  30
008
009
pcb:
times 32*16 dw 0
; space for 32 PCBs
135
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
010
stack:
times 32*256 dw 0
; space for 32 512 byte stacks
011
nextpcb:
dw
1
; index of next free pcb
012
current:
dw
0
; index of current pcb
013
014-073
;;;;; COPY LINES 133-192 FROM EXAMPLE 11.2 (timer) ;;;;;
074
075
; software interrupt to register a new thread
076
; takes parameter block in ds:si
077
; parameter block has cs, ip, ds, es, and param in this order
078
initpcb:
push ax
079
push bx
080
push cx
081
push di
082
083
mov
bx, [cs:nextpcb]
; read next available pcb index
084
cmp
bx, 32
; are all PCBs used
085
je
exit
; yes, exit
086
087
mov
cl, 5
088
shl
bx, cl
; multiply by 32 for pcb start
089
090
mov
ax, [si+0]
;
read
code segment parameter
091
mov
[cs:pcb+bx+18],
ax ;
save
in pcb space for cs
092
mov
ax, [si+2]
;
read
offset parameter
093
mov
[cs:pcb+bx+16],
ax ;
save
in pcb space for ip
094
mov
ax, [si+4]
;
read
data segment parameter
095
mov
[cs:pcb+bx+20],
ax ;
save
in pcb space for ds
096
mov
ax, [si+6]
;
read
extra segment parameter
097
mov
[cs:pcb+bx+24],
ax ;
save
in pcb space for es
098
099
mov
[cs:pcb+bx+22], cs
; set stack to our segment
100
mov
di, [cs:nextpcb]
; read this pcb index
101
mov
cl, 9
102
shl
di, cl
;
multiply by 512
103
add
di, 256*2+stack
;
end of stack for this thread
104
mov
ax, [si+8]
;
read parameter for subroutine
105
sub
di, 2
;
decrement thread stack pointer
106
mov
[cs:di], ax
;
pushing param on thread stack
107
sub
di, 4
;
space for far return address
108
mov
[cs:pcb+bx+14], di
;
save di in pcb space for sp
109
110
mov
word [cs:pcb+bx+26],
0x0200 ; initialize flags
111
mov
ax, [cs:pcb+28]
;
read next of 0th thread in ax
112
mov
[cs:pcb+bx+28], ax ;
set as next of new thread
113
mov
ax, [cs:nextpcb]
;
read new thread index
114
mov
[cs:pcb+28], ax
;
set as next of 0th thread
115
inc
word [cs:nextpcb]  ;
this pcb is now used
116
117
exit:
pop
di
118
pop
cx
119
pop
bx
120
pop
ax
121
iret
123
124
start:
xor ax, ax
125
mov es, ax
; point es to IVT base
126
127
mov
word [es:0x80*4], initpcb
128
mov
[es:0x80*4+2], cs
; hook software int 80
129
cli
130
mov
word [es:0x08*4], timer
131
mov
[es:0x08*4+2], cs
; hook timer interrupt
132
sti
133
134
mov
dx,
start
135
add
dx,
15
136
mov
cl,
4
137
shr
dx,
cl
138
139
mov ax, 0x3100
; terminate and stay resident
140
int 0x21
The second part of our example is a simple program that has the threads
to be registered with the multitasking kernel using its exported services.
136
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
Example 11.4
001
; multitasking TSR caller
002
[org 0x0100]
003
jmp start
004
005
; parameter block layout:
006
; cs,ip,ds,es,param
007
;  0, 2, 4, 6,  8
008
009
paramblock:
times 5 dw 0
; space for parameters
010
lineno:
dw
0
; line number for next thread
011
012-055
;;;;; COPY LINES 028-071 FROM EXAMPLE 10.1 (printnum) ;;;;;
056
057
; subroutine to be run
as a thread
058
; takes line number as
parameter
059
mytask:
push bp
060
mov  bp,
sp
061
sub  sp,
2
; thread local variable
062
push ax
063
push bx
064
065
mov
ax, [bp+4]
; load line number parameter
066
mov
bx, 70
; use column number 70
067
mov
word [bp-2], 0
; initialize local variable
068
069
printagain:
push
ax
;
line number
070
push
bx
;
column number
071
push
word [bp-2]
;
number to be printed
072
call
printnum
;
print the number
073
inc
word [bp-2]
;
increment the local variable
074
jmp
printagain
;
infinitely print
075
076
pop
bx
077
pop
ax
078
mov
sp, bp
079
pop
bp
080
retf
081
082
start:
mov
ah, 0
; service 0 ­ get keystroke
083
int
0x16
; bios keyboard services
084
085
mov
[paramblock+0], cs ;
code segment parameter
086
mov
word [paramblock+2],
mytask ; offset parameter
087
mov
[paramblock+4], ds ;
data segment parameter
088
mov
[paramblock+6], es ;
extra segment parameter
089
mov
ax, [lineno]
090
mov
[paramblock+8], ax ;
parameter for thread
091
mov
si, paramblock
;
address of param block in si
092
int
0x80
;
multitasking kernel interrupt
093
094
inc
word [lineno]
; update line number
095
jmp
start
; wait for next key
We introduce yet another use of the multitasking kernel with this new
example. In this example three different sort of routines are multitasked by
the same kernel instead of repeatedly registering the same routine.
Example 11.5
001
; another multitasking TSR caller
002
[org 0x0100]
003
jmp start
004
005
; parameter block layout:
006
; cs,ip,ds,es,param
007
;  0, 2, 4, 6,  8
008
009
paramblock:
times 5 dw 0
;
space for parameters
010
lineno:
dw
0
;
line number for next thread
011
chars:
db '\|/-'
;
chracters for rotating bar
012
message:
db 'moving hello'
;
moving string
013
message2:
db '
'
;
to erase previous string
137
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
014
messagelen:
dw 12
; length of above strings
015
016-059
;;;;; COPY LINES 028-071 FROM EXAMPLE 10.1 (printnum) ;;;;;
060-101
;;;;; COPY LINES 073-114 FROM EXAMPLE 10.1 (printstr) ;;;;;
102
103
; subroutine to run as first thread
104
mytask:
push bp
105
mov  bp, sp
106
sub  sp, 2
; thread local variable
107
push ax
108
push bx
109
110
xor
ax, ax
; use line number 0
111
mov
bx, 70
; use column number 70
112
mov
word [bp-2], 0
; initialize local variable
113
114
printagain:
push
ax
;
line number
115
push
bx
;
column number
116
push
word [bp-2]
;
number to be printed
117
call
printnum
;
print the number
118
inc
word [bp-2]
;
increment the local variable
119
jmp
printagain
;
infinitely print
120
121
pop
bx
123
pop
ax
124
mov
sp, bp
125
pop
bp
126
retf
127
128
; subroutine to run as second thread
129
mytask2:
push ax
130
push bx
131
push es
132
133
mov
ax, 0xb800
134
mov
es, ax
; point es to video base
135
xor
bx, bx
; initialize to use first shape
136
137
rotateagain:
mov
al, [chars+bx]
;
read current shape
138
mov
[es:40], al
;
print at specified place
139
inc
bx
;
update to next shape
140
and
bx, 3
;
take modulus with 4
141
jmp
rotateagain
;
repeat infinitely
142
143
pop  es
144
pop  bx
145
pop  ax
146
retf
147
148
; subroutine to run as third thread
149
mytask3:
push bp
150
mov  bp, sp
151
sub  sp, 2
; thread local variable
152
push ax
153
push bx
154
push cx
155
156
mov
word [bp-2], 0
; initialize line number to 0
157
158
nextline:
push
word [bp-2]
; line number
159
mov
bx, 50
160
push
bx
; column number 50
161
mov
ax, message
162
push
ax
; offset of string
163
push
word [messagelen]
; length of string
164
call
printstr
; print the string
165
166
mov
cx, 0x100
167
waithere:
push
cx
; save outer loop counter
168
mov
cx, 0xffff
169
loop
$
; repeat ffff times
170
pop
cx
; restore outer loop counter
171
loop
waithere
; repeat 0x100 times
172
173
push word [bp-2]
; line number
174
mov  bx, 50
; column number 50
138
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
175
push
bx
176
mov
ax, message2
177
push
ax
; offset of blank string
178
push
word [messagelen]
; length of string
179
call
printstr
; print the string
180
181
inc
word [bp-2]
;
update line number
182
cmp
word [bp-2], 25
;
is this the last line
183
jne
skipreset
;
no, proceed to draw
184
mov
word [bp-2], 0
;
yes, reset line number to 0
185
186
skipreset:
jmp
nextline
; proceed with next drawing
187
188
pop
cx
189
pop
bx
190
pop
ax
191
mov
sp, bp
192
pop
bp
193
retf
194
195
start:
mov
[paramblock+0], cs ;
code segment parameter
196
mov
word [paramblock+2],
mytask ; offset parameter
197
mov
[paramblock+4], ds ;
data segment parameter
198
mov
[paramblock+6], es ;
extra segment parameter
199
mov
word [paramblock+8],
0 ; parameter for thread
200
mov
si, paramblock
;
address of param block in si
201
int
0x80
;
multitasking kernel interrupt
202
203
mov
[paramblock+0], cs ;
code segment parameter
204
mov
word [paramblock+2],
mytask2 ; offset parameter
205
mov
[paramblock+4], ds ;
data segment parameter
206
mov
[paramblock+6], es ;
extra segment parameter
207
mov
word [paramblock+8],
0 ; parameter for thread
208
mov
si, paramblock
;
address of param block in si
209
int
0x80
;
multitasking kernel interrupt
210
211
mov
[paramblock+0], cs ;
code segment parameter
212
mov
word [paramblock+2],
mytask3 ; offset parameter
213
mov
[paramblock+4], ds ;
data segment parameter
214
mov
[paramblock+6], es ;
extra segment parameter
215
mov
word [paramblock+8],
0 ; parameter for thread
216
mov
si, paramblock
;
address of param block in si
217
int
0x80
;
multitasking kernel interrupt
218
219
jmp $
EXERCISES
1. Change the multitasking kernel such that a new two byte variable is
introduced in the PCB. This variable contains the number of turns
this process should be given. For example if the first PCB contains 20
in this variable, the switch to second process should occur after 20
timer interrupts (approx one second at default speed) and similarly
the switch from second to third process should occur after the
number given in the second process's PCB.
2. Change the scheduler of the multitasking kernel to enque the current
process index a ready queue, and dequeue the next process index
from it, and assign it to current. Therefore the next field of the PCB is
no longer used. Use queue functions from Exercise 5.XX.
3. Add a function in the multitasking kernel to fork the current process
through a software interrupt. Fork should allocate a new PCB and
copy values of all registers of the caller's PCB to the new PCB. It
should allocate a stack and change SS, SP appropriately in the new
PCB. It has to copy the caller's stack on the newly allocated stack. It
will set AX in the new PCB to 0 and in the old PB to 1 so that both
threads can identify which is the creator and which is the created
process and can act accordingly.
139
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
4. Add a function in the multitasking kernel accessible via a software
interrupt that allows the current process to terminate itself.
5. Create a queue in the multitasking kernel called kbQ. This queue
initially empty will contain characters typed by the user. Hook the
keyboard interrupt for getting user keys. Convert the scan code to
ASCII if the key is from a-z or 0-9 and enque it in kbQ. Ignore all
other scan codes. Write a function checkkey accessible via a software
interrupt that returns the process in AX a value removed from the
queue. It waits if there is no key in the queue. Be aware of enabling
interrupts if you wait here.
6. Modify the multitasking kernel such that the initial process displays
at the last line of the screen whatever is typed by the user and clears
that line on enter. If the user types quit followed by enter restore
everything to normal as it was before the multitasking kernel was
there. If the user types start followed by enter, start one more rotating
bar on the screen. The first rotating bar should appear in the upper
left, the next in the second column, then third and so on. The bar
color should be white. The user can type the commands `white', `red',
and `green' to change the color of new bars.
140