易码技术论坛

 找回密码
 加入易码
搜索
查看: 414405|回复: 10

[原创][再议LavaX的动态内存使用]

[复制链接]
发表于 2006-11-18 23:18:54 | 显示全部楼层
不错
从Lavo开始,已经直接支持了malloc和free
 楼主| 发表于 2006-11-19 10:42:26 | 显示全部楼层
呵呵,程序实现无法跟底层编程比.
现在困难的是难以方便的实现内存的整理,因为这需要改变被赋指针的值,所以我也只能以记录地址的方法实现内存整理,但是这样就限制了指针的灵活性......
发表于 2006-11-19 11:17:20 | 显示全部楼层
malloc和free还是很重要的,所以从Lavo起开始有malloc和free函数了
但是由于LavaX1.0的机器内存太小,速度也慢,使用malloc和free的开销较大,而得到的提升不明显,所以最终没有在LavaX1.0上实现malloc和free
发表于 2006-11-20 10:31:21 | 显示全部楼层
关键是,语言底层如何支持动态内存~
认为LavaX架构本来就有问题,伪代码包括指令集,限制了函数库的开发,而且还没有动态指令,只是一些宏。
Lee你没发现你的Laro一点实用性都没有吗?除了在比较成熟的GBA上登陆了你的Laro到底在哪里实现了?现在就算你不想和某厂家合作也要考虑一下你的语言的“销路”吧?
发表于 2006-11-20 10:45:00 | 显示全部楼层
看不惯就一边待着去!
Lavo好不好用不是你说了算的!!!
发表于 2006-11-20 10:53:02 | 显示全部楼层
LavaX和Lavo都不是c,不要用c的眼光看待。
Lvc则兼容ansi c。
无论LavaX,Lavo还是Lvc,各有适用范围,看用户的需要了。
发表于 2006-11-21 18:45:18 | 显示全部楼层
我并没说LavaX和Laro不好啊
LavaX的实用性是很强的,广大星迷已经证实这一点了,但是Laro语言没有适用的群体(或者说有适用群体但是因为非技术因素无法实现)这也是Laro编程大赛失败的原因。我也很看好Lvc语言。虽然现在的编译技术很先进,但是基于RISC的语言还是很重要的,我并没有诬蔑你的劳动成果。
一个语言有它的适用范围,但是并不强烈,Lee你喜欢C也是因为C虽然长于系统编程但是也十分灵活,同样适于其它种类的应用吧?难道你的语言不能做到这一点吗?最好的是你可以将一种语言(现在是ANSI C)编译成各种不同的目标代码,这样使语言编写本身的差异减到最小,而生成的伪代码也有了自己的适用范围,这才是最好的。将一种语言(虽然有不同适用的目标代码)命名为几个不同的名字(如LavaX,Laro,Lvc)是不明智的。
Lee现在的编译技术已经十分成熟,LavaX语言也经过了大家的考验,Lee也应该不甘于做一个简单的程序员,所以希望Lee能有更多的商业头脑,不要高傲地等待别人地垂青(比如有偿开放,个人不赞成这种编译器代码地开放,因为语言本身是不应该被修改地,语言是一种标准,要修改也是修改语言生成地伪代码),Lee应该主动去宣传,推销你的语言,最好销售的是定制前端为ANSI C的编译器的服务,这样才会有前途,厂商也会认识到这种IDE的价值,这样Lee也不需要去销售语言来解决经济问题了。
作为星迷的一员,StarWing无意打击或讽刺诬蔑Lee及Lee的劳动成果,StarWing只希望Lee可以有更大的发展,毕竟有更多更实用的编程环境对所有星迷都是好事。在此基础上即使是谋利大家都不会拒绝的。希望Lee摆正自己的位置:Lee是一个非常有前途,非常有技术头脑的程序员。但是,Lee也需要一些商业头脑这些虽然不一定是以星迷的利益为目的的(毕竟我们写程序都是无偿的),但是希望Lee可以尽量为星迷着想。
Lee你已经加了我,希望有时间我们可以好好聊聊,当然,要是你时间有限就算了~
发表于 2006-11-21 19:06:26 | 显示全部楼层
Lavo是LavaX的加强版(但不是升级版,因为不兼容),二者都是作为无类型语言,再发展也不会脱离这一目标
Lvc是ansi c兼容的跨平台c,当然是有类型语言,其发展是要遵循ansi c的,不会扩展非ansi c兼容的内容,因此主要是完善函数库。当然,目前还是侧重语法测试,等稳定了再进一步发展
关于这些语言的发展完善欢迎提建议,至于推广问题,我心里有数
发表于 2006-11-21 19:09:53 | 显示全部楼层
还有,是Lavo语言,没有Laro一说
发表于 2006-12-20 20:38:49 | 显示全部楼层
嘎嘎,我顶!!!!!!!!!!!!!!!!!!11
 楼主| 发表于 2006-11-18 22:59:17 | 显示全部楼层 |阅读模式

