0

I want to write a program in assembly language to read primary partitions of a hard disk. I Googled a lot last several days and I found that maybe int 13h (ah = 42h) is for me. But I failed at the beginning. After INT 13H was called, CF was set to 1 and AH was 1. From the docs I know the interrupt was failed.

Here is my code:

ASSUME CS:CodeSeg, DS:DataSeg, SS:StackSeg

DataSeg SEGMENT

BSBuffer:             ; Abbr for Boot Sector Buffer.
MBRecord:             ; Master Boot Record.
    MBR DB 446 DUP (0)

PartitionA:
    StatusA      DB 0 ;
    BeginHeadA   DB 0 ;
    BeginSeclynA DW 0 ;
    FileSystemA  DB 0 ;
    FinalHeadA   DB 0 ;
    FinalSeclynA DW 0 ;
    BeginSectorA DD 0 ;
    SectorCountA DD 0 ;

PartitionB:
    StatusB      DB 0 ;
    BeginHeadB   DB 0 ;
    BeginSeclynB DW 0 ;
    FileSystemB  DB 0 ;
    FinalHeadB   DB 0 ;
    FinalSeclynB DW 0 ;
    BeginSectorB DD 0 ;
    SectorCountB DD 0 ;

PartitionC:
    StatusC      DB 0 ;
    BeginHeadC   DB 0 ;
    BeginSeclynC DW 0 ;
    FileSystemC  DB 0 ;
    FinalHeadC   DB 0 ;
    FinalSeclynC DW 0 ;
    BeginSectorC DD 0 ;
    SectorCountC DD 0 ;

PartitionD:
    StatusD      DB 0 ;
    BeginHeadD   DB 0 ;
    BeginSeclynD DW 0 ;
    FileSystemD  DB 0 ;
    FinalHeadD   DB 0 ;
    FinalSeclynD DW 0 ;
    BeginSectorD DD 0 ;
    SectorCountD DD 0 ;

Validation:
    VALID DW 0 ; Should be 55AAH.

; DAPacket is used as the input parameter of ReadBootSector PROC

DAPacket:                ; Abbr for Disk Address Packet.
    PacketSize    DB 16  ; Always 16.
    Reserved      DB 0   ; Reserved.
    SectorCount   DW 1   ; Should be 1 to read boot sector.
    BufferOffset  DW 0
    BufferSegment DW 0
    BlockNumber DB 8 DUP (0)

DataSeg ENDS

StackSeg SEGMENT
    DB 4096 DUP (0)
StackSeg ENDS

CodeSeg SEGMENT
START:

    MOV AX, DataSeg
    MOV DS, AX
    MOV AX, StackSeg
    MOV SS, AX
    MOV SP, 4096

    MOV DL, 80H
    CALL ReadDisk

    MOV CX, VALID

    MOV AX, 4C00H
    INT 21H

; This process is used to read the boot sector of a given disk.
; Input:
;     DL - Disk ID, 0~79H for floppies, 80H~FFH for hds.
; Output:
;     BSBuffer - Boot sector of the disk indicated by DL.

ReadDisk:

    PUSH AX
    PUSH SI
    MOV SI, DAPacket
    MOV PacketSize, 16
    MOV SectorCount, 1
    MOV BufferOffset, BSBuffer
    MOV BufferSegment, DataSeg

    MOV AH, 42H

    INT 13H

    POP SI
    POP AX

    RET

CodeSeg ENDS
END START

Thanks!

Chris Gerken
  • 16,221
  • 6
  • 44
  • 59
Liu Yue
  • 382
  • 5
  • 6
  • 3
    Did you run this code under pure DOS? Because it will not run under Windows – Gunther Piez Jun 06 '11 at 17:47
  • I didn't run that code under pure DOS. I've run that code in a Win XP. Is there any other way to read the first sector of a disk under Windows? – Liu Yue Jun 07 '11 at 02:19

2 Answers2

1

You used two functions who're not part of the same API.

int 13h - ah:42h => This is a BIOS function (IBM/MS Read disk extention)

int 21h - ah:4Ch => This is a DOS function (end of process method)

This program can't run anywhere !

Edit : That's false. You're right @ninjalj, I didn't know. It's work on DOS. My bad. Thanks for the correction.

If you code for WinXP, use assembly have realy poor interest. Use C and inline assembly if you want for critical sections. Sadly I don't know how to read on the physical drive using Win32API, but I've already seen it somwhere, so I'm guesing it's possible...

AxFab
  • 1,157
  • 8
  • 11
  • 1
    DOS programs can (and often do) use BIOS services. The BIOS was just the machine-dependant part of DOS (of CP/M really). – ninjalj Jul 13 '11 at 20:31
1

A sector is 512 (0x200) bytes and if you want to write it to de datasegment you have to make a block of at least 512 bytes long. Otherwise you will overwrite the CODE/DATA you try to execute.

Holus
  • 11
  • 1