|
|||||
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
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
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
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
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
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
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
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
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
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
Table of Contents:
|
|||||