回 帖 发 新 帖 刷新版面

主题:求教: 远调用

我有一模块,运行后驻留内存
我能得到它的入口地址,并且知道调用它的参数,
请问在QB中如何调用它???

请高手指教!谢谢了!!

回复列表 (共18个回复)

沙发

问一下 怎么得到它的入口地址和调用它的参数

板凳

这个模块安装后能够用DOS中断2f获得它的入口地址

在C中可以设置一 far 指针对这个入口调用
在汇编中也可以用 CALL dword ptr addrres 对入口进行远调用

它的功能是有功能号的,把功能号放进AH中再调用
如:AH=2
   call 地址

但是在QB中没用远调用的方法可用
我现在用ASM写,但是翻成机器码时又好麻烦,汇编都是找资料的

说明一下:我是想做一个通用的能够使用扩展内存的QB函数集

3 楼

1 用DEBUG写程序
2 把你写的ASM程序保存,比如你保存为DEMO。COM
3 用QB写个程序转换为机器码
原程序如下:
OPEN "DEMO.com" FOR BINARY AS #1
OPEN "iotest1.bas" FOR OUTPUT AS #2
r$ = "1"
PRINT #2,"DATA ";
FOR i = 1 TO LOF(1)
    GET 1, i, r$
    PRINT #2, HEX$(ASC(r$)); ",";
NEXT i
END
4 把iotest1.bas中的DATA XX,XX,XX.........XX复制到你的BAS文件中
  调用的时候用READ读出来
  例如:FOR I=1 TO 16
           READ,R$   
           ASM$=ASM$+CHR$(VAL("&h"+R$))
       NEXT I
5 用SEG设置段址,用absolute 调用
  例如
  SEG = VALSEG(ASM$)
  CODE%=SADD(ASM$)
  CALL absolute (code%)    


希望能对你有帮助!

4 楼

现在问题是Debug中有很多asm源码不能照样输入
如:    下面中myval是变量

mov myval,ax         
mov es:[di],al
jc label:
jnc label:

输入这些时会发生错误,我正在翻Debug的书看,有要用什么方法

5 楼

To: QB45    (秋水.夕阳?)

真的能这样调用?
反正字符串也是有限制的,要这样能成功调用的话,我来帮你简简:
可谓简单到极点

