Help w/ Disk Read Code
Hey, I am trying to follow along with an old p norton book on 8088 IBM PC Assembly programming and the book builds a disk viewer and I have written the first half and at this point you should see a dump of the first 16 bytes of sector 0 and instead, nothing happens and the application just hangs there.
I haven't tried to debug the code to see where it hangs because I am hoping someoone here can just look threw the code and tell me why and where it isn't working. The code compiles and links just fine using TASM 5, so it must have something to do with my loops.
Here is the full code:
;--------------------
;Author: 3mu180r, Lead Developer @ Black List Software
;Purpose: Dump first 16 bytes of the 0 sector of floppy disk
;--------------------
.model small
.stack
.data
sector db 16 dup(10h)
db 16 dup(11h)
db 16 dup(12h)
db 16 dup(13h)
db 16 dup(14h)
db 16 dup(15h)
db 16 dup(16h)
db 16 dup(17h)
db 16 dup(18h)
db 16 dup(19h)
db 16 dup(1Ah)
db 16 dup(1Bh)
db 16 dup(1Ch)
db 16 dup(1Dh)
db 16 dup(1Eh)
db 16 dup(1Fh)
.code
read_sector proc near
mov al,0 ;Drive A: = 0
mov cx,1 ;Read only 1 sector
mov dx,0 ;Read sector 0
lea bx,sector ;Where to store sector
int 25h ;Execute sector read
popf ;Ignore flags on stack
xor dx,dx ;set offset to 0 in sector
call show_half ;Dump first half only
call kill_me ;end application
read_sector endp
show_half proc near
push cx
push dx
mov cx,16 ;read only 16 lines
half_sector:
call disp_line
call send_crlf
add dx,16
loop half_sector
pop dx
pop cx
ret
show_half endp
disp_line proc near
push bx
push cx
push dx
mov bx,dx ;for ease of use
mov cx,16 ;dump 16 bytes
push bx ;save the offset for loop
hex_loop:
mov dl,sector[bx] ;get 1 byte
call write_hex ;dump this byte as hex
mov dl,' ' ;put space in between
call write_char
inc bx
loop hex_loop
mov dl,' ' ;add one more space
call write_char
mov cx,16
pop bx ;recall offset
ascii_loop:
mov dl,sector[bx]
call write_char
inc bx
loop ascii_loop
pop dx
pop cx
pop bx
ret
disp_line endp
write_char proc near
push ax
push dx
cmp dl,32 ;check if char is before a space
jae is_printable ;else print as is
mov dl,'.' ;yes, then replace with .
is_printable:
mov ah,2 ;char output = 2
int 21h ;output char in dl
pop dx ;reset def val in ax
pop ax
ret
write_char endp
write_hex proc near
push cx
push dx
mov dh,dl
mov cx,4 ;get upper nibble in dl
shr dl,cl
call write_hex_digit
mov dl,dh
and dl,0fh
call write_hex_digit
pop dx
pop cx
ret
write_hex endp
write_hex_digit proc near
push dx
cmp dl,10
jae hex_letter
add dl,"0"
jmp short write_digit
hex_letter:
add dl,"A"-10 ;make conversion to hex
write_digit:
call write_char
pop dx
ret
write_hex_digit endp
send_crlf proc near
push ax
push dx
mov ah,2
mov dl,13
int 21h
mov dl,10
int 21h
pop dx
pop ax
ret
send_crlf endp
kill_me proc near
mov ax,4Ch
int 21h
kill_me endp
end read_sector
I'd appreciate the help, thanks in advance
[3684 byte] By [
3mu180r] at [2007-11-19 9:33:29]

