📄 file.asm
字号:
.MODEL small, pascal, os_dos
INCLUDE demo.inc
.CODE
;* ReadCharAttr - Reads character and display attribute at cursor location.
;*
;* Shows: BIOS Interrupt - 10h, Function 8 (Read Character and Attribute
;* at Cursor)
;*
;* Uses: vconfig - Video configuration structure (initialized
;* by calling the GetVidConfig procedure)
;*
;* Params: Attr - Pointer to short integer for display attribute
;*
;* Return: Short integer with ASCII value of character
ReadCharAttr PROC USES di,
Attr:PWORD
mov ah, 8 ; Function 8
mov bh, vconfig.dpage ; Current page
int 10h ; Read Character and Attribute
sub bh, bh
mov bl, ah ; BX = attribute
cbw ; AX = character
LoadPtr es, di, Attr ; ES:DI = pointer to int
mov es:[di], bx ; Copy attribute
ret
ReadCharAttr ENDP
;* CopyFile - Copies a file from a specified directory to another. Allows
;* two different copy methods. See the OpenFile, CloseFile, ReadFile, and
;* WriteFile procedures for specific examples on opening, closing, reading
;* from, and writing to files.
;*
;* Shows: DOS Functions - 3Ch (Create File)
;* 5Bh (Create New File)
;* Instruction - clc
;*
;* Params: Imode - 0 = Create new target file or overwrite existing file
;* 1 = Abort and return error code if target file already
;* exists (for DOS versions 3.0 and higher only)
;* Fspec1 - Pointer to ASCIIZ source file specification
;* Fspec2 - Pointer to ASCIIZ target file specification
;*
;* Return: Short integer with error code
;* 0 if successful
;* 1 if error
.DATA
Buffer BYTE BUFFERSIZE DUP (?) ; Buffer for diskette read
.CODE
CopyFile PROC USES ds si di,
Imode:WORD,
Fspec1:PBYTE,
Fspec2:PBYTE
LOCAL eof_flag:BYTE
; Open source file for read only
LoadPtr ds, dx, Fspec1 ; Point DS:DX to source file
mov ax, 3D00h ; AH = function #, AL = access code
int 21h ; Open file (for read only)
jc exit
mov si, ax ; SI = file handle for source
; Open target file according to copy mode
LoadPtr ds, dx, Fspec2 ; Point DS:DX to target file
.IF Imode != 1 ; If Imode (DOS Function) is not 1
mov ah, 3Ch ; Request Create File
.ELSE
; Check DOS version
INVOKE GetVer
cmp ax, 300 ; 3.0 or higher?
jb close ; No? Abort with error code
mov ah, 5Bh ; Request Create New File
.ENDIF
sub cx, cx ; Normal attribute for target
int 21h ; DOS function for target file
jc close ; If open error, abort
mov di, ax ; DI = file handle for target
; Both files successfully opened. Now read from source and copy to target.
mov ax, @data
mov ds, ax ; DS:DX = buffer. Read/write
mov dx, OFFSET Buffer ; to and from here.
mov eof_flag, 0 ; Initialize end-of-file flag
.REPEAT
mov bx, si ; Handle for source file
mov cx, BUFFERSIZE ; CX = number of bytes to read
mov ah, 3Fh ; Request DOS read
int 21h ; Read from file
jc close ; If error, exit
.IF ax != cx ; If all bytes not read,
inc eof_flag ; raise end-of-file flag
.ENDIF ; to end .REPEAT loop
mov bx, di ; Handle for target file
mov cx, ax ; Write number of bytes read
mov ah, 40h ; Request DOS write
int 21h ; Write from buffer to target file
jc close ; If error, exit
.UNTIL eof_flag != 0 ; Loop to read next block
clc ; Clear CY to indicate success
close:
pushf ; Preserve flags while closing
INVOKE CloseFile, ; Close source file
si ; Handle for source
INVOKE CloseFile, ; Close target file
di ; Handle for target
sub ax, ax ; Error code = 0
popf ; Recover flags
exit:
.IF carry? ; If carry set,
mov ax, 1 ; error code = 1
.ENDIF
ret
CopyFile ENDP
;* ChangeDrive - Changes default drive.
;*
;* Shows: DOS Function - 0Eh (Select Disk)
;*
;* Params: Drive - Uppercase letter designation for new drive
;*
;* Return: None
ChangeDrive PROC,
Drive:WORD
mov ah, 0Eh ; DOS Function 0Eh
mov dx, Drive ; Drive designation in DL,
sub dl, 'A' ; 0=A, 1=B, 2=C, etc.
int 21h ; Select Disk
ret
ChangeDrive ENDP
;* GetCurDrive - Gets designation of current drive.
;*
;* Shows: DOS Function - 19h (Get Current Disk)
;* Instruction - cbw
;*
;* Params: None
;*
;* Return: Short integer with drive designation
;* 0 = A, 1 = B, 2 = C, etc.
GetCurDrive PROC
mov ah, 19h ; DOS Function 19h
int 21h ; Get Current Disk
cbw ; AX = drive designation
ret
GetCurDrive ENDP
;* SetDTA - Sets address for new Disk Transfer Area.
;*
;* Shows: DOS Function - 1Ah (Set DTA Address)
;*
;* Params: Dta - Far pointer to new transfer address
;*
;* Return: None
SetDTA PROC USES ds,
Dta:FPBYTE
lds dx, [Dta] ; Point DS:DX to DTA
mov ah, 1Ah ; DOS Function 1Ah
int 21h ; Set DTA Address
ret
SetDTA ENDP
;* GetDTA - Gets address of current Disk Transfer Area.
;*
;* Shows: DOS Function - 2Fh (Get DTA Address)
;*
;* Params: Dta - Far pointer to receive transfer address
;*
;* Return: None
GetDTA PROC,
Dta:FPBYTE
mov ah, 2Fh ; DOS Function 2Fh
int 21h ; Get DTA Address in ES:BX
mov ax, es ; Save DTA segment
mov dx, bx ; Save DTA offset
les bx, Dta ; Now ES:BX points to variable
mov es:[bx], dx ; Copy DTA address to
mov es:[bx+2], ax ; dta variable
ret
GetDTA ENDP
;* CreateFile - Creates file with specified attribute.
;*
;* Shows: DOS Function - 3Ch (Create File)
;*
;* Params: Attr - Attribute code: 0 = normal 8 = volume label
;* 1 = read only 16 = subdirectory
;* 2 = hidden 32 = archive
;* 4 = system
;* Fspec - Pointer to ASCIIZ file specification
;*
;* Return: Short integer with file handle or -1 for error
CreateFile PROC USES ds,
Attr:WORD, Fspec:PBYTE
LoadPtr ds, dx, Fspec ; Point DS:DX to file spec
mov cx, Attr ; CX = attribute
mov ah, 3Ch ; AH = function number
int 21h ; Create file
.IF carry?
mov ax, -1 ; Set error code
.ENDIF
ret
CreateFile ENDP
;* OpenFile - Opens specified file for reading or writing. See the CopyFile
;* procedure for another example of using DOS Function 3Dh to open files.
;*
;* Shows: DOS Function - 3Dh (Open File)
;*
;* Params: Access - Access code: 0 = read 1 = write 2 = read/write
;* Fspec - Pointer to ASCIIZ file specification
;*
;* Return: Short integer with file handle or -1 for error
OpenFile PROC USES ds,
Access:WORD, Fspec:PBYTE
LoadPtr ds, dx, Fspec ; Point DS:DX to file spec
mov ax, Access ; AL = access code
mov ah, 3Dh ; AH = function number
int 21h ; Open file
.IF carry?
mov ax, -1 ; Set error code
.ENDIF
ret
OpenFile ENDP
;* CloseFile - Closes an open file specified by handle. See the CopyFile
;* procedure for another example of using DOS Function 3Eh to close files.
;*
;* Shows: DOS Function - 3EH (Close File)
;*
;* Params: Handle - File handle
;*
;* Return: None
CloseFile PROC,
Handle:WORD
mov bx, Handle ; BX = file handle
mov ah, 3Eh ; DOS Function 3Eh
int 21h ; Close file
ret
CloseFile ENDP
;* ReadFile - Read from open file to specified buffer. See the CopyFile
;* procedure for another example of using DOS Function 3Fh to read files.
;*
;* Shows: DOS Function - 3Fh (Read File or Device)
;*
;* Params: Handle - File handle
;* Len - Number of bytes to read
;* Pbuff - Pointer to buffer
;*
;* Return: Short integer with number of bytes read, or 0 if read error
ReadFile PROC USES ds di,
Handle:WORD, Len:WORD, Pbuff:PBYTE
LoadPtr ds, dx, Pbuff ; Point DS:DX to buffer
mov di, dx ; Keep string offset in DI
mov bx, Handle ; BX = handle
mov cx, Len ; CX = number of bytes to read
mov ah, 3Fh ; Request DOS read
int 21h ; Read File
.IF carry?
sub ax, ax ; Set error code
.ENDIF
ret
ReadFile ENDP
;* WriteFile - Write ASCIIZ string to file. If Handle = 0, the string is
;* written to STDOUT (console). See the CopyFile procedure for another
;* example of using DOS Function 40h to write to files.
;*
;* Shows: DOS Function - 40h (Write File or Device)
;* Instructions - inc dec
;*
;* Params: Handle - File handle
;* SPtr - Pointer to ASCIIZ string
;*
;* Return: Short integer with error code
;* 0 if successful
;* 1 if write error
;* 2 if number of bytes written not equal to string length
WriteFile PROC USES ds di,
Handle:WORD, Sptr:PBYTE
LoadPtr es, di, Sptr ; Point ES:DI to string
push di ; Hold on to string pointer
mov cx, -1 ; Set CX to maximum
sub al, al ; AL = 0
repne scasb ; Scan string for NULL
pop dx ; Recover string pointer
dec di
sub di, dx ; Get string length (w/o NULL)
mov cx, di ; Put it into CX
mov bx, Handle ; Load BX with handle
push es ; Set DS to ES to ensure
pop ds ; DS:DX points to string
mov ah, 40h ; Request DOS write
int 21h ; Write File or Device
mov bx, ax ; Get number of bytes written
mov ax, 0 ; Set error code, preserve carry
.IF carry? ; If carry,
inc ax ; increment once for write error
.ENDIF ; carry
.IF bx != cx ; If bytes not all written,
inc ax ; increment twice
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -