易码技术论坛

 找回密码
 加入易码
搜索
查看: 229982|回复: 9

用BAS调用BAS问题

[复制链接]
发表于 2006-7-16 14:05:00 | 显示全部楼层
怎么没人回?
[em03]
发表于 2006-7-20 01:25:00 | 显示全部楼层
发表于 2006-7-20 19:11:00 | 显示全部楼层
报什么错?
发表于 2006-7-20 20:59:00 | 显示全部楼层
NC3000 GVbasic超精华文章 必看!!★☆★NC3000新技术发表: 在BASIC中动态调用程序★☆★
作者:Dojo
    上次在查laugj写的NC2600的PEEK表时意外知道CALL 17927可以运行文件,连忙在我的NC3000上试了一下,结果不行!
    经过好长时间的研究终于发现原来是因为NC2600和NC3000放当前运行程序文件名的地址不同害的:NC2600是2262--2275,NC3000是2189--2202。
方法是:
先新建一个BAS文件:
-------------------
10 B$="B.BAS"
20 L=LEN(B$)
30 FOR I=2189 TO 2202
40 POKE I,0
50 NEXT
60 FOR I=1 TO L
70 N=ASC(MID$(B$,I,1))
80 POKE I+2188,N
90 NEXT
100 CALL 17927
-------------------
将这个程序命名为A.BAS。
再建立一个BAS文件:
-------------------
10 GRAPH
20 FOR I=1 TO 10: BEEP : NEXT
30 PRINT "     恭喜!!!!!"," 你已成功调用本程序 感谢你对Dojo的支持!! ","        By DojoSoft";
40 FOR I=1 TO 10: BEEP : NEXT
50 W$= INKEY$
60 POKE 199,128: END
-------------------
运行A.BAS你会发现B.BAS被调用了!!!
本技术原理如下:
    第一步:修改当前运行程序文件名。即修改内存2189到2202的值,方法是求出被调用程序的文件名(包括后缀)的ASCII码值,再逐个按顺序POKE到2189到2202中。文件名不足15字节要把后面的地址POKE为0,当然你也可以像上面示例一样先把2189到2202POKE为0再去POKE文件名。做完这些后再写上CALL 17927就完了。
    第二步:制做被调用的程序(也可先做这个,没关系的)。这可以是任意程序,但要注意的是此时正常退出程序会关机或重启,我不知道是什么原因(高手知道原因告诉我啊)。解决的方法是退出程序改为"POKE 199,128:END"此时会跳到时间热键,也可改为其它热键。
PS.
1.允许运行被调用程序时再回到原程序中,允许多个程序以环状、星状、树状等方式“接力”,方法同上,退出时的问题同样要注意。还有以上都要用GVBASIC+运行。
2.“接力”程序时变量会清空,如后来要用必需先把它们写入文件或POKE到空闲内存中,要用时再读出来。
3.为防止被调程序被单独运行可采用以下两种方式:
一.在调用程序前几行把系统时间读出来(读出时、分、秒即可),再把它们POKE到空闲的内存地址中(或写入文件),调用完成后由被调程序读出来与系统时间对比,如不同(允许差1秒)则肯定单独运行,提示并自动退出即可。
二.把被调程序都放在另外目录下,由留在“BASIC文件”目录下的入口程序去调用。切换目录的方法我会马上贴上来。
4.如果要调用某程序不同的程序段则可在调用前把特定的数值POKE到空闲内存(或写入文件),在被调程序前写几个IF语句根据该数值GOTO相应的行号即可(可惜GOTO后面不能跟变量,不然方便多了)。
    没想到这么简单吧?快去试试!要调用其它程序改一下A.BAS中的B$就可。
    用这个方法使BAS完全能“拼凑”出大型程序。
    爽歪了吧?
    多顶我欧~~~
 楼主| 发表于 2006-7-22 11:28:00 | 显示全部楼层
上面的方法我也知道!

只是不知道我的方法哪儿有错!
发表于 2006-7-22 12:49:00 | 显示全部楼层
应该是因为行的长度不同。应该这样:

10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

20 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

30 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

然后读到这种地方。

可能是BASIC.BIN在载入文件时就定下行号起始的地址了,所以只能顺序执行不能GOTO。
 楼主| 发表于 2006-7-25 10:01:00 | 显示全部楼层
只能顺序执行???

但可以用FOR的!

10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

20 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

30 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

然后读到这种地方。




我回去试试!
 楼主| 发表于 2006-7-25 10:03:00 | 显示全部楼层
以下是引用George在2006-7-20 19:11:00的发言:[BR]报什么错?


就是提示此行号不存在的错!
发表于 2006-7-26 12:12:00 | 显示全部楼层
不知道说得对不对:

最近看《最新C语言精华》(老外写的),最后一章他说要让我们C的初学者激动一下,于是教我们写一个C的解释程序,大概是这样的:在真正执行前先用一个函数(pre_scan())扫描整个程序,他说这叫预扫,以此记录各个函数开始的地方(也就是在文件中的位置)并提取全局变量,以后的执行是顺序的,读取一个个记号(get_token())然后用分别对应的函数执行,包括for循环--它在读到for的时候才记录它开始的地方。换句话说,行号和函数入口(当前BASIC只有前者)是在载入文件时已经定下的,而FOR循环时记录的地址却是在顺序执行时生成的。
 楼主| 发表于 2006-7-14 00:38:53 | 显示全部楼层 |阅读模式
在GVB中BAS文件是被载到$2000处执行的
只要在一个BAS文件中将另一BAS文件读入$2000 再 GOTO 10 就可以执行另一文件了。
以下是我的代码:
在A.BAS中运行B.BAS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


--------------A.BAS
10 DATA 0,21,5,96,0,22,5,96,0,23,5,96:REM INT$0515;打开文件 INT$0516;读文件;INT$0517;关闭文件
20 FOR I=0 TO 11:READ A
30 POKE 4096+I,A:NEXT
40 FOR I=1 TO LEN("B.BAS")
50 A=ASC(MID$("B.BAS",I,1))
60 IF A-31 THEN POKE 2188+I,A
70 NEXT
80 POKE 2188+I,0:REM 将文件名写入$088d
90 OPEN "B.BAS" FOR RANDOM AS#1=LOF(1):CLOSE #1
100 POKE 2249,128:REM 只读
110 POKE 2246,L-INT(L/256)*256
120 POKE 2247,INT(L/256) :REM 读B.BAS的长度
130 POKE 224,0
140 POKE 225,32:REM 读入$2000
150 CALL 4096:CALL 4100:CALL 4104
160 GOTO 10:REM 读B.BAS


--------------B.BAS
10 :REM 如果将这行改为GOTO 30就报错
20 BOX 1,1,160,80
30 LINE 1,1,160,80
40 END
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


B.BAS 中不能使用GOTO 和 GOSUB 这是为什么?这是NC3000 GVBASIC+的BUG吗?
请各位高手指教!
以下是A.BAS和B.BAS的打包文件。


您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-3-29 05:11 , Processed in 0.009914 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表