以前发过一个贴可以改变函数的内存大小,但是没有真正实现内存的动态使用.
但是这次不同了.

下面的程序以操作LavaX中额外的内存的方法实现了内存的动态分配,
对于程序的书写,以易读为主,没有针对速度做什么优化.
程序中各函数功能:
getsize,返回对应内存块的大小
arrangeram,整理内存,清理未使用的内存块
free,释放内存块,基本上只是将内存块标记为未使用
malloc,分配内存块

以下是程序代码:

/*
RAM:
0x2000:
[变量/函数头 内存]
.
.
.
[动态RAM]
*/


/*
动态RAM:

┏━ListEnd ┏>> NULL
┃           ┗━┓
┃   [空闲内存]  ┃
┗> [next      ]━┛<┓
┏━[last        ]  ┏━┛
┃  [used = F]  ┃
┃  [size        ]  ┃
┃  [used ram]  ┃
┃                ┃
┃  [已用内存]    ┃
┗> [next      ]━┛<┓
┏━[last        ]  ┏━┛
┃  [used = T]  ┃
┃  [size      ]  ┃
┃  [used ram]  ┃
┃              ┃
┃  [空闲内存]   ┃
┗> [next      ]━┛<┓
┏━[last      ]  ┏━┛
┃  [used = F]  ┃
┃  [size      ]  ┃
┃  [used ram]  ┃
┃                ┃
┃  ListHead━━┛
┗>ADD_MAX
*/

#define ADD_MAX 0x7fff   //解释器能使用的最大内存地址
int ListHead = ADD_MAX;
int ListEnd = ADD_MAX;
struct INFO
{
   int next;   //下一块内存地址
   int last;   //上一块内存地址
   int pointadd;//被返回指针的地址
   char used;   //是否空闲
   int size;   //大小
};
long getsize( long point)   //取得内存块的大小
//point:指针
{
   struct INFO &info;
   &info = point - sizeof( struct INFO);
   return info.size;
}
void arrangeram()   //整理内存
{
   int maxadd;
   int pointadd;
   int next;
   struct INFO &info;
   struct INFO &lastornext;
   maxadd = ADD_MAX;
   if( ListHead != ListEnd)//说明已有开辟的内存
   {
      &info = ListHead;
      while( &info)
      {
        next = info.next;
        if( info.used)   //如果内存块已使用则移动到新地址,否则忽略
        {
           pointadd = info.pointadd;
           (int *)pointadd = maxadd - info.size;
           &lastornext = maxadd;
           info.last = maxadd;
           if( maxadd == ADD_MAX)
           {
              ListHead = ( maxadd = maxadd - info.size - sizeof( struct INFO));
           }
           else
           {
              maxadd = maxadd - info.size - sizeof( struct INFO);
              lastornext.next = maxadd;
           }
           memmove( maxadd, &info, info.size + sizeof( struct INFO));
        }
        &info = next;
      }
      &info = maxadd;
      info.next = 0;
   }
   ListEnd = maxadd;
}
void free( addr point)   //释放内存(一般情况下只是标记为&#39;未使用&#39;)
{
   struct INFO &info;
   struct INFO &lastornext;
   &info = point - sizeof( struct INFO);
   if( info.next == NULL)//判断是否为最后一块内存
   {
      //清除内存块节点
      //重置链表尾信息
      ListEnd = info.last;
      //重置链表尾
      &lastornext = ListEnd;
      lastornext.next = NULL;
   }
   else
   {
      info.used = FALSE;
   }
   //arrangeram();//这里可以一释放就整理内存
}
addr malloc( long R_SIZE, long pointadd)//分配内存,返回被分配的内存地址
//R_size:要分配的内存大小(实际要比R_SIZE大一点)
//pointadd:被分配内存返回的地址所要保存的指针地址