# 1 Re: Help w/ Disk Read Code
If i understand correctly then u want to display first 16 bytes of sector 0 (from floppy?) and display it in HEX mode? and thats all?
I must tell u that is hard to read from others source, its better to recode it. But answer to my questions and i will see what i can do.
Im also programming for MS-DOS.Its not hard at all to code it.
# 2 Re: Help w/ Disk Read Code
I remember that book. I used it to learn PC programming too (many years ago).
One problem is here:
kill_me proc near
mov ax,4Ch <-- should be mov ax,4C00h
int 21h
kill_me endpAH is the command code (terminate program) and AL is the return code.
Where is your start-up code? An EXE program needs to do some register initialization at the beginning, although I don't remember what exactly since it's been too long.
# 3 Re: Help w/ Disk Read Code
microcode there is no differents what you use. for Turbo Assembler this are the same: 04Ch, 4ch, 4c00h. there is no diffrents what you use.
U see .code statement? Thats the place where program starts. and not all programs needs assume codeseg etc stuff.
microcode, read book and refresh your memory then u will see that im right.
im coding my version so u can compare them later if somebody don't code / fix it before me.
# 4 Re: Help w/ Disk Read Code
microcode there is no differents what you use. for Turbo Assembler this are the same: 04Ch, 4ch, 4c00h. there is no diffrents what you use.I don't agree with that. mov ax,4Ch and mov ax,4C00h are not the same thing. mov ax,4Ch puts 004Ch into ax just like mov cx,1 puts 0001h into cx.
U see .code statement? Thats the place where program starts. and not all programs needs assume codeseg etc stuff.
microcode, read book and refresh your memory then u will see that im right.
im coding my version so u can compare them later if somebody don't code / fix it before me.Well technically it's the end read_sector statement at the end of the file that makes read_sector the entry point of the program. But still, I think the code needs to initialize the DS register. I couldn't find the Peter Norton book, but another book I have says this code is needed at the entry point of an EXE program:
mov ax,@data
mov ds,axThat initializes the ds register to point to the .data segment.
# 5 Re: Help w/ Disk Read Code
@ both:
Thank you both very much.. you were both right. It didn't seem to matter how I was exiting the application and I did need to initilize the DS, in fact I have seen this before and sadly even worked with the DS in the same way before.. so I can vouche for the validity of that statement.. and for the combined answer, the result below:
C:\>C:\TASM\BIN\TEST.EXE
EB 3C 90 4D 53 44 4F 53 35 2E 30 00 02 01 01 00 δ<MSDOS5.0....
02 E0 00 40 0B F0 09 00 12 00 02 00 00 00 00 00 .α.@.≡........
00 00 00 00 00 00 29 46 61 8B BC 4E 4F 20 4E 41 .....)Fa╝NO NA
4D 45 20 20 20 20 46 41 54 31 32 20 20 20 33 C9 ME FAT12 3╔
8E D1 BC F0 7B 8E D9 B8 00 20 8E C0 FC BD 00 7C ╤╝≡{┘╕. └ⁿ╜.|
38 4E 24 7D 24 8B C1 99 E8 3C 01 72 1C 83 EB 3A 8N$}$┴Φ<.r.δ:
66 A1 1C 7C 26 66 3B 07 26 8A 57 FC 75 06 80 CA f.|&f;.&Wⁿu.╩
02 88 56 02 80 C3 10 73 EB 33 C9 8A 46 10 98 F7 .V.├.sδ3╔F.≈
66 16 03 46 1C 13 56 1E 03 46 0E 13 D1 8B 76 11 f..F..V..F..╤v.
60 89 46 FC 89 56 FE B8 20 00 F7 E6 8B 5E 0B 03 `FⁿV■╕ .≈^..
C3 48 F7 F3 01 46 FC 11 4E FE 61 BF 00 00 E8 E6 ├H≈≤.Fⁿ.N■a┐..Φ
00 72 39 26 38 2D 74 17 60 B1 0B BE A1 7D F3 A6 .r9&8-t.`▒.╛}≤
61 74 32 4E 74 09 83 C7 20 3B FB 72 E6 EB DC A0 at2Nt.╟ ;√rδ▄
FB 7D B4 7D 8B F0 AC 98 40 74 0C 48 74 13 B4 0E √}┤}≡@t.Ht.┤.
BB 07 00 CD 10 EB EF A0 FD 7D EB E6 A0 FC 7D EB ╗..═.δ∩}δⁿ}δ
E1 CD 16 CD 19 26 8B 55 1A 52 B0 01 BB 00 00 E8 ═.═.&U.R░.╗..Φ
very nice.. indeed!
and for those interested, the working code:
;--------------------
;Author: 3mu180r, Lead Developer @ Black List Software
;Purpose: Dump first 16 bytes of the 0 sector of floppy disk
;Credits: microcode and BytePtr.. many thanks!!
;--------------------
.model small
.stack
.data
sector db 16 dup(10h)
db 16 dup(11h)
db 16 dup(12h)
db 16 dup(13h)
db 16 dup(14h)
db 16 dup(15h)
db 16 dup(16h)
db 16 dup(17h)
db 16 dup(18h)
db 16 dup(19h)
db 16 dup(1Ah)
db 16 dup(1Bh)
db 16 dup(1Ch)
db 16 dup(1Dh)
db 16 dup(1Eh)
db 16 dup(1Fh)
.code
read_sector proc near
mov ax,@data ;get DS offset
mov ds,ax ;initalize DS
mov al,0 ;Drive A: = 0
mov cx,1 ;Read only 1 sector
mov dx,0 ;Read sector 0
lea bx,sector ;Where to store sector
int 25h ;Execute sector read
popf ;Ignore flags on stack
xor dx,dx ;set offset to 0 in sector
call show_half ;Dump first half only
call kill_me ;end application
read_sector endp
show_half proc near
push cx
push dx
mov cx,16 ;read only 16 lines
half_sector:
call disp_line
call send_crlf
add dx,16
loop half_sector
pop dx
pop cx
ret
show_half endp
disp_line proc near
push bx
push cx
push dx
mov bx,dx ;for ease of use
mov cx,16 ;dump 16 bytes
push bx ;save the offset for loop
hex_loop:
mov dl,sector[bx] ;get 1 byte
call write_hex ;dump this byte as hex
mov dl,' ' ;put space in between
call write_char
inc bx
loop hex_loop
mov dl,' ' ;add one more space
call write_char
mov cx,16
pop bx ;recall offset
ascii_loop:
mov dl,sector[bx]
call write_char
inc bx
loop ascii_loop
pop dx
pop cx
pop bx
ret
disp_line endp
write_char proc near
push ax
push dx
cmp dl,32 ;check if char is before a space
jae is_printable ;else print as is
mov dl,'.' ;yes, then replace with .
is_printable:
mov ah,2 ;char output = 2
int 21h ;output char in dl
pop dx ;reset def val in ax
pop ax
ret
write_char endp
write_hex proc near
push cx
push dx
mov dh,dl
mov cx,4 ;get upper nibble in dl
shr dl,cl
call write_hex_digit
mov dl,dh
and dl,0fh
call write_hex_digit
pop dx
pop cx
ret
write_hex endp
write_hex_digit proc near
push dx
cmp dl,10
jae hex_letter
add dl,"0"
jmp short write_digit
hex_letter:
add dl,"A"-10 ;make conversion to hex
write_digit:
call write_char
pop dx
ret
write_hex_digit endp
send_crlf proc near
push ax
push dx
mov ah,2
mov dl,13
int 21h
mov dl,10
int 21h
pop dx
pop ax
ret
send_crlf endp
kill_me proc near
mov ax,4C00h
int 21h
kill_me endp
end read_sector
Thanks again, best regards!
