ZeePedia Add to Favourites   |   Contact us


Assembly Language Programming

<<< Previous Secondary Storage: Storage Access Using BIOS, DOS, Device Drivers Next >>>
 
img
13
Secondary Storage
13.1. PHYSICAL FORMATION
A floppy disk is a circular plate with a fine coating of magnetic material
over it. The plate is enclosed in a plastic jacket which has a cover that can
slide to expose the magnetic surface. The drive motor attaches itself to the
central piece and rotates the plate. Two heads on both sides can read the
magnetically encoded data on the disk.
If the head is fixed and the motor rotates the disk the readable area on the
disk surface forms a circle called a track. Head moved to the next step forms
another track and so on. In hard disks the same structure is extended to a
larger number of tracks and plates. The tracks are further cut vertically into
sectors. This is a logical division of the area on the tracks. Each sector holds
512 bytes of data. A standard floppy disk has 80 tracks and 18 sectors per
track with two heads, one on each side totallying to 2880 sectors or 1440 KB
of data. Hard disks have varying number of heads and tracks pertaining to
their different capacities.
BIOS sees the disks as a combination of sectors, tracks, and heads, as a
raw storage device without concern to whether it is reading a file or directory.
BIOS provides the simplest and most powerful interface to the storage
medium. However this raw storage is meaningless to the user who needs to
store his files and organize them into directories. DOS builds a logical
structure on this raw storage space to provide these abstractions. This
logical formation is read and interpreted by DOS. If another file system is
build on the same storage medium the interpretations change. Main units of
the DOS structure are the boot sector in head 0, track 0, and sector 1, the
first FAT starting from head 0, track 0, sector 2, the second copy of FAT
starting from head 0, track 0, sector 11, and the root directory starting from
head 1, track 0, sector 2. The area from head 0, track 1, sector 16 to head 1,
track 79, sector 18 is used for storing the data of the files. Among this we will
be exploring the directory structure further. The 32 sectors reserved for the
root directory contain 512 directory entries. The format of a 32 byte directory
entry is shown below.
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
+00 Filename (8 bytes)
+08 Extension (3 bytes)
+0B Flag Byte (1 byte)
+0C Reserved (1 byte)
+0D Creation Date/Time (5 bytes)
+12 Last Accessed Data (2 bytes)
+14 Starting Cluster High Word (2 bytes) for FAT32
+16 Time (2 bytes)
+18 Date (2 bytes)
+1A Starting Cluster Low Word (2 bytes)
+1C File Size (4 bytes)
13.2. STORAGE ACCESS USING BIOS
We will be using BIOS disk services to directly see the data stored in the
directory entries by DOS. For this purpose we will be using the BIOS disk
services.
INT 13 - DISK - RESET DISK SYSTEM
AH = 00h
DL = drive
Return:
CF = error flag
AH = error code
INT 13 - DISK - READ SECTOR(S) INTO MEMORY
AH = 02h
AL = number of sectors to read (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5)
high two bits of cylinder (bits 6-7, hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
Return:
CF = error flag
AH = error code
AL = number of sectors transferred
INT 13 - DISK - WRITE DISK SECTOR(S)
AH = 03h
AL = number of sectors to write (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5)
high two bits of cylinder (bits 6-7, hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
Return:
CF = error flag
AH = error code
AL = number of sectors transferred
INT 13 - DISK - GET DRIVE PARAMETERS
AH = 08h
DL = drive (bit 7 set for hard disk)
Return:
CF = error flag
AH = error code
CH = low eight bits of maximum cylinder number
CL = maximum sector number (bits 5-0)
148
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
high two bits of maximum cylinder number (bits 7-6)
DH = maximum head number
DL = number of drives
ES:DI -> drive parameter table (floppies only)
Example 13.1
001
; floppy directory using bios services
002
[org 0x0100]
003
jmp  start
004
005
sector:
times 512 db 0
; space for directory sector
006
entryname:
times 11 db 0
; space for a file name
007
db
10, 13, '$'
; new line and terminating $
008
009
start:
mov
ah, 0
;
service 0 ­ reset disk system
010
mov
dl, 0
;
drive A:
011
int
0x13
;
bios disk services
012
jc
error
;
if error, terminate program
013
014
mov
ah, 2
;
service 2 ­ read sectors
015
mov
al, 1
;
count of sectors
016
mov
ch, 0
;
cyliner
017
mov
cl, 2
;
sector
018
mov
dh, 1
;
head
019
mov
dl, 0
;
drive A:
020
mov
bx, sector
;
buffer to read sector
021
int
0x13
;
bios disk services
022
jc
error
;
if error, terminate program
023
024
mov
bx,
0
;
start from first entry
025
nextentry:
mov
di,
entryname
;
point di to space for filename
026
mov
si,
sector
;
point si to sector
027
add
si,
bx
;
move ahead to desired entry
028
mov
cx,
11
;
one filename is 11 bytes long
029
cld
;
auto increment mode
030
rep
movsb
;
copy filename
031
032
mov
ah, 9
; service 9 ­ output string
033
mov
dx, entryname
; filename to be printed
034
int
0x21
; dos services
035
036
add
bx, 32
; point to next dir entry
037
cmp
bx, 512
; is last entry in this sector
038
jne
nextentry
; no, print next entry
039
040
error:
mov
ax, 0x4c00
; terminate program
041
int
0x21
With the given services and the bits allocated for heads, tracks, and
sectors only 8GB disks can be accessed. This limitation can be overcome by
using INT 13 extensions that take a linear 64bit sector number and handle
all the head, track, sector conversion themselves. The important services in
this category are listed below.
INT 13 - INT 13 Extensions - EXTENDED READ
AH = 42h
DL = drive number
DS:SI -> disk address packet
Return:
CF = error flag
AH = error code
disk address packet's block count field set to number of blocks
successfully transferred
INT 13 - INT 13 Extensions - EXTENDED WRITE
AH = 43h
AL = write flags
149
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
DL = drive number
DS:SI -> disk address packet
Return:
CF = error flag
AH = error code
disk address packet's block count field set to number of blocks
successfully transferred
The format of the disk address packet used above is as follows.
Offset Size
Description
00h
BYTE
size of packet = 10h
01h
BYTE
reserved (0)
02h
WORD
number of blocks to transfer
04h
DWORD
-> transfer buffer
08h
QWORD
starting absolute block number
Hard disks have a different formation from floppy disks in that there is a
partition table at the start that allows several logical disks to be maintained
within a single physical disk. The physical sector 0 holds the master boot
record and a partition table towards the end. The first 446 bytes contain
MBR, then there are 4 16 byte partition entries and then there is a 2 byte
signature. A partition table entry has the following format.
Byte 0 ­ 0x80 for active 0x00 for inactive
Byte 1-3 ­ Starting CHS
Byte 4 ­ Partition Type
Byte 5-7 ­ Ending CHS
Byte 8-B ­ Starting LBA
Byte C-F ­ Size of Partition
Some important partition types are listed below.
00 Unused Entry
01 FAT12
05 Extended Partition
06 FAT16
0b FAT32
0c FAT32 LBA
0e FAT16 LBA
0f Extended LBA
07 NTFS
Extended partition type signals that the specified area is treated as a
complete hard disk with its own partition table and partitions. Therefore
extended partitions allow a recursion in partitioning and consequently an
infinite number of partitions are possible. The following program reads the
partition tables (primary and extended) using recursion and displays in an
indented form all partitions present on the first hard disk in the system.
Example 13.2
001
; a program to display the partition table
002
[org 0x0100]
003
jmp  start
004
005
dap:
db
0x10, 0
; disk address packet
006
dw
1
007
dd
0, 0, 0
150
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
008
009-026
msg:
times 17 db ' '
027
db
10, 13, '$'
028
fat12:
db
'FAT12...$'
029
fat16:
db
'FAT16...$'
030
fat32:
db
'FAT32...$'
031
ntfs:
db
'NTFS....$'
032
extended:
db
'EXTEND..$'
033
unknown:
db
'UNKNOWN.$'
034
035
partypes:
dw
0x1,
fat12
; table of known partition types
036
dw
0x5,
extended
037
dw
0x6,
fat16
038
dw
0xe,
fat16
039
dw
0xb,
fat32
040
dw
0xc,
fat32
041
dw
0x7,
ntfs
042
dw
0xf,
extended
043
dw
0x0,
unknown
044
045
; subroutine to print a number in a string as hex
046
; takes address of string and a 16bit number as parameter
047
printnum:
push bp
048
mov  bp, sp
049
push ax
050
push bx
051
push cx
052
push dx
053
push di
054
055
mov
di, [bp+6]
; string to store the number
056
add
di, 3
057
058
mov
ax, [bp+4]
; load number in ax
059
mov
bx, 16
; use base 16 for division
060
mov
cx, 4
061
062
nextdigit:
mov
dx, 0
063
div
bx
; divide by 16
064
add
dl, 0x30
; convert into ascii value
065
cmp
dl, 0x39
066
jbe
skipalpha
067
068
add
dl, 7
069
070
skipalpha:
mov  [di], dl
; update char in string
071
dec  di
072
loop nextdigit
073
074
pop
di
075
pop
dx
076
pop
cx
077
pop
bx
078
pop
ax
079
pop
bp
080
ret
4
081
082
; subroutine to print the start and end of a partition
083
; takes the segment and offset of the partition table entry
084
printpart:
push bp
085
mov  bp, sp
086
push es
087
push ax
088
push di
089
090
les
di, [bp+4]
; point es:di to dap
091
092
mov
ax, msg
093
push
ax
094
push
word [es:di+0xA]
095
call
printnum
; print first half of start
096
097
add
ax, 4
098
push
ax
099
push
word [es:di+0x8]
100
call
printnum
; print second half of start
151
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
101
102
add
ax, 5
103
push
ax
104
push
word [es:di+0xE]
105
call
printnum
; print first half of end
106
107
add
ax, 4
108
push
ax
109
push
word [es:di+0xC]
110
call
printnum
; print second half of end
111
112
mov
dx, msg
113
mov
ah, 9
114
int
0x21
; print the whole on the screen
115
116
pop
di
117
pop
ax
118
pop
es
119
pop
bp
120
ret
4
121
123
; recursive subroutine to read the partition table
124
; take indentation level and 32bit absolute block number as parameters
125
readpart:
push bp
126
mov  bp, sp
127
sub  sp, 512
; local space to read sector
128
push ax
129
push bx
130
push cx
131
push dx
132
push si
133
134
mov
ax, bp
135
sub
ax, 512
136
mov
word [dap+4], ax
; init dest offset in dap
137
mov
[dap+6], ds
; init dest segment in dap
138
mov
ax, [bp+4]
139
mov
[dap+0x8], ax
; init sector no in dap
140
mov
ax, [bp+6]
141
mov
[dap+0xA], ax
; init second half of sector no
142
143
mov
ah, 0x42
;
read sector in LBA mode
144
mov
dl, 0x80
;
first hard disk
145
mov
si, dap
;
address of dap
146
int
0x13
;
int 13
147
148
jc
failed
; if failed, leave
149
150
mov
si, -66
;
start of partition info
151
nextpart:
mov
ax, [bp+4]
;
read relative sector number
152
add
[bp+si+0x8], ax
;
make it absolute
153
mov
ax, [bp+6]
;
read second half
154
adc
[bp+si+0xA], ax
;
make seconf half absolute
155
156
cmp
byte [bp+si+4], 0
; is partition unused
157
je
exit
158
159
mov
bx, partypes
; point to partition types
160
mov
di, 0
161
nextmatch:
mov
ax, [bx+di]
162
cmp
[bp+si+4], al
;
is this
partition known
163
je
found
;
yes, so
print its name
164
add
di, 4
;
no, try
next entry in table
165
cmp
di, 32
;
are all
entries compared
166
jne
nextmatch
;
no, try
another
167
168
found:
mov
cx, [bp+8]
; load indentation level
169
jcxz
noindent
; skip if no indentation needed
170
indent:
mov
dl, ' '
171
mov
ah, 2
; display char service
172
int
0x21
; dos services
173
loop
indent
; print required no of spaces
174
175
noindent:
add
di, 2
176
mov
dx, [bx+di]
; point to partition type name
177
mov
ah, 9
; print string service
152
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
178
int
0x21
; dos services
179
180
push
ss
181
mov
ax, bp
182
add
ax, si
183
push
ax
; pass partition entry address
184
call
printpart
; print start and end from it
185
186
cmp
byte [bp+si+4], 5
; is it an extended partition
187
je
recurse
; yes, make a recursive call
188
189
cmp
byte [bp+si+4], 0xf ; is it an extended partition
190
jne
exit
; yes, make a recursive call
191
192
recurse:
mov
ax, [bp+8]
193
add
ax, 2
; increase indentation level
194
push
ax
195
push
word [bp+si+0xA]
; push partition type address
196
push
word [bp+si+0x8]
197
call
readpart
; recursive call
198
199
exit:
add
si, 16
; point to next partition entry
200
cmp
si, -2
; gone past last entry
201
jne
nextpart
; no, read this entry
202
203
failed:
pop
si
204
pop
dx
205
pop
bx
206
pop
cx
207
pop
ax
208
mov
sp, bp
209
pop
bp
210
ret
6
211
212
start:
xor
ax, ax
213
push
ax
; start from zero indentation
214
push
ax
; main partition table at 0
215
push
ax
216
call
readpart
; read and print it
217
218
mov
ax, 0x4c00
; terminate program
219
int
0x21
13.3. STORAGE ACCESS USING DOS
BIOS provides raw access to the storage medium while DOS gives a more
logical view and more cooked services. Everything is a file. A directory is a
specially organized file that is interpreted by the operating system itself. A
list of important DOS services for file manipulation is given below.
INT 21 - CREATE OR TRUNCATE FILE
AH = 3Ch
CX = file attributes
DS:DX -> ASCIZ filename
Return:
CF = error flag
AX = file handle or error code
INT 21 - OPEN EXISTING FILE
AH = 3Dh
AL = access and sharing modes
DS:DX -> ASCIZ filename
CL = attribute mask of files to look for (server call only)
Return:
CF = error flag
AX = file handle or error code
INT 21 - CLOSE FILE
AH = 3Eh
153
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
BX = file handle
Return:
CF = error flag
AX = error code
INT 21 - READ FROM FILE
AH = 3Fh
BX = file handle
CX = number of bytes to read
DS:DX -> buffer for data
Return:
CF = error flag
AX = number of bytes actually read or error code
INT 21 - WRITE TO FILE
AH = 40h
BX = file handle
CX = number of bytes to write
DS:DX -> data to write
Return:
CF = error flag
AX = number of bytes actually written or error code
INT 21 - DELETE FILE
AH = 41h
DS:DX -> ASCIZ filename (no wildcards, but see notes)
Return:
CF = error flag
AX = error code
INT 21 - SET CURRENT FILE POSITION
AH = 42h
AL = origin of move
BX = file handle
CX:DX = offset from origin of new file position
Return:
CF = error flag
DX:AX = new file position in bytes from start of file
AX = error code in case of error
INT 21 - GET FILE ATTRIBUTES
AX = 4300h
DS:DX -> ASCIZ filename
Return:
CF = error flag
CX = file attributes
AX = error code
INT 21 - SET FILE ATTRIBUTES
AX = 4301h
CX = new file attributes
DS:DX -> ASCIZ filename
Return:
CF = error flag
AX = error code
We will use some of these services to find that two files are same in
contents or different. We will read the file names from the command prompt.
The command string is passed to the program in the program segment prefix
located at offset 0 in the current segment. The area from 0-7F contains
information for DOS, while the command tail length is stored at 80. From 81
to FF, the actual command tail is stored terminated by a CR (Carriage
Retrun).
154
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
Example 13.3
001
; file comparison using dos services
002
[org 0x0100]
003
jmp  start
004
005
filename1:
times 128 db 0
;
space for first filename
006
filename2:
times 128 db 0
;
space for second filename
007
handle1:
dw
0
;
handle for first file
008
handle2:
dw
0
;
handle for second file
009
buffer1:
times 4096 db 0
;
buffer for first file
010
buffer2:
times 4096 db 0
;
buffer for second file
011
012
format:
db
'Usage error: diff <filename1> <filename2>$'
013
openfailed:
db
'First file could not be opened$'
014
openfailed2:
db
'Second file could not be opened$'
015
readfailed:
db
'First file could not be read$'
016
readfailed2:
db
'Second file could not be read$'
017
different:
db
'Files are different$'
018
same:
db
'Files are same$'
019
020
start:
mov  ch, 0
021
mov  cl, [0x80]
;
command tail length in cx
022
dec  cx
;
leave the first space
023
mov  di, 0x82
;
start of command tail in di
024
mov  al, 0x20
;
space for parameter separation
025
cld
;
auto increment mode
026
repne scasb
;
search space
027
je
param2
;
if found, proceed
028
mov  dx, format
;
else, select error message
029
jmp  error
;
proceed to error printing
030
031
param2:
push
cx
;
save original cx
032
mov
si, 0x82
;
set si to start of param
033
mov
cx, di
;
set di to end of param
034
sub
cx, 0x82
;
find param size in cx
035
dec
cx
;
excluding the space
036
mov
di, filename1
;
set di to space for filename 1
037
rep
movsb
;
copy filename there
038
mov
byte [di], 0
;
terminate filename with 0
039
pop
cx
;
restore original cx
040
inc
si
;
go to start of next filename
041
mov
di, filename2
;
set di to space for filename 2
042
rep
movsb
;
copy filename there
043
mov
byte [di], 0
;
terminate filename with 0
044
045
mov
ah, 0x3d
;
service 3d ­ open file
046
mov
al, 0
;
readonly mode
047
mov
dx, filename1
;
address of filename
048
int
0x21
;
dos services
049
jnc
open2
;
if no error, proceed
050
mov
dx, openfailed
;
else, select error message
051
jmp
error
;
proceed to error printing
052
053
open2:
mov [handle1], ax
;
save handle for first file
054
mov  ah, 0x3d
;
service 3d ­ open file
055
mov  al, 0
;
readonly mode
056
mov  dx, filename2
;
address of filename
057
int  0x21
;
dos services
058
jnc  store2
;
if no error, proceed
059
mov  dx, openfailed2
;
else, select error message
060
jmp  error
;
proceed to error printing
061
062
store2:
mov
[handle2], ax
; save handle for second file
063
064
readloop:
mov
ah, 0x3f
;
service 3f ­ read file
065
mov
bx, [handle1]
;
handle for file to read
066
mov
cx, 4096
;
number of bytes to read
067
mov
dx, buffer1
;
buffer to read in
068
int
0x21
;
dos services
069
jnc
read2
;
if no error, proceed
070
mov
dx, readfailed
;
else, select error message
071
jmp
error
;
proceed to error printing
072
073
read2:
push ax
; save number of bytes read
074
mov  ah, 0x3f
; service 3f ­ read file
155
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
075
mov
bx, [handle2]
;
handle for file to read
076
mov
cx, 4096
;
number of bytes to read
077
mov
dx, buffer2
;
buffer to read in
078
int
0x21
;
dos services
079
jnc
check
;
if no error, proceed
080
mov
dx, readfailed2
;
else, select error message
081
jmp
error
;
proceed to error printing
082
083
check:
pop
cx
;
number of bytes read of file 1
084
cmp
ax, cx
;
are number of byte same
085
je
check2
;
yes, proceed to compare them
086
mov
dx, different
;
no, files are different
087
jmp
error
;
proceed to message printing
088
089
check2:
test
ax, ax
;
are zero bytes read
090
jnz
compare
;
no, compare them
091
mov
dx, same
;
yes, files are same
092
jmp
error
;
proceed to message printing
093
094
compare:
mov
si, buffer1
;
point si to file 1 buffer
095
mov
di, buffer2
;
point di to file 2 buffer
096
repe
cmpsb
;
compare the two buffers
097
je
check3
;
if equal, proceed
098
mov
dx, different
;
else, files are different
099
jmp
error
;
proceed to message printing
100
101
check3:
cmp
ax, 4096
; were 4096 bytes read
102
je
readloop
; yes, try to read more
103
mov
dx, same
; no, files are same
104
105
error:
mov
ah, 9
; service 9 ­ output message
106
int
0x21
; dos services
107
108
mov
ah, 0x3e
; service 3e ­ close file
109
mov
bx, [handle1]
; handle of file to close
110
int
0x21
; dos services
111
112
mov
ah, 0x3e
; service 3e ­ close file
113
mov
bx, [handle2]
; handle of file to close
114
int
0x21
; dos services
115
116
mov
ax, 0x4c00
; terminate program
117
int
0x21
Another interesting service that DOS provides regarding files is executing
them. An important point to understand here is that whenever a program is
executed in DOS all available memory is allocated to it. No memory is
available to execute any new programs. Therefore memory must be freed
using explicit calls to DOS for this purpose before a program is executed.
Important services in this regard are listed below.
INT 21 - ALLOCATE MEMORY
AH = 48h
BX = number of paragraphs to allocate
Return:
CF = error flag
AX = segment of allocated block or error code in case of error
BX = size of largest available block in case of error
INT 21 - FREE MEMORY
AH = 49h
ES = segment of block to free
Return:
CF = error flag
AX = error code
INT 21 - RESIZE MEMORY BLOCK
AH = 4Ah
BX = new size in paragraphs
ES = segment of block to resize
156
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
Return:
CF = error flag
AX = error code
BX = maximum paragraphs available for specified memory block
INT 21 - LOAD AND/OR EXECUTE PROGRAM
AH = 4Bh
AL = type of load (0 = load and execute)
DS:DX -> ASCIZ program name (must include extension)
ES:BX -> parameter block
Return:
CF = error flag
AX = error code
The format of parameter block is as follows.
Offset Size
Description
00h
WORD
segment of environment to copy for child process
(copy caller's environment if 0000h)
02h
DWORD
pointer to command tail to be copied into child's PSP
06h
DWORD
pointer to first FCB to be copied into child's PSP
0Ah
DWORD
pointer to second FCB to be copied into child's PSP
0Eh
DWORD
(AL=01h) will hold subprogram's initial SS:SP on return
12h
DWORD
(AL=01h) will hold entry point (CS:IP) on return
As an example we will use the multitasking kernel client from the
multitasking chapter and modify it such that after running all three threads
it executes a new instance of the command prompt instead of indefinitely
hanging around.
Example 13.4
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
014
messagelen:
dw 12
;
length of above strings
015
tail:
db ' ',13
016
command:
db 'COMMAND.COM', 0
017
execblock:
times 11 dw 0
018
019-062
;;;;;
COPY
LINES
028-071
FROM
EXAMPLE
10.1
(printnum) ;;;;;
063-104
;;;;;
COPY
LINES
073-114
FROM
EXAMPLE
10.1
(printstr) ;;;;;
104-127
;;;;;
COPY
LINES
103-126
FROM
EXAMPLE
11.5
(mytask) ;;;;;
128-146
;;;;;
COPY
LINES
128-146
FROM
EXAMPLE
11.5
(mytask2) ;;;;;
147-192
;;;;;
COPY
LINES
148-193
FROM
EXAMPLE
11.5
(mytask3) ;;;;;
193
194
start:
mov
[paramblock+0], cs ;
code segment parameter
195
mov
word [paramblock+2],
mytask ; offset parameter
196
mov
[paramblock+4], ds ;
data segment parameter
197
mov
[paramblock+6], es ;
extra segment parameter
198
mov
word [paramblock+8],
0 ; parameter for thread
199
mov
si, paramblock
;
address of param block in si
200
int
0x80
;
multitasking kernel interrupt
201
202
mov
[paramblock+0], cs ; code segment parameter
203
mov
word [paramblock+2], mytask2 ; offset parameter
204
mov
[paramblock+4], ds ; data segment parameter
157
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
205
mov
[paramblock+6], es ;
extra segment parameter
206
mov
word [paramblock+8],
0 ; parameter for thread
207
mov
si, paramblock
;
address of param block in si
208
int
0x80
;
multitasking kernel interrupt
209
210
mov
[paramblock+0], cs ;
code segment parameter
211
mov
word [paramblock+2],
mytask3 ; offset parameter
212
mov
[paramblock+4], ds ;
data segment parameter
213
mov
[paramblock+6], es ;
extra segment parameter
214
mov
word [paramblock+8],
0 ; parameter for thread
215
mov
si, paramblock
;
address of param block in si
216
int
0x80
;
multitasking kernel interrupt
217
218
mov
ah, 0x4a
; service 4a ­ resize memory
219
mov
bx, end
; end of memory retained
220
add
bx, 15
; rounding up
221
mov
cl, 4
222
shr
bx, cl
; converting into paras
223
int
0x21
; dos services
224
225
mov
ah, 0x4b
;
service 4b - exec
226
mov
al, 0
;
load and execute
227
mov
dx, command
;
command to be executed
228
mov
bx, execblock
;
address of execblock
229
mov
word [bx+2], tail
;
offset of command tail
230
mov
[bx+4], ds
;
segment of command tail
231
int
0x21
;
dos services
232
233
jmp $
; loop infinitely if returned
234
end:
13.4. DEVICE DRIVERS
Device drivers are operating system extensions that become part of the
operating system and extend its services to new devices. Device drivers in
DOS are very simple. They just have their services exposed through the file
system interface.
Device driver file starts with a header containing a link to the next driver in
the first four bytes followed by a device attribute word. The most important
bit in the device attribute word is bit 15 which dictates if it is a character
device or a block device. If the bit is zero the device is a character device and
otherwise a block device. Next word in the header is the offset of a strategy
routine, and then is the offset of the interrupt routine and then in one byte,
the number of units supported is stored. This information is padded with
seven zeroes.
Strategy routine is called whenever the device is needed and it is passed a
request header. Request header stores the unit requested, the command
code, space for return value and buffer pointers etc. Important command
codes include 0 to initialize, 1 to check media, 2 to build a BIOS parameter
block, 4 and 8 for read and write respectively. For every command the first
13 bytes of request header are same.
RH+0
BYTE
Length of request header
RH+1
BYTE
Unit requested
RH+2
BYTE
Command code
RH+3
BYTE
Driver's return code
RH+5
9 BYTES Reserved
The request header details for different commands is listed below.
0 ­ Driver Initialization
Passed to driver
RH+18
DWORD
Pointer to character after equal sign on CONFIG.SYS line
that loaded driver (read-only)
158
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
RH+22
BYTE
Drive number for first unit of this block driver
(0=A...)
Return from driver
RH+13
BYTE
Number of units (block devices only)
RH+14
DWORD
Address of first free memory above driver (break
address)
RH+18
DWORD
BPB pointer array (block devices only)
1 ­ Media Check
RH+13
BYTE
Media descriptor byte
Return
RH+14
BYTE
Media change code
-1 if disk changed
0 if dont know whether disk changed
1 if disk not changed
RH+15
DWORD
pointer to previous volume label if device attrib bit
11=1 (open/close/removable media supported)
2 ­ Build BPB
RH+13
BYTE
Media descriptor byte
RH+14
DWORD
buffer address (one sector)
Return
RH+18
DWORD
pointer to new BPB
if bit 13 (ibm format) is set buffer is first sector of fat, otherwise
scrach space
4 ­ Read / 8 ­ Write / 9 ­ Write with verify
RH+13
BYTE
Media descriptor byte
RH+14
DWORD
transfer address
RH+18
WORD
byte or sector count
RH+20
WORD
starting sector number (for block devices)
Return
RH+18
WORD
actual byte or sectors transferred
RH+22
DWORD
pointer to volume label if error 0Fh is returned
The BIOS parameter block discussed above is a structure that provides
parameters about the storage medium. It is stored in the first sector or the
boot sector of the device. Its contents are listed below.
00-01
bytes per sector
02
sectors per allocation unit
03-04
Number of reserved sectors ( 0 based)
05
number of file allocation tables
06-07
max number of root directory entries
08-09
total number of sectors in medium
0A
media descriptor byte
0B-0C
number of sectors occupied by a single FAT
0D-0E
sectors per track (3.0 or later)
0F-10
number of heads (3.0 or later)
11-12
number of hidden sectors (3.0 or later)
13-14
high-order word of number of hidden sectors (4.0)
15-18
IF bytes 8-9 are zero, total number of sectors in medium
19-1E
Reserved should be zero
We will be building an example device driver that takes some RAM and
expresses it as a secondary storage device to the operating system. Therefore
a new drive is added and that can be browsed to, filed copied to and from
just like ordinary drives expect that this drive is very fast as it is located in
the RAM. This program cannot be directly executed since it is not a user
program. This must be loaded by adding the line "device=filename.sys" in the
"config.sys" file in the root directory.
159
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
Example 13.5
001
; ram disk dos block device driver
002
header:
dd
-1
;
no next driver
003
dw
0x2000
;
driver attributes: block device
004
dw
strategy
;
offset of strategy routine
005
dw
interrupt
;
offset of interrupt routine
006
db
1
;
no of units supported
007
times 7 db 0
;
reserved
008
009
request:
dd
0
; space for request header
010
011
ramdisk:
times 11 db 0
;
initial part of boot sector
012
bpb:
dw
512
;
bytes per sector
013
db
1
;
sectors per cluster
014
dw
1
;
reserved sectors
015
db
1
;
fat copies
016
dw
48
;
root dir entries
017
dw
105
;
total sectors
018
db
0xf8
;
media desc byte: fixed disk
019
dw
1
;
sectors per fat
020
times 482 db 0
;
remaining part of boot sector
021
db
0xfe, 0xff, 0xff
;
special bytes at start of FAT
022
times 509 db 0
;
remaining FAT entries unused
023
times 103*512 db 0
;
103 sectors for data
024
bpbptr:
dw
bpb
;
array of bpb pointers
025
026
dispatch:
dw
init
;
command
0:
init
027
dw
mediacheck
;
command
1:
media check
028
dw
getbpb
;
command
2:
get bpb
029
dw
unknown
;
command
3:
not handled
030
dw
input
;
command
4:
input
031
dw
unknown
;
command
5:
not handled
032
dw
unknown
;
command
6:
not handled
033
dw
unknown
;
command
7:
not handled
034
dw
output
;
command
8:
output
035
dw
output
;
command
9:
output with verify
036
037
; device driver strategy routine
038
strategy:
mov  [cs:request], bx
; save request header offset
039
mov  [cs:request+2], es
; save request header segment
040
retf
041
042
; device driver interrupt routine
043
interrupt:  push ax
044
push bx
045
push cx
046
push dx
047
push si
048
push di
049
push ds
050
push es
051
052
push cs
053
pop  ds
054
055
les
di, [request]
056
mov
word [es:di+3], 0x0100
057
mov
bl, [es:di+2]
058
mov
bh, 0
059
cmp
bx, 9
060
ja
skip
061
shl
bx, 1
062
063
call [dispatch+bx]
064
065
skip:
pop
es
066
pop
ds
067
pop
di
068
pop
si
069
pop
dx
070
pop
cx
071
pop
bx
072
pop
ax
073
retf
074
160
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
075
mediacheck: mov
byte [es:di+14], 1
076
ret
077
078
getbpb:
mov
word [es:di+18], bpb
079
mov
[es:di+20], ds
080
ret
081
082
input:
mov
ax, 512
083
mul
word [es:di+18]
084
mov
cx, ax
085
086
mov
ax, 512
087
mul
word [es:di+20]
088
mov
si, ax
089
add
si, ramdisk
090
091
les
di, [es:di+14]
092
cld
093
rep
movsb
094
ret
095
096
output:
mov
ax, 512
097
mul
word [es:di+18]
098
mov
cx, ax
099
100
lds
si, [es:di+14]
101
mov
ax, 512
102
mul
word [es:di+20]
103
mov
di, ax
104
add
di, ramdisk
105
106
push cs
107
pop  es
108
cld
109
rep  movsb
110
unknown:
ret
111
112
init:
mov
ah, 9
113
mov
dx, message
114
int
0x21
115
116
mov
byte [es:di+13], 1
117
mov
word [es:di+14], init
118
mov
[es:di+16], ds
119
mov
word [es:di+18], bpbptr
120
mov
[es:di+20], ds
121
ret
122
123
message:
db
13, 10, 'RAM Disk Driver loaded',13,10,'$'
161