Assembly interrupt problem: int 13h (ah = 42h) failed returning cf = 1, ah = 1
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!
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...
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.
精彩评论