{
   int lastadd;   //暂存一下地址
   struct INFO &info;
   struct INFO &lastornext;
   char test;
   //寻找现有空闲内存
   if( ListHead != ListEnd)   //说明有已开辟的内存
   {
      &info = ListHead;
      while( &info)
      {
        if( info.used == FALSE && info.size >= R_SIZE)
        {
           //未使用的内存块,且容量足够,多出的空间被设置为新的空闲内存
           if( info.size - R_SIZE > sizeof( struct INFO))   //有足够的多余空间设置新的空闲内存
           {
              //添加节点
              lastadd = &info + R_SIZE + sizeof( struct INFO);
              if( info.last != ADD_MAX)
              {
                &lastornext = info.last;
                lastornext.next = lastadd;
                ListHead = lastadd;
              }
              &lastornext = lastadd;
              lastornext.next = &info;
              lastornext.last = info.last;
              info.last = lastadd;
              //设置信息
              info.size = R_SIZE;
              lastornext.size = info.size - R_SIZE - sizeof( struct INFO);
              lastornext.used = FALSE;
           }
           info.pointadd = pointadd;
           info.used = TRUE;
           return &info + sizeof( struct INFO);
        }
        &info = info.next;
      }
   }
   //开辟新内存
   if( &test + R_SIZE + sizeof( struct INFO) >= ListEnd)
   {
      arrangeram();   //自动整理内存
      if( &test + R_SIZE + sizeof( struct INFO) >= ListEnd)
      {
        printf("内存不足!");
        getchar();
        exit(0);
      }
   }
   //保留上一个内存块的地址
   lastadd = ListEnd;
   if( ListEnd < ADD_MAX)
   {
      //修改上一个内存块的next地址
      &lastornext = ListEnd;
      lastornext.next = ListEnd - R_SIZE - sizeof( struct INFO);
      //修改内存使用的最大位置
      ListEnd = lastornext.next;
   }
   else
   {
      ListEnd = ListEnd - R_SIZE - sizeof( struct INFO);
   }
   //取得内存块信息的地址
   &info = ListEnd;
   //记录上一个内存块的地址
   info.last = lastadd;
   //表示链表结尾
   info.next = NULL;
   //记录内存块大小信息
   info.size = R_SIZE;
   //标记已经在使用
   info.used = TRUE;
   //记录存放指针值的地址
   info.pointadd = pointadd;
   if( info.last == ADD_MAX)
   {
      ListHead = ListEnd;
   }
   (int *)pointadd = &info + sizeof( struct INFO);
   return &info + sizeof( struct INFO);
}
void main(){
   int a,b;
   SetScreen(1);
   printf("分配后:\n");
   malloc(0x1000, &a);
   malloc(0x2000, &b);
   printf("a = %d,size = %d\n",a,getsize(a));
   printf("b = %d,size = %d\n",b,getsize(b));
   free(a);
   malloc(0x800, &a);
   arrangeram();
   printf("释放a,分配a,整理后:\n");
   printf("a = %d,size = %d\n",a,getsize(a));
   printf("b = %d,size = %d",b,getsize(b));
}



真是晕!
似乎字宽总是有问题,编辑了N次也不行,凑合着看吧~~
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

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

GMT+8, 2024-3-29 22:08 , Processed in 0.012818 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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