0% found this document useful (0 votes)
12 views16 pages

Document 25

Uploaded by

aneezakiran2007
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views16 pages

Document 25

Uploaded by

aneezakiran2007
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

Q1

; multitasking and dynamic thread registration

[org 0x0100]

jmp start

; 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

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

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

nextpcb: dw 1 ; index of next free pcb

current: dw 0 ; index of current pcb

lineno: dw 24 ; line number for next thread

char: dw '*'

col dw 0,80,75,70

;;;;; COPY LINES 028-071 FROM EXAMPLE 10.1 (printnum) ;;;;;

delay:

pusha

pushf

mov cx, 1000

mydelay:

mov bx, 500 ; increase to add more delay, decrease to reduce


delay

mydelay1:

dec bx

jnz mydelay1

loop mydelay
popf

popa

ret

; takes the row no, column no, and number to be printed as parameters

; subroutine to clear the screen

clrscr: push es

push ax

push cx

push di

mov ax, 0xb800

mov es, ax ; point es to video base

xor di, di ; point di to top left column

mov ax, 0x0720 ; space char in normal attribute

mov cx, 2000 ; number of screen locations

cld ; auto increment mode

rep stosw ; clear the whole screen

pop di

pop cx

pop ax

pop es

ret

printnum: push bp

mov bp, sp

push es
push ax

push bx

push cx

push dx

push di

call clrscr

mov di, 80 ; load di with columns per row

mov ax, [bp+8] ; load ax with row number

mul di ; multiply with columns per row

mov di, ax ; save result in di

add di, [bp+6] ; add column number

shl di, 1 ; turn into byte count

add di, 8 ; to end of number location

mov ax, 0xb800

mov es, ax ; point es to video base

mov dl,'*'

mov dh, 0x07 ; attach normal attribute

mov [es:di], dx ; print char on screen

pop di

pop dx

pop cx

pop bx

pop ax

pop es

pop bp

ret 6

; mytask subroutine to be run as a thread

; takes line number as parameter


mytask: push bp

mov bp, sp

sub sp, 2 ; thread local variable

push ax

push bx

mov ax, [bp+4] ; load line number parameter

mov bx, [col] ; use column number 70

; add byte[col],5

mov word [bp-2], 0 ; initialize local variable

printagain: push ax ; line number

push bx ; column number

push word [char] ; number to be printed

call printnum ; print the number

inc word [bp-2] ; increment the local variable

jmp printagain ; infinitely print

pop bx

pop ax

mov sp, bp

pop bp

ret

; subroutine to register a new thread

; takes the segment, offset, of the thread routine and a parameter

; for the target thread subroutine

initpcb: push bp

mov bp, sp
push ax

push bx

push cx

push si

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

cmp bx, 32 ; 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

pop cx

pop bx

pop ax

pop bp

ret 6

; timer interrupt service routine

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, 1

shl bx, 1

shl bx, 1

shl bx, 1

shl bx, 1 ; 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 diof 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: xor ax, ax

mov es, ax ; point es to IVT base

cli

mov word [es:8*4], timer

mov [es:8*4+2], cs ; hook timer interrupt

sti

nextkey:

xor ah, ah ; service 0 – get keystroke

int 0x16 ; bios keyboard services

push cs ; use current code segment


mov ax, mytask

push ax ; use mytask as offset

push word [lineno] ; thread parameter

call initpcb ; register the thread

dec word [lineno] ; update line number

cmp word[lineno],0

je reset

jmp nextkey ; wait for next keypress

reset:

mov word[lineno],24

jmp nextkey
Q2

;elementary multitasking of two threads

[org 0x0100]

jmp start

; ax,bx,ip,cs,flags storage area

taskstates: dw 0, 0, 0, 0, 0 ; task0 regs

dw 0, 0, 0, 0, 0 ; task1 regs

dw 0, 0, 0, 0, 0 ; task2 regs

current: db 0 ; index of current task

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

col db 0

col2 db 3

row db 0

row2 db 0

char db '*'
printloop:

pusha

mov word ax,[bp+4]

mov [col],ax

reset:

; Clear the character from the previous position

mov ah, 0x09 ; Function to print character

mov al, ' ' ; Load a space character into AL register

mov bh, 0 ; Page number (0 = active page)

mov bl, 7 ; Attribute (light gray on black)

mov cx, 1

int 0x10 ; Print space to clear the previous character

; set cursor again

mov ah, 0x02 ; Function to set cursor position

mov bh, 0 ; Page number (0 = active page)

mov dh, [row] ; Row (0-based, so 4 means row 5)

