Board logo

标题: [求助]关于djgpp的保护模式? [打印本页]

作者: forzhanghua     时间: 2003-9-26 00:00    标题: [求助]关于djgpp的保护模式?
我是一个djgpp的初级学习者,所有的介绍都突出它一次可以访问4G的空间,我觉得它的语法和c差不多,可是我以前在c下编程时分配内存是通过数组或是指针的,那么在djgpp里,应该怎么样来访问这么大的地址空间呢?
我看出错后,dj报告有段地址和偏移量,这些东西是怎么设置的呢?
请高手指点!谢谢

作者: ATLaS     时间: 2003-9-26 00:00
应该用sys/farptr.h中的_far*系列函数来访问内存。以下函数原型来自djgpp v2.0x的libc帮助文档。

#include

unsigned char _farpeekb(unsigned short selector, unsigned long offset);
unsigned short _farpeekw(unsigned short selector, unsigned long offset);
unsigned long _farpeekl(unsigned short selector, unsigned long offset);

void _farpokeb(unsigned short sel, unsigned long off, unsigned char val);
void _farpokew(unsigned short sel, unsigned long off, unsigned short val);
void _farpokel(unsigned short sel, unsigned long off, unsigned long val);

void _farsetsel(unsigned short selector);
unsigned short _fargetsel(void);

void _farnspokeb(unsigned long offset, unsigned char value);
void _farnspokew(unsigned long offset, unsigned short value);
void _farnspokel(unsigned long offset, unsigned long value);

unsigned char _farnspeekb(unsigned long offset);
unsigned short _farnspeekw(unsigned long offset);
unsigned long _farnspeekl(unsigned long offset);

假定你要访问的内存地址为:
unsigned long ulAddr = 0x0000a000;
用_farpokeb(_dos_ds, ulAddr, byte)来写一个byte,用_farpeekb()来读一个byte。_dos_ds是系统预定义值,直接用就行了。
如果要连续访问内存地址区间, 则可以:
unsigned int i, wLen = 0x1000;
_farsetsel(_dos_ds);
for (i = 0; i < wLen; i++) {
printf("0x%02hX\t", _farnpeekb(ulAddr + i);
}

ps: 建议认真阅读djgpp faq,如果这样的问题你问在djpp的邮件列表里,他们只会回答你faq 10.2或者18.x。



作者: lemonhall     时间: 2003-9-28 00:00
恩,你原来在C里的做法是怎么样的呢??

使用MALLOC和FREE函数来分配内存的吧?相信你是这样做的。

那么现在继续使用它们吧,它们将还是你的老朋友。

指针么,DJGPP没有抛弃C语言的指针概念哦。

但是要注意,这里是C语言的指针概念,而不是TC等实现的概念。
(当然,所有语言总是或多或少地依赖与实现的)

所以说,你还是可以使用“C语言的指针”

===================================================
那么什么是保护模式呢?

它其实是一种编程的进化,是又一次抽象(ABSTRACT)。

它将80386以上机器的内存调用机制做了一次抽象,让无数程序员从繁重的内存访问机制
(底层的枷锁中)解放了出来。

从而,恭喜你。你可以用抽象过的方法访问4G内存了,而不是使用繁复的内存分页访问技术
(事实上是不行的,因为在DOS7。1下也不过能使用2G,WINXP系列中4G可访问,
但是有一半是留给系统的)

====================================================

那么,你怎么访问这些内存呢。很简单:

使用MALLOC函数,分配一个2G的内存块给一个指针吧。
(当然,你的机器不会有那么大的内存的,所以,请先试试20M这类在以前看来不可想象
的大数字)

请注意:这里的指针和你以前使用的指针,有一个区别了。

那就是,没有远近之分。(FAR MALLOC和FAR FREE这类的东西再也不需要了)
这样,你的这个指针就可以直接映射到你的内存上去,而不需要在乎什么640K,1M
这类的枷锁了。

还等什么,去尝试一下吧!





===============================================

另外,还有一个技术细节,就是:

通过MALLOC函数分配完成后,请不要试图使用 MEM等类似的函数去查看内存的剩余量
,尽管你分配了20M或更多,但是实际上它们并没有被初始化(其实不是这样的,只是
我这样讲,大家都好理解),只有当你真正写入20M内容后,它们才真正地被分配使用了。

通俗地讲,使用MALLOC调用大内存后,再使用MEM这类函数查看内存分配情况将不会看到
任何变化。这和以前使用TC时可是大不一样了(真不知道他们是怎么想的,晕)


完成于2003/09/26

作者: lemonhall     时间: 2003-9-28 00:00
ATLaS
看得出来,你对DJGPP等编程是有功底的,有没有兴趣加入我的小组。

参与DJGPP的中文化工作,我们现在正在编写中文化的DJGPP FAQ和
DJGPP的用户指南(一个是翻译,一个是完全重写)

有兴趣的话,回个帖子哦。

作者: ATLaS     时间: 2003-9-29 00:00
to lemonhall:
呵呵,可以啊!前段时间的确研究了一下djgpp,本来有个project打算在djgpp下做,但因为多线程的问题,加上进度要求,还是改回watcom c了。不过对djgpp的兴趣一直比较大。
有什么具体的工作我可以帮忙的吗(因为工作的缘故,可能进度会慢些,呵呵)?

作者: lemonhall     时间: 2003-9-29 00:00
具体工作就是写一个DJGPP的使用指南,你对内存和保护模式比较熟悉,所以你能负责那部分的编写么?
写个初稿看看吧.发到我信箱里
lemonhall@vip.sina.com

我做的网站,换地址啦: http://lemonhall.533.net/ 去看看,最近没什么更新.

作者: ATLaS     时间: 2003-9-29 00:00
这些部分在faq中的解释还算比较清楚吧?那我试试看用一些小例子来说明djgpp下和borland c/watcom c下的不同?可以包括外部中断部分,如何?不过拜托不要催我进度,工作上的活儿也很多。<img src="images/smilies/face-raspberry.png" align="absmiddle" border="0">

我的email是atlas_wang@hotmail.com。

作者: lemonhall     时间: 2003-9-30 00:00
对,就是用小文章来说明。 需要和FAQ里有所不同,谢谢啦