中断调用,读写内存、端口应用讲解(2)

来自:http://qbdos.51.net/cgi-bin/bbs 作者:
详细调用举例(INT21中的文件功能)
我们找到DOS中断调用手册中有关的资料,然后在QB中来完成它!
入口 AH=1A 置数据传送地址 DS:DX=* 指向存储单元
入口 AH=4 E寻找第一个相符文件 DS:DX=* ASCIIZ字符串存储单元 (驱动器/路径/文件名)
CX=检索属性
入口 AH=4F下一个相符文件 (AH=4EH是第一次被调用)
我刚开始学QB的时候,是用SHELL “DIR >1.TXT”然后用程序分析1.TXT来判断显示文件列表,后来知道了QB可以用中断。我们再看看与这些有关功能调用的详细说明,当然看上面的资料就应该已经可以做出来了 !
功能4EH
功能描述: 获取第一个与给定的文件名相匹配的文件
入口参数: AH=4EH,DS:DX=给定文件名的字符串
CX=搜索时使用的文件属性: 位0=1——只读  位1=1——隐含
位2=1——系统  位3=1——卷标号
位4=1——目录  位5=1——归档
其它位保留不用,并置为0
出口参数: CF=1——操作失败,AX=错误号(02H、03H或12H),其含义见错误代码表,否则,操作成功,DTA(Disk Transfer Area)按下列方式填入数据: 字节00~14H 保留
字节15H 匹配的文件属性
字节16~17H 压缩的文件名
字节18~19H 压缩的文件日期
字节1A~1DH 文件大小
字节1E~2AH 文件名字符串
功能4FH
功能描述: 在中断21H的功能4EH成功使用之后,再搜索下一个文件名
入口参数: AH=4FH,AL=返回的代码
出口参数: CF=1——操作失败,AX=错误号(12H),其含义见错误代码表,否则,操作成功,DTA中的数据如前面功能4EH所示

根据这些资料,我们来做个文件列表,请看

TYPE RegTypeX
ax AS INTEGER
bx AS INTEGER
cx AS INTEGER
dx AS INTEGER
bp AS INTEGER
si AS INTEGER
di AS INTEGER
Flags AS INTEGER
ds AS INTEGER
es AS INTEGER
END TYPE

DIM SHARED ax, bx, cx, dx, si, di, Flags, ds, es, ah, al, bh, bl, ch, cl, dh, dl

CLS
file.list "*.*"
END

FUNCTION file.dta$ (dta$, fmode)
'从缓冲区中分离出文件名
endofstr% = INSTR(31, dta$, CHR$(0))
file.dta$ = MID$(dta$, 31, endofstr% - 31)
END FUNCTION

SUB file.list (Filename$)
FileNum = 0
dta$ = SPACE$(43)
dx = SADD(dta$)
ds = VARSEG(dta$)
ax = &H1A00 '设置文件数据块
Xint &H21

Filename$ = Filename$ + CHR$(0)
ax = &H4E00
dx = SADD(Filename$)
ds = VARSEG(Filename$)
cx = &HFF
Xint &H21 '查找第一个相符的文件
f = Flags AND 1
PRINT FileNum, file.dta$(dta$, 1)
DO WHILE f = 0 '如果找到第一个文件,就继续查找,直到结束
FileNum = FileNum + 1
PRINT FileNum, file.dta$(dta$, 1)
ax = &H4F00
Xint &H21
f = Flags AND 1
LOOP
END SUB

SUB Xint (IntNum%)
DIM Reg AS RegTypeX
IF ax = 0 THEN ax = ah * &H100 + al
IF bx = 0 THEN bx = bh * &H100 + bl
IF cx = 0 THEN cx = ch * &H100 + cl
IF dx = 0 THEN dx = dh * &H100 + dl
Reg.ax = ax
Reg.bx = bx
Reg.cx = cx
Reg.dx = dx
Reg.si = si
Reg.di = di
Reg.ds = ds
Reg.es = es
CALL INTERRUPTX(IntNum%, Reg, Reg)
ax = Reg.ax
bx = Reg.bx
cx = Reg.cx
dx = Reg.dx
si = Reg.si
di = Reg.di
ds = Reg.ds
es = Reg.es
Flags = Reg.Flags
ah = ax AND &HFF00: ah = ah / &H100
al = ax AND &HFF
bh = bx AND &HFF00: bh = bh / &H100
bl = bx AND &HFF
ch = cx AND &HFF00: ch = ch / &H100
cl = cx AND &HFF
dh = dx AND &HFF00: dh = dh / &H100
dl = dx AND &HFF
END SUB