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

来自:http://qbdos.51.net/cgi-bin/bbs 作者:
要在程序中调用中断必须要做到:
(1)启动QB时,要加上命令参数/L,才能将QB.QLB系统快速库装入集成环境;
例如在Dos下键入 QB/L
(2)在程序开始处写入调用包含文件的语句:'$INCLUDE:'QB.BI'。
中断后援的定义以及子程序的声明都写在系统头文件:QB.BI中。如果不想写这个语句,也可以只复制这个里面的相关内容就行!
Quick BASIC提供了中断调用的接口,来实现中断的调用。QB系统提供的快速库QB.QLB和QB.LIB就是为用户实现中断调用的。其中INTERRUPT 和 INTERRUPTX 是它们五个系统子程序中的两个,它们两个中断调用更方便,执行中断执行中断前后CPU的寄存器组用记录类型来处理。
INT86OLD,INT86XOLD,INTERRUPT,INTERRUPTX 可以调用中断


下面是与其有关的语句用法!
OUT P,D '功能I O通道的输出,P是端口地址,D是数据
INP (P) '功能I O通道的输入,P是端口地址
'注意:用端口输入输出的数据是字节,不是字!

POKE A,D '功能写内存,A是偏移量,D是数据
PEEK(A) '功能读内存
DEF SEG=A '功能设置段址,A是段址 范围在:0-&HFFFF

VARSEG(A$) '功能,返回A$的段址
SADD(A$) '功能,返回A$的偏移地址,相当于C语言中的字符指针,不过它只取地址!

如果你定义A是16个字符例如DIM A AS STRING*16
是不能用SADD语句来获得它的偏移地址,必须用VARPTR来获得
例如 :
DIM A AS STRING*16
PRINT "段址= " ;varseg(a)
PRINT "偏移= " ;varptr(a)

VARPTR还有个用处是获得数组的偏移地址
absolute (code%) '功能,执行机器码 Code%是机器码的起始地址
这个语句非常好,本来极大的提高程序的速度,如果要用QB做游戏或者是速度要求很高的场合,非此句莫属!这个得需要有汇编基础的人才能用的得心应手!在本论坛的也有这个方面的原程序!请自己找!

以上的语句在DOS功能调用的时候经常要用到!


我们在QB来调用INT21得到日期
我们先来看看有关的资料
INT 21号DOS中断调用:
入口 2AH AH=2AH 功能:取日期
返回 CX=年
DH=月
DL=日

有了上面这个资料,我门来取当前的系统日期
'$INCLUDE: 'qb.bi'
DIM reg AS RegType
reg.ax = &H2A00 '入口AH=2A
INTERRUPT &H21, reg, reg '调用21号DOS中断
PRINT reg.cx 'CX中是返回的日期

详细的中断调用例程见:
"读取硬盘主引导区的源程序"
“鼠标、汉字、按纽的原程序”
“文本模式下显示汉字的原程序”
教程中获得文件列表的那部分程序!
还有请自己找找
... .... ....
冷石作品中1024*768 256色显示的程序也有响应的中断调用的例子

用法举例
例1 :
out &H61,&HFF '此句可以让pc喇叭发声
PRINT INP(&H61) '此句是读取61H端口的数据

例2:
目的:把A$的内容改掉
A$="abcdefgh"
DEF SEG=VARSEG(A$)'把当前段定位到A$的段纸
off=sadd(a$) '获得A$的偏移      
FOR I= 0 TO len(a$)
POKE off+I,49+i
NEXT I
DEF SEG '恢复段

运行后a$里的内容就被改成12345678了

例3:
DEF SEG=&hb800
FOR I= 1 TO 100
POKE I,49
NEXT I
DEF SEG
END