汇编中断问题:int 13h (ah = 42h) 失败返回 cf = 1, ah = 1
我想用汇编语言编写一个程序来读取硬盘的主分区。过去几天我用谷歌搜索了很多,我发现也许 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
谢谢!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您使用了两个不属于同一 API 的函数。
int 13h - 啊:42h =>这是 BIOS 函数(IBM/MS 读取磁盘扩展)
int 21h - ah:4Ch =>这是一个 DOS 功能(进程结束方法)
该程序无法在任何地方运行!
编辑:这是错误的。你是对的@ninjalj,我不知道。它可以在 DOS 下运行。我的不好。感谢您的指正。
如果您为 WinXP 编写代码,那么对使用汇编的兴趣真的很差。如果需要关键部分,请使用 C 和内联汇编。
遗憾的是,我不知道如何使用 Win32API 在物理驱动器上读取数据,但我已经在某处看到过它,所以我猜这是可能的......
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...
一个扇区为 512 (0x200) 字节,如果要将其写入数据段,则必须创建一个至少 512 字节长的块。否则您将覆盖您尝试执行的代码/数据。
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.