使用汇编语言的32位系统调用进行硬盘处理

时间:2015-11-17 07:02:11

标签: windows assembly x86 dos masm

朋友们,我需要有关使用32位系统调用的硬盘处理方面的帮助。我是汇编语言的新手,我正在使用MASM汇编程序。我已经尝试了一些示例代码,但它们处于16位模式,并且我在编译时也给出了错误。我想用32位写。我还在一本书中读到32位很复杂,是否还有另一个32位系统调用程序。

示例代码!

; This program calls INT 21h Function 7303h, to get free space information
; on a FAT-type drive volume. It displays both the volume size and free space.
; Runs under Windows 95/98/Me, but not under Windows NT/2000/XP.
; Last update: 12/11/01

INCLUDE Irvine16.inc

.data

buffer ExtGetDskFreSpcStruc <>
driveName BYTE "C:\",0
str1 BYTE "Volume size (KB): ",0
str2 BYTE "Free space (KB):  ",0
str3 BYTE "Function call failed.",0dh,0ah,0

.code
main PROC
    mov ax,@data
    mov ds,ax
    mov es,ax

    mov  buffer.Level,0     ; must be zero
    mov  di, OFFSET buffer      ; ES:DI points to buffer
    mov  cx, SIZEOF buffer      ; buffer size
    mov  dx, OFFSET DriveName   ; ptr to drive name
    mov  ax, 7303h          ; Get disk free space
    int  21h
    jc   error          ; Failed if CF = 1

    mov  dx,OFFSET str1     ; volume size
    call WriteString
    call CalcVolumeSize
    call WriteDec
    call Crlf

    mov  dx,OFFSET str2     ; free space
    call WriteString
    call CalcVolumeFree
    call WriteDec
    call Crlf
    jmp  quit
error:
    mov  dx,OFFSET str3
    call WriteString
quit:
    exit
main ENDP

;-------------------------------------------------------------------
CalcVolumeSize PROC
; Calculate and return the disk volume size, in kilobytes.
; Receives: buffer variable, a ExtGetDskFreSpcStruc structure
; Returns:  EAX = volume size
; Remarks:  (SectorsPerCluster * 512 * TotalClusters) / 1024
;--------------------------------------------------------------------
    mov eax,buffer.SectorsPerCluster
    shl eax,9           ; mult by 512
    mul buffer.TotalClusters
    mov ebx,1024
    div ebx             ; return kilobytes
    ret
CalcVolumeSize ENDP


;-------------------------------------------------------------------
CalcVolumeFree PROC
; Calculate and return the number of available kilobytes on the
;           given volume.
; Receives: buffer variable, a ExtGetDskFreSpcStruc structure
; Returns:  EAX = available space, in kilobytes
; Remarks:  (SectorsPerCluster * 512 * AvailableClusters) / 1024
;--------------------------------------------------------------------
    mov eax,buffer.SectorsPerCluster
    shl eax,9           ; mult by 512
    mul buffer.AvailableClusters
    mov ebx,1024
    div ebx             ; return kilobytes
    ret
CalcVolumeFree ENDP

END main 

1 个答案:

答案 0 :(得分:3)

尝试组装此程序......

  

我也给了我错误

首先,它无法组装,因为行

中的结构ExtGetDskFreSpcStruc
buffer ExtGetDskFreSpcStruc <>

之前没有定义 - 不在此文件中,也不在(唯一的)包含文件中,在这种情况下&#34; Irvine16.inc&#34;,它不包含定义。因此,所有尝试访问&#34; buffer.xxx&#34;会抛出错误。

其次,如果您尝试将此程序组装为32位,则需要在32位汇编文件中包含16位包含文件。您应该使用32位版本&#34; Irvine32.inc&#34;,因为否则子例程中的所有间接寻址(如mov al, [si](16位)都将失败。

第三,你正在调用DOS-legacy-interrupts,它们仅在Win95 / 98 / Me中可用,因为它们的内核基于DOS。 Win2000及更高版本中较新的NT内核不提供它们,因为它是一个不同的OS体系结构/代码库,没有/减少遗留代码。 DOS中断(21h)是16位,因为DOS是16位。我不知道在Win95 / 98 / Me中是否实现了32位版本的旧DOS中断。快速搜索没有表明这已经实现。在&#34; Irvine16.inc&#34;中使用的BIOS中断肯定是16位,因此在32位可执行文件中无法使用(没有非常复杂的变通方法)可能导致程序崩溃。

  

是否还有其他32位系统调用程序[?]

是。使用Win32-API,Win95中可用,直到Win8 / 10(?)。 最简单的方法是使用Hutch在MOVSD.COM找到的MASM-package,然后从中包含kernel32.inc/lib。然后,您可以调用GetFreeDiskSpace function以获得所需的结果,其行类似于:

invoke GetFreeDiskSpace, 
  offset driveName, 
  offset buffer.lpSectorsPerCluster,       ; adjust to actual buffer layout names
  offset buffer.lpBytesPerSector,          ; "
  offset buffer.lpNumberOfFreeClusters,    ; "
  offset buffer.lpTotalNumberOfClusters    ; "