中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
作者:
标题: 改變檔案屬性的源碼 上一主题 | 下一主题
Roy
管理员

專業島民



积分 4869
发帖 1633
注册 2002-12-10
状态 离线
『楼 主』:  改變檔案屬性的源碼 使用 LLM 解释/回答一下

; ATTR.ASM -- File Attribute Utility
; ==================================
model tiny
.code

CSEG Segment
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
Org 0080h
Parameter Label Byte ; Parameter is here
Org 0100h
Entry: Jmp Begin ; Entry Point

; Most Data (some more at end of program)
; ---------------------------------------

db "ATTR (C) 1986, Ziff-Davis Publishing Co.",1Ah
db " Programmed by Charles Petzold ",1Ah
SyntaxMsg db "Syntax: ATTR "
db "filename",13,10
db " Archive System Hidden Read-Only$"
DosVersMsg db "ATTR: Needs DOS 2.0 +$"
FlagErrMsg db "ATTR: Incorrect flag$"
FileSpecMsg db "ATTR: Incorrect File Spec$"
Delimiters db 9,' ,;=',13
FlagList db "ASHR", 20h, 04h, 02h, 01h
AllFlagList db " $Arc $Dir $$$$$$Sys $Hid $R-O$"
ChangeFlag db 0
AndAttrBits db 0
OrAttrBits db 0
SearchString dw ?
AppendFileName dw ?

; Check DOS Version
; -----------------

Begin: Mov AH, 30h ; Check for DOS Version
Int 21h ; through DOS call
Cmp AL, 2 ; See if it's 2.0 or above
Jae DosVersOK ; If so, continue

Mov DX, Offset DosVersMsg ; Error message
ErrorExit: Mov AH, 9 ; Print String function call
Int 21h ; Do it
Int 20h ; And exit prematurely

; Parse Command Line to get file specification
; --------------------------------------------

DosVersOK: Mov SI, 1+Offset Parameter ; Parameter string pointer
Cld ; Directions forward

FlagSearch: Lodsb ; Get Byte
Mov DI, Offset Delimiters ; Check if delimiter
Mov CX, 5 ; Five delimiters to check
Repne Scasb ; Scan the string
Je FlagSearch ; If delimiter, circle back
Mov DX, Offset SyntaxMsg ; Possible error msg
Cmp AL, 13 ; If carriage return, no file
Je ErrorExit ; so exit with message

Mov DI, Offset OrAttrBits ; Pointer to plus flag saver
Cmp AL, '+' ; See if plus sign
Je PlusOrMinus ; If so, save the bit
Mov DI, Offset AndAttrBits ; Pointer to minus flag saver
Cmp AL, '-' ; See if minus sign
Jne MustBeFile ; If not, it must be file name

PlusOrMinus: Mov ,-1 ; Set for changing
Lodsb ; Get the next byte
And AL, 0DFh ; Capitalize it
Mov BX, Offset FlagList ; List for scanning
Mov CX, 4 ; Scan for A, S, H, and R

SearchList: Cmp AL, ; See if a match
Jz FoundFlag ; If so, proceed to save
Inc BX ; Kick up pointer
Loop SearchList ; And loop around for next
Mov DX, Offset FlagErrMsg ; Otherwise, set message
Jmp ErrorExit ; And terminate

FoundFlag: Mov AL, ; Get bit mask
Or , AL ; Turn saved bit on
Jmp FlagSearch ; And continue looking

MustBeFile: Not ; Invert bits for turn off
Mov , SI ; Save file name pointer
Dec ; Actually one byte lower

EndSearch: Lodsb ; Get Byte
Mov DI, Offset Delimiters ; Check if delimiter
Mov CX, 6 ; Six delimiters including CR
Repne Scasb ; Scan the string
Jne EndSearch ; If not delimiter, keep going

; Transfer Search String down at end of program
; ---------------------------------------------

Dec SI ; Points after file spec
Mov Byte Ptr , 0 ; Make it ASCIIZ string
Mov CX, SI ; CX points to end
Mov SI, ; SI points to beginning
Sub CX, SI ; Now CX is length of it
Mov DI, Offset PathAndFile ; Destination of string
Mov , DI ; Save it here also

