- 注册时间
- 2006-7-15
- 最后登录
- 1970-1-1
|
浅探BASIC文件结构
BY:Windy.Bell.
(本文中的内容均来自NC3000,研究工具为pacmgr.lav和我编写的垃圾程序 窥视者.BAS)
--------------------------
+------+
| 例子 |
+------+
0 :
10 GRAPH
20 PRINT "HELLO WORLD!","这是一个测试程序。"
30 END
用pacmgr打开看到:
-00077000003A000D
-700A009E003F7014
-00982248454C4C4F
-20574F524C442122
-2C221FD5E21FCAC7
-1FD2BB1FB8F61FB2
-E21FCAD41FB3CC1F
-D0F21FA1A3220045
-701E0080000000
+------+
| 开头 |
+------+
每行开头有5bits,格式为:
00 YY XX BB AA
$00 为固定的标识符,但不知具体用处是什么。
$XXYY 为下一行开头的地址,指向下一个5bits的 YY 处。
AA*256+BB 即该行的行号
eg.
0 :
00 0770 0000 3A
10 GRAPH
00 0D70 0A00 9E
(pacmgr大概是将文件放到了$7000处,开始地址为$7000。我用自己编的 窥视者.BAS 察看时,发现开头是$2000,即8192。)
第一个5bits中的$7007即下一个5bits的 #$0D 的地址,0000即行号0。第二个5bits中的0A00当然就是行号10了。
(我很矛盾,行号要不要算到开头来。如果不算的话,那么开头和结束都是3bits,很整齐。但我又觉得,行号这个东西,应该和$XXYY一样起着标识作用。这5bits是我划分的,算不得准,读者不要存在心里面。)
+------+
| 中部 |
+------+
每函数名(关键字)均对应一个大于127的数字(请看附表),在文件中占1byte。函数的参数在文件中则以ASCII码储存。
eg.
20 PRINT "HELLO WORLD!","这是一个测试程序。"
(为了不至于眼花缭乱,我把它们分段写下来。)
00 3F70 1400 98 22 48454C4C4F 20 574C4421 22 2C 22 1FD5E2 1FCAC7 1FD2BB 1FB8F6 1FB2E2 1FCAD4 1FB3CC 1FD0F2 1FA1A3 22
(还是很眼花缭乱......-_-U)
对应起来看,显然#$98对应的就是PRINT函数。
+------+
| 结尾 |
+------+
结尾是3bits,00 00 00,GVBASIC.bin应该就是以$0000作为结尾标记的。
--------------------------
可以看出,由于汉字的ASCII码是两个大于127的数字,可能会与关键字的判断发生冲突,ASCII码大于127的符号前面都用#$1F作了标记。所以在GVBASIC里用LEN()函数看ASCII码大于127的字串时,显示的长度为3的倍数。
在GVBASIC中,符号CHR$(31)无法直接用 PRINT CHR$(31) 显示,就是由于31(#$1F)被用作了标记。
既然清楚了原理,问题自然迎刃而解。只需要 PRINT CHR$(31)+CHR$(31) 即可。注意这加号前一个CHR$(31)是标记,如果写成 PRINT CHR$(31);CHR$(31) 可就成了两个标记,一样显示不出来的。
就这么多,不知除了动态修改程序时数(Shǔ)字节,本文还有没有什么用处。汗......-_-U
附表:
------ 关键字对应表 ------
80 END 81 FOR 82 NEXT 83 DATA
84 INPUT 85 DEL 86 DIM 87 READ
88 SWAP 89 TRACE 8A NOTRACE 8B POP
8C LET 8D GOTO 8E RUN 8F IF
90 RESTORE 91 GOSUB 92 RETURN 93 REM
94 STOP 95 ON 96 DEF 97 POKE
98 PRINT 99 CONT 9A LIST 9B CLEAR
9C NEW 9D TEXT 9E GRAPH 9F SYSTEM
A0 NORMAL A1 INVERSE A2 FLASH A3 PLAY
A4 BEEP A5 INKEY$ A6 LOAD A7 SAVE
A8 KILL A9 FILES AA OPEN AB CLOSE
AC WRITE AD FIELD AE GET AF PUT
B0 LSET B1 RSET B2 AUTO B3 LOCATE
B4 DRAW B5 LINE B6 BOX B7 CIRCLE
B8 ELLIPSE B9 CLS BA EDIT BB WHILE
BC WEND BD CALL BE RENAME BF COPY
C0 TAB C1 TO C2 FN C3 SPC
C4 THEN C5 ELSE C6 AT C7 NOT
C8 STEP C9 + CA - CB *
CC / CD ^ CE AND CF OR
D0 > D1 = D2 < D3 SGN
D4 INT D5 ABS D6 POS D7 SQR
D8 RND D9 LOG DA EXP DB COS
DC SIN DD TAN DE ATN DF PEEK
E0 LEN E1 STR$ E2 VAL E3 ASC
E4 MKS$ E5 MKI$ E6 CVS$ E7 CVI$
E8 LOF E9 EOF EA CHR$ EB LEFT$
EC RIGHT$ ED MID$
--------------------------
附注:
这张表中的内容,有些前辈们恐怕很早就知道了。我在用GVBASIC研究并填满这张表时,发现根本填不满!像FLASH这种PC1000及以前机种上才有的指令,我自己都不知道。后来灵光一闪,想起pacmgr有BAS转化的功能,于是抱着希望用pacmgr察看了pacmgr本身,居然给我找到了整张表!激动之余想起前辈风范,不禁心向往之…… |
|