mov dl, [col] ; Column (0-based, so 9 means column 10)

mov byte[row],0

l1:

mov word bx,[row]

mov word ax,80

mul bx

add word ax,[col]

shl ax,1 ; ax now has the position of asterik at current time

; set cursor

mov ah, 0x02

mov bh, 0

mov dl, [col] ; Column (0-based)


mov dh, [row] ; Row (0-based)

int 0x10 ; BIOS interrupt to set cursor position

cmp byte [row], 0

je notspace

; set cursor for space printing

mov ah, 0x02 ; Function to set cursor position

mov bh, 0 ; Page number (0 = active page)

mov dh, [row] ; Row (0-based, so 4 means row 5)

dec dh

mov dl, [col] ; Column (0-based, so 9 means column 10)

int 0x10 ; BIOS interrupt to set cursor position

; Clear the character from the previous position

mov ah, 0x09 ; Function to print character

mov al, ' ' ; Load a space character into AL register

mov bh, 0 ; Page number (0 = active page)

mov bl, 7 ; Attribute (light gray on black)

mov cx, 1

int 0x10 ; Print space to clear the previous character

; set cursor again

mov ah, 0x02 ; Function to set cursor position

mov bh, 0 ; Page number (0 = active page)

mov dh, [row] ; Row (0-based, so 4 means row 5)

mov dl, [col] ; Column (0-based, so 9 means column 10)

int 0x10

notspace:

; Print the character at the current cursor position

mov ah, 0x09 ; Function to print character


mov al, [char] ; Load the character into AL register

mov bh, 0 ; Page number (0 = active page)

mov bl, 7 ; Attribute (light gray on black)

mov cx, 1

int 0x10 ; BIOS interrupt to print the character

call small_delay

;increment to next row

cmp byte [row],24

je reset

add byte [row],1

jmp l1

small_delay:

pusha

mov cx, 0x00FF ; Outer loop count (reduce for smaller delay)

delay_outer:

mov bx, 0x00FF ; Inner loop count (reduce for smaller delay)

delay_inner:

dec bx

jnz delay_inner

dec cx

jnz delay_outer

popa

ret

; one task to be multitasked

taskone:

push word [col]

call printloop
jmp taskone ; infinite task

; second task to be multitasked

tasktwo:

push word [col]

call printloop

jmp tasktwo ; infinite task

; timer interrupt service routine

timer: push ax

push bx

mov bl, [cs:current] ; read index of current task

mov ax, 10 ; space used by one task

mul bl ; multiply to get start of task

mov bx, ax ; load start of task in bx

pop ax ; read original value of bx

mov [cs:taskstates+bx+2], ax ; space for current task

pop ax ; read original value of ax

mov [cs:taskstates+bx+0], ax ; space for current task

pop ax ; read original value of ip

mov [cs:taskstates+bx+4], ax ; space for current task

pop ax ; read original value of cs

mov [cs:taskstates+bx+6], ax ; space for current task

pop ax ; read original value of flags

mov [cs:taskstates+bx+8], ax ; space for current task

inc byte [cs:current] ; update current task index


cmp byte [cs:current], 3 ; is task index out of range

jne skipreset ; no, proceed

mov byte [cs:current], 0 ; yes, reset to task 0

skipreset: mov bl, [cs:current] ; read index of current task

mov ax, 10 ; space used by one task

mul bl ; multiply to get start of task

mov bx, ax ; load start of task in bx

mov al, 0x20

out 0x20, al ; send EOI to PIC

push word [cs:taskstates+bx+8] ; flags of new task

push word [cs:taskstates+bx+6] ; cs of new task

push word [cs:taskstates+bx+4] ; ip of new task

mov ax, [cs:taskstates+bx+0] ; ax of new task

mov bx, [cs:taskstates+bx+2] ; bx of new task

iret ; return to new task

start: mov word [taskstates+10+4], taskone ; initialize ip

mov [taskstates+10+6], cs ; initialize cs

mov word [taskstates+10+8], 0x0200 ; initialize flags

mov word [taskstates+20+4], tasktwo ; initialize ip

mov [taskstates+20+6], cs ; initialize cs

mov word [taskstates+20+8], 0x0200 ; initialize flags

mov word [current], 0 ; set current task index

xor ax, ax

mov es, ax ; point es to IVT base


cli

mov word [es:8*4], timer

mov [es:8*4+2], cs ; hook timer interrupt

mov ax, 0xb800

mov es, ax ; point es to video base

xor bx, bx ; initialize bx for tasks

sti

jmp $

You might also like