2011-06-06 106 views
0

我想用汇编语言编写程序来读取硬盘的主分区。我最近几天搜索了很多,我发现可能int 13h(ah = 42h)对我来说。但我一开始就失败了。 INT 13H被调用后,CF被设置为1,AH为1.从文档中我知道中断失败了。程序集中断问题:int 13h(ah = 42h)返回cf = 1失败,ah = 1

这里是我的代码:

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 

谢谢!

+3

您是否在纯DOS下运行此代码?因为它不会在Windows下运行 – hirschhornsalz 2011-06-06 17:47:25

+0

我没有在纯DOS下运行该代码。我已经在Win XP中运行该代码。有没有其他方法可以在Windows下读取磁盘的第一个扇区? – 2011-06-07 02:19:51

回答

1

您使用了两个不属于同一API的函数。

INT 13H - 啊:42H =>这是一个BIOS功能(IBM/MS读取磁盘extention)

INT 21H - 啊:4CH =>这是一个DOS函数(处理方法结束)

这个程序不能运行在任何地方!

编辑:这是错误的。你说得对@ninjalj,我不知道。它在DOS上工作。我的错。感谢您的更正。

如果你为WinXP编写代码,使用程序集真的很不感兴趣。如果您需要关键部分,请使用C和内联汇编。 可悲的是我不知道如何阅读使用Win32API的物理驱动器,但我已经看到它的somwhere,所以我觉得这是可能的...

+0

DOS程序可以(并且经常)使用BIOS服务。 BIOS只是DOS的机器相关部分(真正的CP/M)。 – ninjalj 2011-07-13 20:31:38

1

扇区是512(0x200)字节,如果你想把它写入数据库,你必须创建至少512字节长的块。否则,您将覆盖您尝试执行的代码/数据。