Amit Singh Tomar
Amit Singh Tomar

Reputation: 8610

Reading boot Sector of the hard disk

I am trying to learn assembly in real mode .I wanted to read the boot sector of the hard disk ,So below is the code

org 100h

start:
xor ax, ax
mov es, ax    ; ES <- 0
mov cx, 1     ; cylinder 0, sector 1
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, buff ; segment offset of the buffer
mov ax, 0201h ; AH = 02 (disk read), AL = 01 (number of sectors to read)
int 13h

jnc .read

 .read:
  mov     ax, cs ; set up segments
  mov     ds, ax
  mov     es, ax
  mov     al, 03h
  mov     ah, 0
  int 10h

 mov     si, buff
 call    print_string

.done:
 jmp     .done


print_string:
lodsb        ; grab a byte from SI

test    al, al  ; logical or AL by itself
jz      .done   ; if the result is zero, get out

mov     ah, 0x0E
int 0x10      ; otherwise, print out the character!
jmp     print_string
.done:
 ret

buff dw 512

My execution environment is DosBox0.70 and exe file is .COM. I am expecting to see 512 bytes on screen but when I run my .COM file its just blank screen there.There are couple of reason that I could see behind it

1)Is given code not returning from Bios interrupt properly(int 13h). 2)String should terminate with null ,which is not happening here.

But not sure is it the above reasons causing it to happen and if so how do I reactify theses issues??

Upvotes: 0

Views: 2674

Answers (2)

Frank Kotler
Frank Kotler

Reputation: 3119

Dos loads a .com file to some segment of it's own choosing, and sets ds and es to that segment. Your buff is in that segment, not segment 0! You're reading the first sector to segment 0, which probably clobbers your IVT. Leave es alone.

After reading one sector, you check for carry flag (indicating an error), but drop into .read whether it's set or not.. If error, you probably want to reset the drive and try the read again. You probably want a "retry counter" around this, so you don't go into an infinite loop.

Your buff does not reserve 512 bytes, but two bytes with a value of 512. Since it's at the end of your file, this probably won't do any harm, but it isn't "right".

Having successfully read a sector, you could print it as ascii characters, but you want to print all 512 bytes, not stop at the first 0 you encounter. A hex dump would probably be more readable.

If the first byte of your MBR is zero, we're in deep muddy water! The first byte of a valid bootsector should be a short jmp followed by a nop, or a near jmp. We're a bit casual about starting a bootsector that way, and most BIOSes don't check, but that's what's "supposed" to be there. What would the CPU execute if it saw 0 as the first byte? (hint: it's an add)

I think your two main problems are setting es to zero, and stopping the print if a zero is encountered. Try it again. FFS, don't try to write anything to your drive until you've got the read working reliably!

Upvotes: 1

johnfound
johnfound

Reputation: 7061

The boot sector of the disk contains not ASCII data, but code. With high probability, one of the first bytes will be NULL and remaining possibly not printable codes (such as CR, LF, etc.).

Trying to print the buffer by INT 10h, which prints ascii codes, and ending on 0 will result probably with nothing displayed at all.

You should convert every byte of the buffer to hexadecimal string and then print these strings to the display. This way you will get simple hex dump of the boot sector.

Upvotes: 3

Related Questions