fr=freefile
OPEN "DEMO.com" FOR BINARY AS #fr
  ARM$=input$(16383,#fr)
close #fr
  SEG = VArSEG(ASM$)
  CODE%=SADD(ASM$)
  CALL absolute (code%)    
如果文件太大的话,用数组可以去到64K
dim ARM(64) as string*1000
code%=varptr(asm(0))

To:  QB71  (秋风?)
如果45讲的方法不出错的话,
参数的方法也很简单喔.
比如你要用到某个变量,
你弄点语句作变量的赋值(或者是参数)
弄个容易认的数字啊(比如两三个大写字母A之类的)
找到这个参数的地址.(可以用edit /100 或者用你想得到的任何办法去找)
然后
把ARM$对应的位置的字符值改掉
mid$(ARM$,,)=(QB中的变量)
哈哈,苏伊士(SO EASY.)
如果不成功别要笑我笨喔.


再To: QB45
.com文件就是用汇编写的?
让我狂冒汗.(没脸见人了)

6 楼

to MOZ:

'$INCLUDE: 'qbx.bi'
dim shared segxms as integer,offxms as integer

'初始化XMS,返回时 0 没有扩展内存,<>0 有扩展内存
function xms.init%     
    dim asm as string*13
    dim al as integer
    Mid$(asm,1,3) = CHR$(&HB8) + CHR$(&H0) + CHR$(&H43)
    Mid$(asm,4,2) = CHR$(&HCD) + CHR$(&H2f)
    Mid$(asm,6,3) = CHR$(&H68) + MKI$(VARSEG(Al))
    Mid$(asm,9,1) = CHR$(&H1F)
    Mid$(asm,10,3) = CHR$(&HA2) + MKI$(VARPTR(Al))
    Mid$(asm,13,1) = CHR$(&HCB)

    DEF SEG = VARSEG(asm)
    CALL Absolute(VARPTR(asm))
    def seg
    if al=128 then xms.init%=-1
end function

'取XMS入口地址,返回 segxms 段地址,offxms 偏移地址
function xms.addrres
    dim asm as string*22
    Mid$(asm,1,3) =chr$(&Hb8)+chr$(&H10)+chr$(&H43)
    Mid$(asm,4,2) =CHR$(&HCD) + CHR$(&H2f)    
    Mid$(asm,6,3) =chr$(&H68)+MKI$(VARSEG(offxms))
    Mid$(asm,9,1) =chr$(&H1f)
    Mid$(asm,10,4) =chr$(&H89)+chr$(&H1e)+MKI$(VARPTR(offxms))
    Mid$(asm,14,3) =chr$(&H68)+ MKI$(VARSEG(segxms))
    Mid$(asm,17,1) =chr$(&H1f)
    Mid$(asm,18,4) =chr$(&H8c)+chr$(&H06)+MKI$(VARPTR(segxms))
    Mid$(asm,22,1) =chr$(&hcb)
    
    DEF SEG = VARSEG(asm)
    CALL Absolute(VARPTR(asm))
    def seg
end function

'请实现以下功能
'说明: 将 AH  置于功能代码而进行对驱动程序入口点的FAR调用
'用 def seg=segxms   
'   call absolute(offxms) 调用 ?

'09    分配已扩展的内存块      AX=0001H  成功
'      DX=需要的K字节数           DX=内存块句柄
'                                 0000H  失败
'                                 BL=错误码

'0A    释放自由扩展内存块      AX=0001H  成功
'                                 0000H  失败
'                                 BL=错误码

'0B    移动扩展内存块          AX=0001H  成功
'      DS:SI=EMMTYPE              0000H  失败
'      (如果两者中的任一句柄      BL=错误码
'       为0000H则相应的偏移被
'       当作绝对段:在可直接寻
'       址内存中的偏移地址)

'EMM结构格式:
'Type EMMTYPE
'   msize as long         '要移动的字节数(必须为偶数)
'   sHandle as integer    '源句柄
'   sOffset as long       '进入源块的偏移
'   aHandle as integer    '目的句柄
'   aOffset as long       '进入目的块的偏移
'end TYPE

7 楼

嘿嘿,我又忍不住手帮你简写了一下,哈哈,别介意.

DECLARE FUNCTION xms.init% ()
DECLARE FUNCTION xms.addrres! ()

'$INCLUDE: 'qbx.bi'
DIM SHARED segxms AS INTEGER, offxms AS INTEGER

'取XMS入口地址,返回 segxms 段地址,offxms 偏移地址
FUNCTION xms.addrres
    DIM asm AS STRING * 22
    asm = CHR$(&HB8) + CHR$(&H10) + CHR$(&H43) + CHR$(&HCD) + CHR$(&H2F) + CHR$(&H68) + MKI$(VARSEG(offxms)) + CHR$(&H1F) + CHR$(&H89) + CHR$(&H1E) + MKI$(VARPTR(offxms)) + CHR$(&H68) + MKI$(VARSEG(segxms)) + CHR$(&H1F) + CHR$(&H8C) + CHR$(&H6) +  _
MKI$(VARPTR(segxms)) + CHR$(&HCB)
    DEF SEG = VARSEG(asm)
    CALL Absolute(VARPTR(asm))
    DEF SEG
END FUNCTION

'初始化XMS,返回时 0 没有扩展内存,<>0 有扩展内存
FUNCTION xms.init%
    DIM asm AS STRING * 13
    DIM al AS INTEGER
    asm = CHR$(&HB8) + CHR$(&H0) + CHR$(&H43) + CHR$(&HCD) + CHR$(&H2F) + CHR$(&H68) + MKI$(VARSEG(al)) + CHR$(&H1F) + CHR$(&HA2) + MKI$(VARPTR(al)) + CHR$(&HCB)
    DEF SEG = VARSEG(asm)
    CALL Absolute(VARPTR(asm))
    DEF SEG
    'IF al = 0 THEN xms.init% = -1
    xms.init% = al
END FUNCTION

你这两个函数我不太明白
xms.init%返回的不是al的值吗?
那就应该按我改的xms.init%=al
第二个函数怎么没有返回值的
xms的段地址和偏移量是放在什么地方的?

至于你的问题:怎样调用
我就不太明白了,很抱歉,我只在好多年前学了几句汇编MOV, ADD
其他的我不知道要调用哪个中断号.

8 楼

哎!!!!!!!!!!

程序不能再简了
AL=128时有扩展内存,<>128时没有扩展内存
这一句是我写错了,我改回去了
求地址的地方那几句是不能去掉的,否则不能返回

    Mid$(asm,10,4) =chr$(&H89)+chr$(&H1e)+MKI$(VARPTR(offxms))
                                                        ^偏移地址
    Mid$(asm,18,4) =chr$(&H8c)+chr$(&H06)+MKI$(VARPTR(segxms))
                                                        ^段地址

9 楼

我现在是连用哪个段寄存器都弄不清楚
真失败,老是死机,有高手又不肯说,就说不会没弄过扩展内存
这是中国人的悲哀,叫什么蔽帚自珍

10 楼

呵呵,不一定每个高手都像你想像中的那么高的,
当代高手已经用不着接触低层的东西了.

你那几句mid$()=我已经放在赋值语句去了,哈哈

我这两个星期都在各个书店找关于中断的出入口参数,
在网上找到的只是英文的,而且参数也不齐全,更加上我的汇编还没有时间恶补,
所以很抱歉...... I can't help you.

是秋水找你要这些东西吧?
他想用这些东西要做一些关于硬盘的工具,
希望不通过文件来处理一些数据吧.
1.  你可以参考一下UCDOS的有关程序
    比如FREE之类
2.  这个更简单,哪天你需要了,我帮你找,
    其实说不定你的QB目录里面也附带例程的,
    我见过到,
    文件名大概是mem*.bas吧,哈哈,别揍我.这是真的.
    我有时间找到了告诉你.应该不会很久的.

我来回复

您尚未登录,请登录后再回复。点此登录或注册