【问题标题】:Assembly interrupt problem: int 13h (ah = 42h) failed returning cf = 1, ah = 1汇编中断问题:int 13h (ah = 42h) 失败返回 cf = 1, ah = 1
【发布时间】:2011-09-09 10:57:16
【问题描述】:

我想用汇编语言编写一个程序来读取硬盘的主分区。过去几天我在 Google 上搜索了很多,我发现 int 13h (ah = 42h) 可能适合我。但一开始我失败了。调用 INT 13H 后,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

谢谢!

【问题讨论】:

  • 你是在纯DOS下运行这段代码的吗?因为它不会在Windows下运行
  • 我没有在纯 DOS 下运行该代码。我已经在 Win XP 中运行了该代码。 Windows下有没有其他方法可以读取磁盘的第一个扇区?

标签: assembly interrupt disk disk-partitioning


【解决方案1】:

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

int 13h - ah:42h => 这是一个 BIOS 功能(IBM/MS 读取磁盘扩展)

int 21h - ah:4Ch => 这是一个 DOS 函数(进程结束方法)

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

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

如果你为 WinXP 编码,使用汇编的兴趣真的很差。如果您需要关键部分,请使用 C 和内联汇编。 遗憾的是,我不知道如何使用 Win32API 在物理驱动器上进行读取,但我已经在某个地方看到过,所以我猜这是可能的......

【讨论】:

  • DOS 程序可以(并且经常)使用 BIOS 服务。 BIOS 只是 DOS(实际上是 CP/M)的机器相关部分。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-09-16
    • 2014-09-23
    • 2015-07-16
    • 2017-07-12
    • 2012-02-17
    • 2012-01-31
    • 2010-12-31
    • 1970-01-01
    • 2022-11-18
    相关资源
    最近更新 更多