Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:983回复:2

谁能帮我解答这个问题?

楼主#
更多 发布于:2001-12-27 16:04
关于硬盘读写原理的疑惑

远在DOS年代,执行磁盘的读写操作归根结底都是通过如下的方式
mov ah,2(read)/3(write)
mov al,要写的扇区数
mov cx,起始扇区
mov dx,80(硬盘)/0(floppy)
int 13

当硬盘的空间一度增大到超过8.4G时,传统的BIOS int 13h已经不能访问到大于8.4的空间了。于是乎 Extention BIOS应运而出,新的扩展int 13h不再通过寄存器传参数而代之以一个参数包,包的大小可以大至10h字节不等,并以DS:SI的值指向这个包。于是就成了
mov ds,seg Package
mov si,offset package
mov ax,4200h(read)/4300h(write)
int 13h

这样就解决了8.4G以上的硬盘不能识别的问题。但到此为至,所有的对硬盘的操作还是16位的。
到了windows win32时代,对硬盘的读写也变成了32位的,这样的传统的读/写盘中断int 13h又不能适应,于是又推出了win32环境下的32位的读/写盘方法。这就是为什么DOS下的关于拦截磁盘读写操作的TSR不能在win32 下工作的原因。当然你可以禁止(通过某些设置)这项功能而继续沿用老的16位磁盘操作。

但本人对32位环境下读/写磁盘的物理根本原理还没完全弄明白,首先:Windows对硬盘的读/写还是是通过调用BIOS的Int13h?还是有专门自己的服务函数?

知道的朋友还请不要保留,以解小弟之迷惑,谢谢!!!





Tom_lyd
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2001-12-30 21:14
看你是在什么系统下使用。
如果是9x,Me,你应该使用Win32.vxd service.

BOOL
VOpenFile(
/*OUT*/ HANDLE *phFile,
/*IN */ const char * szFileName,
/*IN */ BOOL bWriteMode   //added by zdhe
)
{
ULONG ulMode;

ulMode = bWriteMode ? 0x2022 : 0x2020;
*phFile = NULL;

_asm mov     esi, szFileName
_asm mov     edi, esi
_asm xor     ecx, ecx
_asm mov     ebx, ulMode
_asm mov     edx, 0x1
_asm mov     ax, 0x716c
_asm push    0x21
VMMcall( Exec_VxD_Int )
_asm jb      error_return
_asm mov     ebx, phFile
_asm mov     [ebx], eax

return TRUE;
error_return:
return FALSE;
}

BOOL
VReadFile(
/*IN */ HANDLE hFile,
/*OUT*/ void * pBuffer,
/*IN */ USHORT wReadBytes,
/*IN */ ULONG dwOffset
)
{
_asm mov     ebx, hFile
_asm lea     eax, dwOffset
_asm mov     dx, [eax]
_asm mov     cx, [eax+0x2]
_asm mov     ax, 0x4200
_asm push    0x21
VMMcall( Exec_VxD_Int )
_asm jb      error_return_move

_asm mov     ebx, hFile
_asm xor     ecx, ecx
_asm mov     cx, wReadBytes
_asm mov     edx, pBuffer
_asm mov     ax, 0x3f00
_asm push    0x21
VMMcall( Exec_VxD_Int )
_asm jb      error_return_read
_asm cmp     ax, wReadBytes //ax != wReadBytes
_asm jnz     error_return_read

return TRUE;
error_return_move:
DPRTINF(\"vreadfile move error\\n\");
return FALSE;
error_return_read:
DPRTINF(\"vreadfile read error\\n\");
return FALSE;
}

void
VCloseFile(
/*IN */ HANDLE hFile
)
{
_asm mov     ebx, hFile
_asm mov     ax, 0x3e00
_asm push    0x21
VMMcall( Exec_VxD_Int )
}

BOOL
VCreateFile(
/*OUT*/ HANDLE * phFile,
/*IN */ const char * szFileName
)
{
*phFile = NULL;

_asm mov     edx, szFileName
_asm mov     ecx, 0
_asm mov     ax, 0x3c00
_asm push    0x21
VMMcall( Exec_VxD_Int )
_asm jb      error_return
_asm mov     ebx, phFile
_asm mov     [ebx], eax

return TRUE;
error_return:
return FALSE;
}

BOOL
VWriteFile(
/*IN */ HANDLE hFile,
/*OUT*/ void *pBuffer,
/*IN */ USHORT wWriteBytes,
/*IN */ ULONG dwOffset
)
{
HANDLE *phFile;
phFile = &hFile;

if (dwOffset == -1 )  //append mode
{
_asm mov     ebx, phFile
_asm mov     ebx, [ebx]
_asm mov dx, 0
_asm mov     cx, 0
_asm mov     ax, 0x4202
_asm push    0x21
VMMcall( Exec_VxD_Int )
_asm jb      error_return_move

}else   //write to abs position
{
_asm mov     ebx, phFile
_asm mov     ebx, [ebx]
_asm lea     eax, dwOffset
_asm mov     dx, [eax]
_asm mov     cx, [eax+0x2]
_asm mov     ax, 0x4200
_asm push    0x21
VMMcall( Exec_VxD_Int )
_asm jb      error_return_move
}

_asm mov     ebx, phFile
_asm mov     ebx, [ebx]
_asm xor     ecx, ecx
_asm mov     cx, wWriteBytes
_asm mov     edx, pBuffer
_asm mov     ax, 0x4000
_asm push    0x21
VMMcall( Exec_VxD_Int )
_asm jb      error_return_write
_asm cmp     ax, wWriteBytes //ax != wWriteBytes
_asm jnz     error_return_write

return TRUE;
error_return_move:
DPRTINF(\"******************************Move Faild \\n\");
return FALSE;

error_return_write:
DPRTINF(\"******************************Write Faild \\n\");
return FALSE;
}


如果是WINNT/2000/XP,因该使用
InitializeObjectAttributes
ZwCreateFile来进行文件输入输出访问。

Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2001-12-31 09:17
    非常感谢你抽空回答我的问题,让我得到了很大的启发,再一次感谢你,我的Email是 lydmusic@163.net,希望我们以后可以成为朋友!:)
    你的回答让我得知,Win9x/Me下,磁盘的读/写是通过调用VxD Service来执行一个软件中断(Int21h),然后DOS中断Int21h的磁盘读/写服务实际上是BIOS Int13h的一个封装(DOS文件IO.sys封装了这些服务,并且MSDOS.sys IO.sys在2000下也存在),因此在DOS下,所有的通过调用Int21h的磁盘读/写操作最终都会调用Int13h。
    所以我的一个悬而未决的疑问是在Win9x/Me,或者2000下,还有其它的操作系统(UNIX/Linux)等,它们的磁盘读/写的最终本质上会不会和DOS一样是通过调用BIOS Int13h来实现的 ?
Tom_lyd
游客

返回顶部