![]() ![]() |
|
PC技术指导:汇编源码free | |
作者:佚名 文章来源:不详 点击数 更新时间:2007/12/5 10:44:57 文章录入:杜斌 责任编辑:杜斌 | |
|
|
page 0,132 title 'free --- report free space on disk' ; free --- a utility to report free space on ; the default or selected disk drive. ; ; requires pc-dos or ms-dos.0. ; ; used in the form: ; a> free [unit:] ; (item in square brackets is optional) ; ; version 1.0 july, 1984 ; copyright (c) 1984 by ray duncan ; may be freely reproduced for non-commercial use. cr equ 0dh ;ascii carriage return lf equ 0ah ;ascii line feed blank equ0h ;ascii space code eom equ '$' ;end of string marker ; here we define a dummy segment containing labels ; for the default file control block and the command tail buffer, ; so that the main program can access those locations. ; psp segment para public 'psp' org 05ch fcb label byte ;default file control block org 080h command label byte ;default command buffer psp ends cseg segment para public 'code' assume cs:cseg,ds:psp,es:data,ss:stack get_drive proc near ;get drive selection, if any, ;otherwise obtain the identity ;of the current disk drive. ;return drive (1=a,=b, etc) in al. ; mov al,fcb ;pick up the drive code, parsed ;by dos into the default file ;control block. or al,al ;is it the default? jnz get_drive1 ;no, use it mov ah,19h ;yes, get the actual current int1h ;drive from pc-dos. inc al ;increment to match fcb code. get_drive1: ;return drive code in al. ret get_drive endp free proc far ;entry point from pc-dos push ds ;save ds:0000 for final xor ax,ax ;return to pc-dos push ax mov ax,data ;make our data segment mov es,ax ;addressable via es register. mov ah,30h ;check version of pc-dos. int 1h cmp al,2 jae free1 ;proceed, dos.0 or greater. mov dx,offset msg2 ;dos 1.x --- print error message mov ax,es ;and exit. first fix up ds register mov ds,ax ;so error message is addressable. jmp free4 free1: call get_drive ;get drive selection into dl. push es ;copy es to ds for remainder pop ds ;of the program... assume ds:data ;and tell assembler about it. mov dl,al add al,'a'-1 ;form drive letter from drive code, mov outputb,al ;and put it into the output string. mov ah,36h ;now call dos to get free disk space. int1h cmp ax,-1 ;was drive invalid? je free3 ;yes,go print error message ;drive was ok, so now registers are... ;ax=number of sectors per cluster ;bx=available clusters, ;cx=number of bytes per sector, ;dx=total clusters per drive. ;calculate free space: mul cx ;sectors per cluster * bytes per sector ;(we assume this won't overflow into dx) mul bx ;then * available clusters ;dx:ax now contains free space in bytes. ;si = last byte address for converted string. mov si,offset (outputa+9) mov cx,10 ;cx = 10, radix for conversion call bin_to_asc ;convert free space value to ascii, mov dx,offset output jmp free4 ;and print it out. free3: mov dx,offset msg1 ;illegal drive, print error free4: mov ah,9 ;print the string whose address int1h ;is in dx. ret ;then return to dos. free endp ; convert2 bit binary value to ascii string. ; ; call with dx:ax = signed2 bit value ; cx = radix ; si = last byte of area to store resulting string ; (make sure enough room is available to store ; the string in the radix you have selected.) ; ; destroys ax, bx, cx, dx, and si. ; bin_to_asc proc near ;convert dx:ax to ascii. ;force storage of at least 1 digit. mov byte ptr [si],'0' or dx,dx ;test sign of2 bit value, pushf ;and save sign on stack. jns bin1 ;jump if it was positive. not dx ;it was negative, take's complement not ax ;of the value. add ax,1 adc dx,0 bin1: ;divide the2 bit value by the radix ;to extract the next digit for the ;forming string. mov bx,ax ;is the value zero yet? or bx,dx jz bin3 ;yes, we are done converting. call divide ;no, divide by radix. add bl,'0' ;convert the remainder to an ascii digit. cmp bl,'9' ;we might be converting to hex ascii, jle bin2 ;jump if in range 0-9, add bl,'a'-'9'-1 ;correct it if in range a-f. bin2: mov [si],bl ;store this character into string. dec si ;back up through string, jmp bin1 ;and do it again. bin3: ;restore sign flag, popf ;was original value negative? jns bin4 ;no, jump ;yes,store sign into output string. mov byte ptr [si],'-' bin4: ret ;back to caller. bin_to_asc endp ; general purpose2 bit by 16 bit unsigned divide. ; this must be used instead of the plain machine unsigned divide ; for cases where the quotient may overflow 16 bits (for example, ; dividing 100,000 by). if called with a zero divisor, this ; routine returns the dividend unchanged and gives no warning. ; ; call with dx:ax =2 bit dividend ; cx = divisor ; ; returns dx:ax = quotient ; bx = remainder ; cx = divisor (unchanged) ; divide proc near ; divide dx:ax by cx jcxz div1 ; exit if divide by zero push ax ; 0:dividend_upper/divisor mov ax,dx xor dx,dx div cx mov bx,ax ; bx = quotient1 pop ax ; remainder1:dividend_lower/divisor div cx xchg bx,dx ; dx:ax = quotient1:quotient2 div1: ret ; bx = remainder2 divide endp cseg ends data segment para public 'data' output db cr,lf outputa db 10 dup (blank) db ' bytes free on drive ' outputb db 'x:',cr,lf,eom msg1 db cr,lf db 'that disk drive does not exist.' db cr,lf,eom msg2 db cr,lf db 'requires dos version or greater.' db cr,lf,eom data ends stack segment para stack 'stack' db 4 dup (?) stack ends end free |
|
![]() ![]() |