SearchTrans: Lodsb ; Get byte of search string
Stosb ; And save it down below
Cmp AL, ':' ; See if drive marker
Je PossibleEnd ; If so, take note of it
Cmp AL, '\' ; See if path separator
Jne NextCharacter ; If not, skip next code

PossibleEnd: Mov , DI ; This is the new end
NextCharacter: Loop SearchTrans ; Do it again until done

; Find Files from Search String
; -----------------------------

Mov DX, Offset DTABuffer ; Set File Find buffer
Mov AH, 1Ah ; by calling DOS
Int 21h

Mov DX, ; Search string
Mov CX, 16h ; Search Everything
Mov AH, 4Eh ; Find first file

FindFile: Int 21h ; Call DOS to find file
Jnc Continue ; If no error continue
Cmp AX, 18 ; If not "no more files" error
Jnz FindError ; print error message
Jmp NoMoreFiles ; Now get out of the loop

FindError: Mov DX, Offset FileSpecMsg ; Error message for file spec
Jmp ErrorExit ; Exit and print message

Continue: Mov SI, 30+Offset DTABuffer ; Points to filename
Cmp Byte Ptr , '.' ; See if "dot" entry
Jnz FileIsOK ; If not, continue
Jmp FindNextFile ; If so, skip it

FileIsOK: Mov DI, ; Destination of file name
Mov CX, 14 ; Number of bytes to display

TransferName: Lodsb ; Get the byte in file name
Stosb ; Save it
Or AL, AL ; See if terminating zero
Jz PadWithBlanks ; If so, display blanks
Call DisplayChar ; Display the character
Loop TransferName ; And loop back around

PadWithBlanks: Mov AL, ' ' ; Pad names with blanks
Call DisplayChar
Loop PadWithBlanks ; And loop until CX is zero

; Change And Display File Attributes
; ----------------------------------

Mov DX, Offset PathAndFile ; Points to ASCIIZ string
Test , -1 ; See if changing attributes
Jz DisplayIt ; If not, just display them

Mov AX, 4300h ; Get file attribute
Int 21h ; by calling DOS
And CL, 27h ; Zero out some bits
And CL, ; Turn off some bits
Or CL, ; Turn on some bits
Mov AX, 4301h ; Set file attribute
Int 21h ; by calling DOS

DisplayIt: Mov AX, 4300h ; Get file attribute
Int 21h ; by calling DOS
Mov BL, CL ; BL is attributes
Or BL, 08h ; Turn on Volume bit
Shl BL, 1 ; Shift to get rid of
Shl BL, 1 ; unused bits
Mov CX, 6 ; Number of bits left
Mov DX, 5+Offset AllFlagList; Storage of abbreviations

AttrListLoop: Push DX ; Save abbreviation pointer
Shl BL, 1 ; Shift bit into carry
Jc FlagIsOn ; See if it's on
Mov DX, Offset AllFlagList ; If not, print blanks

FlagIsOn: Mov AH, 9 ; Print string
Int 21h ; by calling DOS
Pop DX ; Get back abbreviation ptr
Add DX, 5 ; Kick up for next bit
Loop AttrListLoop ; And loop around
Mov AL, 13 ; Print carriage return
Call DisplayChar
Mov AL, 10 ; Print line feed
Call DisplayChar

FindNextFile: Mov AH, 4Fh ; Find next file
Jmp FindFile ; By looping around

NoMoreFiles: Int 20h ; Terminate

; SUBROUTINE: Display Character in AL
; -----------------------------------

DisplayChar: Push AX
Push DX
Mov DL, AL ; Move character to DL
Mov AH, 2 ; Display it
Int 21h ; by calling DOS
Pop DX
Pop AX
Ret

; Some data stored at end to cut down COM size
; --------------------------------------------

DTABuffer Label Byte ; For file find calls
PathAndFile equ DTABuffer + 43 ; For file path and name
CSEG EndS ; End of the segment
End Entry ; Denotes entry point




我的網站:http://mw16.2ya.com/ 我的網誌: http://scrappedblog.blogspot.com/
~
我的Winamp正在播放的歌曲:
2003-6-1 00:00
查看资料  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: