家教机 点读机 校园内外 亲子部落 礼物兑换
您的位置: 论坛/校园内外/帖子详情
Hi,您好!|步步高消息(0)
楼主

标题:

[原创]强大函数 制作bb的动态链接库(dll),实现数据库,用汇编的【申精】

4跳转到确定


做这个函数是很久以前都有打算的,今天弄出来后实现的效果还是非常满意啊,甚至可以直接生成一个可供运行的bin,也可以读取外部的bin,只需要在开头偏移16字节就是了(下面有实例)。
其实4mb还是相当的大了,基本还没有谁做过3 4mb的游戏吧。所以呢,对于当东西进去的时候不要考虑太多了。

这里讲讲函数的本质:
[quote]ld int r0,0
ld byte r0,地址[/quote]
就这么的简单。只要我们一字节一字节的读取,就不会出错了。避免了低位在前高位在后的困扰。
但是首先确保r0清零。-------这是我睡了又爬起来写的~~~~


做这个函数也是为了我做游戏的,为了把大部分的数据读到内存,方便访问。这里说说我读取文件的原理,按照正常的想法
[quote]get #1,a

vasm("ld int [buffer],[vint_a]")'将a的值放到缓存下面[/quote]
这样是必死无疑的。因为bb读文件的时候都是低位在前高位在后的,好像叫这个。比如一个数字[quote]5201314 = 4F5DA2(16进制)
然后因为是8字节的数据类型,补齐就是
4F5DA2 = 00 4F 5D A2
然后存入数据
因为先说的那个规则存入结果:
[/quote][quote]00 4F 5D A2 =》 5D A2 00 4F[/quote]
关于这个我也不必讲太多了,有兴趣的可以百度或者谷歌,关键字:big-edian和little-endia
关于这个 可以用 010 EDITOR 编辑器改变,当然,改变的只是你看到的,不能改变bb读取的方式。

先上代码:
[quote];==//=======
;r0 偏移
;r1 监听函数
;r2 缓存地址
;r3 文件名
;==//=======

in_file:
ld int [in_file_cur_op],r0
ld int [in_file_listener],r1
push r2

;打开文件
ld int r0,1;打开方式
ld int r1,9;文件号
out 48,0
;获取文件长度
ld int r3,9;文件号
out 53,0
ld int [in_file_file_len],r3 ;文件长度


pop r0;缓存地址
;遍历
in_file_while_begin:;//循环开始
cmp int [in_file_cur_op],[in_file_file_len]
jpc z in_file_while_end:

;指针偏移
ld int r2,9;文件号
ld int r3,[in_file_cur_op]
out 55,16 ;seek

;读取文件内容
ld int r1,9;文件号
ld int r2,2147483647;偏移量
out 50,16 ;get

;out 0,r0 存放到缓存地址
ld byte [r0],r3
cal int add r0,1

;计算进度,调用监听函数

ld int [vint_load_process],[in_file_cur_op]
cal int mul [vint_load_process],100
cal int div [vint_load_process],[in_file_file_len]
call [in_file_listener];调用回调函数

;指针增量
cal int add [in_file_cur_op],1

jmp in_file_while_begin:

in_file_while_end:;//循环结束



ld int [vint_load_process],[in_file_cur_op]
cal int mul [vint_load_process],100
cal int div [vint_load_process],[in_file_file_len]
call [in_file_listener];调用回调函数 在这里返回才是100

out 49,9 ;关闭文件

ret
data in_file_cur_op int 0
data in_file_file_len int 0
data vint_load_process int 0
data in_file_listener int 0
data in_file_offset int 0
;==//=============
[/quote]
彩色代码(用这个编辑器即可
展开帖子列表 [下载][分享]看代码必备工具,高亮     
):
[upload=jpg,in_1.jpg]UploadFile/2010-10/201010301432484521.jpg[/upload]
[upload=jpg,in_2.jpg]UploadFile/2010-10/201010301433931439.jpg[/upload]
这个我就帖一个就好了,那个out那个就不贴了,要是喜欢看这样的效果,下那个编辑器就好了。


out_file:
[quote];==//=======
;r0 开始地址
;r1 结束地址
;r2 监听函数
;r3 文件名
;==//=======
out_file:

ld int [add_begin],r0
ld int [out_file_listener],r2
ld int [out_file_file_len],r1
cal int sub [out_file_file_len],r0
;打开文件
ld int r0,1;打开方式
ld int r1,9;文件号
out 48,0

ld int r0,[add_begin]
out_file_while_begin:;//循环开始
cmp int [out_file_cur_op],[out_file_file_len]
jpc z out_file_while_end:




;指针偏移
ld int r2,9;文件号
ld int r3,[out_file_cur_op]
out 55,16 ;seek

;获取地址下的数据
ld int r3,0
ld byte r3,[r0]
cal int add r0,1
;输出到文件
ld int r1,9;文件号
ld int r2,2147483647;偏移量
out 51,16 ;put

out 0,[out_file_cur_op]

;计算进度,调用监听函数

ld int [vint_put_process],[out_file_cur_op]
cal int mul [vint_put_process],100
cal int div [vint_put_process],[out_file_file_len]
call [out_file_listener];调用回调函数

;指针增量
cal int add [out_file_cur_op],1

jmp out_file_while_begin:

out_file_while_end:;//循环结束



ret
data add_begin int 0
;data add_end int 0
data out_file_cur_op int 0
data out_file_file_len int 0
data vint_put_process int 0
data out_file_listener int 0
;==//======================
[/quote]
上面帖的都是函数主体,一下看到可能还丈二和尚了,那看看我整个例子的完整代码,不要嫌弃我帖代码帖的太多了哈,这些都是没办法的。

先从in_file开始讲讲
[quote]
;这些就是程序主体了
ld int r0,16 ;偏移16,这个是为了给bin文件准备的,当然,你也可以设置为0,那就是从开始读取。
;在这里让我在多说两句,你也可以在读取普通bin文件的时候设置为0,然后全部都读取进buffer(缓存)后,然后偏移
;16字节后在进行call或者你自己的调用
ld int r1,fint_try ;监听函数 每次读取都会调用,其实读取还是很快的。也就是进度
;in_file的进度保存在
[vint_load_process]所以 这个函数访问这个就可以了
;可以实现很炫的东西啊
ld int r2,buffer
;缓存位置 也就是一大块空白的地方,可以是一个bb中的数组 比如 dim a(100) 用 ld int r2,vint_a 也可以的
ld int r3,str
;要打开文件的文件名,注意是地址,也就是指针啦

call in_file

call buffer
out 39,0
exit

;==//=======
;r0 偏移
;r1 监听函数
;r2 缓存地址
;r3 文件名
;==//=======

in_file:
ld int [in_file_cur_op],r0
ld int [in_file_listener],r1
push r2

;打开文件
ld int r0,1;打开方式
ld int r1,9;文件号
out 48,0
;获取文件长度
ld int r3,9;文件号
out 53,0
ld int [in_file_file_len],r3 ;文件长度


pop r0;缓存地址
;遍历
in_file_while_begin:;//循环开始
cmp int [in_file_cur_op],[in_file_file_len]
jpc z in_file_while_end:

;指针偏移
ld int r2,9;文件号
ld int r3,[in_file_cur_op]
out 55,16 ;seek

;读取文件内容
ld int r1,9;文件号
ld int r2,2147483647;偏移量
out 50,16 ;get

;out 0,r0 存放到缓存地址
ld byte [r0],r3
cal int add r0,1

;计算进度,调用监听函数

ld int [vint_load_process],[in_file_cur_op]
cal int mul [vint_load_process],100
cal int div [vint_load_process],[in_file_file_len]
call [in_file_listener];调用回调函数

;指针增量
cal int add [in_file_cur_op],1

jmp in_file_while_begin:

in_file_while_end:;//循环结束

ld int [vint_load_process],[in_file_cur_op]
cal int mul [vint_load_process],100
cal int div [vint_load_process],[in_file_file_len]
call [in_file_listener];调用回调函数 在这里返回才是100

out 49,9 ;关闭文件

ret
data in_file_cur_op int 0
data in_file_file_len int 0
data vint_load_process int 0
data in_file_listener int 0
data in_file_offset int 0
;==//=============

fint_try:;//==监听函数

out 0,[vint_load_process]

ret

buffer:;//===缓存的位置
.block 1000,0

data str int "t.bin",0
[/quote]

看起来也不难吧。这些是基础的,下面再讲讲基础的一个out_file
[quote]jmp end;要注意这个形式,因为这中间才是我要生成的代码,我不能运行,所以先直接jmp
pro_start:
ld int r0,rp;注意,当将这些生成的机器码读取到另一个程序中的时候,绝对位置都不管用了。rp是当前位置,因为上hi寄存器访问
;所以即使到了其他的地方一样能用
ld int r1,main_end
cal int sub r1,pro_start;这里计算出了到main_end的长度
cal int add r0,r1;将rp的相对位置加上了长度才能访问到str1的位置
out 1,r0;输出了str1的内容

ret;因为在其他文件中是用的call,所以要有个ret
main_end:
data str1 int "我的id:a3160586",0
data str2 int "欢迎来到bbk论坛",0

end:



ld int r0,pro_start;//==开始的地址
ld int r1,end;//==结束的地址
ld int r2,call_back;//==监听函数
ld int r3,str;//==保存的文件名
call out_file

exit

;==//=======
;r0 开始地址
;r1 结束地址
;r2 监听函数
;r3 文件名
;==//=======
out_file:

ld int [add_begin],r0
ld int [out_file_listener],r2
ld int [out_file_file_len],r1
cal int sub [out_file_file_len],r0
;打开文件
ld int r0,1;打开方式
ld int r1,9;文件号
out 48,0

ld int r0,[add_begin]
out_file_while_begin:;//循环开始
cmp int [out_file_cur_op],[out_file_file_len]
jpc z out_file_while_end:




;指针偏移
ld int r2,9;文件号
ld int r3,[out_file_cur_op]
out 55,16 ;seek

;获取地址下的数据
ld int r3,0
ld byte r3,[r0]
cal int add r0,1
;输出到文件
ld int r1,9;文件号
ld int r2,2147483647;偏移量
out 51,16 ;put

out 0,[out_file_cur_op]

;计算进度,调用监听函数

ld int [vint_put_process],[out_file_cur_op]
cal int mul [vint_put_process],100
cal int div [vint_put_process],[out_file_file_len]
call [out_file_listener];调用回调函数

;指针增量
cal int add [out_file_cur_op],1

jmp out_file_while_begin:

out_file_while_end:;//循环结束



ret
data add_begin int 0
;data add_end int 0
data out_file_cur_op int 0
data out_file_file_len int 0
data vint_put_process int 0
data out_file_listener int 0
;==//======================

call_back:

out 0,[vint_put_process]

ret

data str int "out.txt",0
[/quote]

这也都是比较简单的实例,待会详细讲讲如何生成一个能用的,代码,虽然这些也能用,但是相比你也看出了很多缺陷。
刚刚那两个例子的代码:
[upload=zip,tie.zip]viewFile.asp?ID=82641[/upload]

[align=right][color=#000066][此贴子已经被作者于2010-10-30 4:15:57编辑过][/color][/align]
发表于2010-10-30 02:26:00
个性签名这个人很懒,什么也没留下!
楼主
沙发

 [quote]详细讲解生成bin,和运行bin[/quote]
主要代码形式如下:
[quote]exit;最主要的就是这里

;main、。,,[/quote]
主要的调用格式如下:
[quote].block 1,0
buffer_top:
jmp main_pro
.block 1000,0
main_pro:
ld int r0,16;下面纠正了这个错误了。
ld int r1,fint_try
ld int r2,buffer
ld int r3,str
[/quote]
原因讲解: 因为我要生成bin的时候是不要运行的,所以一来我就exit,exit的机器码是f0 只有一字节,为了让在生成的bin的访问地址有效,说明一下:
[quote]out 1,a

exit

data a int "我喜欢你吗?",0[/quote]
在这个例子里面,编译后的a会被替换成一个地址,应该是 11(10+1)。要是读取到了其他文件中,位置变了,访问11这个地址便不再是想要的值了。所以这就是我说的需要它访问的地址有效。
而且你们也看到了,偏移哪里是17,避开了exit,从而又让.block 1,0来替上这个位置。使原文中的地址便和读取进入后相契合了。
纠正下,这里可以是16的,因为我竟然忘了bb可以只编译不执行的。大大的失误啊。我开头弄个exit就是为了直接退出就避免执行带来的错误,其实直接编译就可以了。

看看这个简单的例子:
[quote]exit
out 0,rp
out 1,b
out 1,a
ret

data a int "Wener",0
data b int "我的名字是:",0[/quote]
编译生成xxx
[quote].block 1,0
buffer_top:
jmp main_pro
.block 1000,0
main_pro:

ld int r0,17
ld int r1,fint_try
ld int r2,buffer
ld int r3,str

call in_file

call buffer
out 39,0
exit[/quote]
读取,结果如下:
[upload=jpg,test.jpg]UploadFile/2010-10/201010302471112867.jpg[/upload]
[quote]
如何构建自己的dll?[/quote]
其实用dll还是挺好的建议,这样可以让一些不想公开自己源代码的人一样的能公布自己的dll,使用地址作为借口进行访问。
还是用例子来说明吧
[quote]exit;一个dll中的3个函数
fint_myname:
out 1,name
ret
data name int "Wener",0

fint_myfirstlove:
out 1,girl
ret
data girl int "媛",0
;前面一直再举输出的例子,现在说点其他的。

;计算r3的平方
fint_pow:
cal int mul r3,r3
ret
[/quote]
bin倒是生成了,可是我们怎么进行访问那些函数呢?
看生成的bin,虽然位置可以计算出来,但是多麻烦。
[upload=jpg,dll_funces.jpg]UploadFile/2010-10/20101030310228213.jpg[/upload]
[upload=jpg,dll_instance.jpg]UploadFile/2010-10/201010303101937825.jpg[/upload]
我也只能想到这样愚钝的方法了,要是你有什么好的方法来寻找函数地址的话不妨分享下。
我该有个想法,就是在开始弄个这样的函数:
[quote]f_intro:
out 0,func1
out 0,func2
out 0,func3
out 0,func4
;……
ret[/quote]


我想这样就应该简单了吧。直接看就知道是多少了。

[quote]out_file的一些使用方法[/quote]
1。存储动态数据
2。动态查看栈(这个绝的挺有意思的)
3,。制作小机编译器(只是有这个想法,但是应该多难的)
4.…………
各自也可以去发掘的。这个我就不要详细讲了嘛
就说说栈。
栈的开始是栈顶,rs,栈底rb
之间就是栈了。
要是你要想输出栈的话,开始点就是 rb吧,结束为止就是(注意,要最原生态的rs)了
[quote]ld int r1,rs
push 16
push 17
push 1000
push 1314520
push 120
push 438

ld int r0,rb


ld int r2,call_back
ld int r3,str
call out_file[/quote]
结果:
[upload=jpg,zhan.jpg]UploadFile/2010-10/201010303314133228.jpg[/upload]
看了啥感觉呢?
哈哈我都不知道原来栈是这样的,那些个东西都不知道是啥~~~~无语~~
就连16都没找到~~有点扯、。,

[quote]高级扩展[/quote]
加上加密技术的运用,我说说我的思路,现在的确很晚了,可能不写例子了。
从基本的结构上来看,这些都是一跳线的,那我们要是不按照常规,比如说 本来是
123456789
但是我这样
1?2?3?4?5?6?7?8?9
问号不要一样,我们只是在读取的时候将那个指针+2就好了,这是多么的简单。一般这样别人打开你弄的存档的时候基本看起来就会略微吃力了。
要是我们设计一个f(n),来对应这样的关系,那这也基本算是一种简单的加密了,除非某人真的很有功夫和闲心来专门破解你这个,否则还是很难破解的。
在加深一下,我们甚至不安这样的顺序。
比如说我的数据是 123456789
我保存成147258369
这个一看也不是很难吧,就是一个排序的问题。我说说在读取的时候。
1,先将全文读入内存
2,验证(要是有个别数据是你故意留来做验证的,可以验证)
3,从新排序
一样的用一位一位的进行排序。
ld byte
结构加密了,我们还可以用数据上的简单加密。
天狼做出了位运算的。 EXOR(A, B) 异或
那我们就用用基础的异或运算。

(一个数与XX异或)再与XX异或 = 原来数字
xx为你自己的任意密钥

这里要注意的一点,进行异或的时候是4字节数字,所以我们要先将内存中的要异或的加密后然后再次输出。
读取的时候也是全部读取后,再次将那些进行异或。

加密说完了。说说我要在游戏中的运用。

一个人物的信息:
|hp|mp|力量|敏捷|智力|x坐标|经验|技能(此处我打算的是保留10*4的空间,可能有浪费,但是方便计算)|
同样的方法可以构建包裹信息
|id|name|num|

如果是一个很大的map,我可以构建索引
|id|offset|id1|offset1|id2|offset2|………………|name(作为字符串是不定的长度)|ai(一样也是不定的长度)|name|ai|……………………
红线前面的数据结构都是可以计算的,长度都是统一的,offset保存的是红线到特定id的name的距离。由于name可以求字符串长度,所以我只用了一个索引。求出name长度后+offset=ai的地址了。

意思也就是说,我们可以有下面这样的样式
[quote]
item_base:
item_id:
.block 4,0
item_num:
.block 40000,0
…………[/quote]
因此我们可以导入一大部分信息进去。
访问第一个物品就是 item_id,第二个的id就是 item_id+8
这些都是结构化的数据了。
处理起来也非常方便吧。




好了。说到这里也差不多了。
郁闷的是居然4点了,遭感冒了还、。,
恩恩 睡觉了。大家晚安~~~~希望你们喜欢。


[align=right][color=#000066][此贴子已经被作者于2010-11-2 21:53:56编辑过][/color][/align]
发表于2010-10-30 02:27:00
发表
个性签名这个人很懒,什么也没留下!
楼主
2楼

为方便大家在bb上使用:
[quote]VASM(";==//=======")
VASM(";r0 偏移")
VASM(";r1 监听函数")
VASM(";r2 缓存地址")
VASM(";r3 文件名")
VASM(";==//=======")
VASM("")
VASM("in_file:")
VASM("ld int [in_file_cur_op],r0")
VASM("ld int [in_file_listener],r1")
VASM("push r2")
VASM("")
VASM(";打开文件")
VASM("ld int r0,1;打开方式")
VASM("ld int r1,9;文件号")
VASM("out 48,0")
VASM(";获取文件长度")
VASM("ld int r3,9;文件号")
VASM("out 53,0")
VASM("ld int [in_file_file_len],r3 ;文件长度")
VASM("")
VASM("")
VASM("pop r0;缓存地址")
VASM(";遍历")
VASM("in_file_while_begin:;//循环开始")
VASM("cmp int [in_file_cur_op],[in_file_file_len]")
VASM("jpc z in_file_while_end:")
VASM("")
VASM(";指针偏移")
VASM("ld int r2,9;文件号")
VASM("ld int r3,[in_file_cur_op]")
VASM("out 55,16 ;seek")
VASM("")
VASM(";读取文件内容")
VASM("ld int r1,9;文件号")
VASM("ld int r2,2147483647;偏移量")
VASM("out 50,16 ;get")
VASM("")
VASM(";out 0,r0 存放到缓存地址")
VASM("ld byte [r0],r3")
VASM("cal int add r0,1")
VASM("")
VASM(";计算进度,调用监听函数")
VASM("")
VASM("ld int [vint_load_process],[in_file_cur_op]")
VASM("cal int mul [vint_load_process],100")
VASM("cal int div [vint_load_process],[in_file_file_len]")
VASM("call [in_file_listener];调用回调函数")
VASM("")
VASM(";指针增量")
VASM("cal int add [in_file_cur_op],1")
VASM("")
VASM("jmp in_file_while_begin:")
VASM("")
VASM("in_file_while_end:;//循环结束")
VASM("")
VASM("ld int [vint_load_process],[in_file_cur_op]")
VASM("cal int mul [vint_load_process],100")
VASM("cal int div [vint_load_process],[in_file_file_len]")
VASM("call [in_file_listener];调用回调函数 在这里返回才是100")
VASM("")
VASM("out 49,9 ;关闭文件")
VASM("")
VASM("ret")
VASM("data in_file_cur_op int 0")
VASM("data in_file_file_len int 0")
VASM("data vint_load_process int 0")
VASM("data in_file_listener int 0")
VASM("data in_file_offset int 0")
VASM(";==//=============")
VASM("")
VASM(";==//=======")
VASM(";r0 开始地址")
VASM(";r1 结束地址")
VASM(";r2 监听函数")
VASM(";r3 文件名")
VASM(";==//=======")
VASM("out_file:")
VASM("")
VASM("ld int [add_begin],r0")
VASM("ld int [out_file_listener],r2")
VASM("ld int [out_file_file_len],r1")
VASM("cal int sub [out_file_file_len],r0")
VASM(";打开文件")
VASM("ld int r0,1;打开方式")
VASM("ld int r1,9;文件号")
VASM("out 48,0")
VASM("")
VASM("ld int r0,[add_begin]")
VASM("out_file_while_begin:;//循环开始")
VASM("cmp int [out_file_cur_op],[out_file_file_len]")
VASM("jpc z out_file_while_end:")
VASM("")
VASM("")
VASM("")
VASM("")
VASM(";指针偏移")
VASM("ld int r2,9;文件号")
VASM("ld int r3,[out_file_cur_op]")
VASM("out 55,16 ;seek")
VASM("")
VASM(";获取地址下的数据")
VASM("ld int r3,0")
VASM("ld byte r3,[r0]")
VASM("cal int add r0,1")
VASM(";输出到文件")
VASM("ld int r1,9;文件号")
VASM("ld int r2,2147483647;偏移量")
VASM("out 51,16 ;put")
VASM("")
VASM(";out 0,[out_file_cur_op]")
VASM("")
VASM(";计算进度,调用监听函数")
VASM("")
VASM("ld int [vint_put_process],[out_file_cur_op]")
VASM("cal int mul [vint_put_process],100")
VASM("cal int div [vint_put_process],[out_file_file_len]")
VASM("call [out_file_listener];调用回调函数")
VASM("")
VASM(";指针增量")
VASM("cal int add [out_file_cur_op],1")
VASM("")
VASM("jmp out_file_while_begin:")
VASM("")
VASM("out_file_while_end:;//循环结束")
VASM("")
VASM("")
VASM("")
VASM("ret")
VASM("data add_begin int 0")
VASM(";data add_end int 0")
VASM("data out_file_cur_op int 0")
VASM("data out_file_file_len int 0")
VASM("data vint_put_process int 0")
VASM("data out_file_listener int 0")
VASM(";==//======================")
VASM("")[/quote] [align=right][color=#000066][此贴子已经被作者于2010-10-30 3:59:39编辑过][/color][/align]
发表于2010-10-30 02:27:00
发表
个性签名这个人很懒,什么也没留下!
3楼

 我没有沙发。。。表示幽怨。。。
发表于2010-10-30 02:41:00
发表
个性签名这个人很懒,什么也没留下!
4楼

都发展到dll了。。。。

发表于2010-10-30 07:59:00
发表
个性签名这个人很懒,什么也没留下!
5楼

[quote]get #1,a

vasm("ld int [buffer],[vint_a]")'将a的值放到缓存下面

这样是必死无疑的。因为bb读文件的时候都是低位在前高位在后的,好像叫这个。比如一个数字[/quote]

 

不会吧,数值在内存中和文件中的顺序都是低位在前高位在后的吧。

发表于2010-10-30 11:59:00
发表
个性签名这个人很懒,什么也没留下!
6楼

[quote]ld int r3,str
;要打开文件的文件名,注意是地址,也就是指针啦
[/quote]

 

不要误导了,我们通常是说指针指向某个地址。还有,这里貌似是要使用句柄。这又和指针不一样了。

发表于2010-10-30 12:25:00
发表
个性签名这个人很懒,什么也没留下!
7楼

以下是引用Lux在2010-10-30 12:25:00的发言:

 

不要误导了,我们通常是说指针指向某个地址。还有,这里貌似是要使用句柄。这又和指针不一样了。

汗死。。。那么变量岂不就是一个指针了?

发表于2010-10-30 14:07:00
发表
个性签名这个人很懒,什么也没留下!
8楼

以下是引用Lux在2010-10-30 11:59:00的发言:

 

不会吧,数值在内存中和文件中的顺序都是低位在前高位在后的吧。

。。。。几进制这样表示数据。。。。。既不方便,也不实用。。作者没那么无聊。。。

发表于2010-10-30 14:11:00
发表
个性签名这个人很懒,什么也没留下!
9楼

/* 每个DLL文件应该包含的代码 */

asm{
;====================================
; r0 函数表地址(用于计算)
; r1 DLL基址
; r3 函数表地址(用于返回)
;====================================

xdll_init:
 ld int r1, rp  ; 加载DLL基址
 ld int r0, r1
 cal int add r0, ftab ; 计算函数列表的绝对地址
 
 ; 载入函数信息
 ld int [r0], function_1 ; 载入相对地址
 cal int add [r0], r1 ; 计算函数的绝对地址
 cal int add r0, 4 ; 后移指针
 
 ;....
 
 ld int [r0], function_n
 cal int add [r0], r1
 
 ld int r3, ftab
 
 ret
 ftab:   ; 这个表的大小应该等于导出函数个数×4
 .block 64,0
;xdll_init_exit
}

function function_x(a, b$)

end function

/* 给用户使用的引导文件 */
/* 在调用了 xdll_init 后获得一个数据,假设存在 _pos 中 */

function function_x(a, b$) ' b|a
 asm{
 ld int r3,rs
 cal int add r3,16 ; 获得参数地址 ->b
 ld int r0, vint__pos
 ; 计算该函数在表中的位置
 ld int r1, x  ; x 是序号
 cal int mul r1, 4
 cal int add r1, r0
 ld int r0, [r0]  ; 获得函数地址
 ; 压入参数
 push [r3]  ; b$
 cal int add r3, 4
 push [r3]  ; a
 ; 调用函数
 call r0
 }
end function

 

 

 

仅是理论,没有测试,特别是压入参数那部分。

发表于2010-10-30 14:14:00
发表
个性签名这个人很懒,什么也没留下!
  • 1
  • 2
  • ...
  • 3
  • 4
  • 下一页
  • 尾页
  • 37回复 共 4页 跳转到 确定