Board logo

标题: 请教:dos操作系统下的程序如何使用扩展内存 (急) [打印本页]

作者: limelm     时间: 2003-11-21 00:00    标题: 请教:dos操作系统下的程序如何使用扩展内存 (急)

小弟做嵌入式系统的开发,使用PC104板,CPU为486,内存16M,操作系统为DOS。现在编了一C程序,里面用到动态分配内存空间函数MALLOC用于存储数据,本打算存储10000个数据点,可是由于内存原因,只能存促4000个数据,同时farmalloc函数无法使用,请问各位大侠如何解决这一问题。
作者: GhostJ     时间: 2003-12-4 00:00
可以進到保護模式嗎
作者: hhmmdd     时间: 2004-3-1 00:00
#ifndef XMSMEM_H
#define XMSMEM_H

#include
#include

typedef int                 BOOL;
#define FALSE               0
#define TRUE                1

//-------- XMS class function prototype ---------
class CXMSManager
{
    friend class CXMSBlock;
   
    struct XMSMOVE {
        unsigned long length;
        unsigned int  s_handle;
        unsigned long s_offset;
        unsigned int  d_handle;
        unsigned long d_offset;
    };
   
    BOOL initialize();
    BOOL transfer(XMSMOVE*);
    unsigned alloc(unsigned nKB);
        void free(unsigned handle);
   
public:
    CXMSManager();
    ~CXMSManager();
   
    unsigned Version();
    unsigned TotalKB();
    unsigned FreeKB();
};

extern CXMSManager XMSManager;
//---------------------------------------------------------------------
class CXMSBlock
{
        unsigned Handle;
        unsigned nKB;
       
public:
        CXMSBlock();
        CXMSBlock(unsigned nKB);
        ~CXMSBlock();
               
        BOOL alloc(unsigned nKB);
        void free();
        unsigned getKB() { return nKB; }
       
        BOOL input(char far *buf, unsigned long offset, unsigned long len);  //len must not be odd?
        BOOL output(char far *buf, unsigned long offset, unsigned long len); //len must be even?
       
        BOOL input(CXMSBlock *mem, unsigned long offset1, unsigned long offset, unsigned long len);
        BOOL output(CXMSBlock *mem, unsigned long offset1, unsigned long offset, unsigned long len);
       
        BOOL loadFile(const char *fname, unsigned long from, unsigned long length);
};

#endif
作者: hhmmdd     时间: 2004-3-1 00:00
#include "XMSMEM.H"

CXMSManager XMSManager;

static void far (*XMSVector)() = NULL;

CXMSManager::CXMSManager()
{
    initialize();
}

CXMSManager::~CXMSManager()
{
}

BOOL CXMSManager::initialize()
{
        union REGS r;
        struct SREGS sr;
        r.x.ax = 0x4300;
        int86(0x2f,&r,&r);
        if(r.h.al != 0x80)
        {
            XMSVector = NULL;
            return FALSE;
        }
       
        r.x.ax = 0x4310;
        int86x(0x2f,&r,&r,&sr);
        XMSVector = (void far (*)())MK_FP(sr.es, r.x.bx);
        return TRUE;
}

unsigned CXMSManager::Version()
{
        if(XMSVector == NULL) return 0;
       
        asm {
                MOV AX,0
                CALL XMSVector
        }
        return _AX;
}

unsigned CXMSManager::TotalKB()
{
        if(XMSVector == NULL) return 0;
       
        asm {
                MOV AH,8
                CALL XMSVector
        }
        if(_BL>=0X80 && _BL=0X80 && _BLnKB = nKB, TRUE) : (this->nKB = 0 , FALSE);
}

void CXMSBlock::free()
{
    XMSManager.free(Handle);
    Handle = 0;
    nKB = 0;
}

BOOL CXMSBlock::input(char far *buf, unsigned long offset, unsigned long len)
{
        struct CXMSManager::XMSMOVE xms = {len, 0, (unsigned long)buf, Handle, offset};
        return XMSManager.transfer(&xms);
}

BOOL CXMSBlock:utput(char far *buf, unsigned long offset, unsigned long len)
{
        struct CXMSManager::XMSMOVE xms = {len, Handle, offset, 0, (unsigned long)buf};
        return XMSManager.transfer(&xms);
}

BOOL CXMSBlock::input(CXMSBlock *mem, unsigned long offset1, unsigned long offset, unsigned long len)
{
        struct CXMSManager::XMSMOVE xms = {len, mem->Handle, offset1, Handle, offset};
        return XMSManager.transfer(&xms);
}

BOOL CXMSBlock:utput(CXMSBlock *mem, unsigned long offset1, unsigned long offset, unsigned long len)
{
        struct CXMSManager::XMSMOVE xms = {len, Handle, offset, mem->Handle, offset1};
        return XMSManager.transfer(&xms);
}

BOOL CXMSBlock::loadFile(const char *filename, unsigned long from, unsigned long length)
{
    FILE *fp = fopen(filename, "rb";
        if(fp == NULL) return FALSE;

        fseek(fp, 0L, SEEK_END);       
        long filelen = ftell(fp);
        if(filelen = length || result < 1024) break;
        }
       
        fclose(fp);
        return TRUE;
}
作者: 凌晨一点     时间: 2004-3-3 00:00
楼上的,人家要的是基于C的,你怎么给了个C++的啊?
作者: 蓝蓝冷月     时间: 2004-4-9 00:00
我也想过这个问题,只是我会的是quickbasic.解决的方法是,借助硬盘或虚拟内存,把大量的数组写成数据文件, 写两个子程序,一个读文件,一个写文件,这样就可以实现大数组.
作者: cdl     时间: 2004-4-11 00:00
可以通过以下两种方式使用
1、进入保护模式修改段大小属性好退出实模式。可用到4G内存
2、同过加载himem.sys或emm386.exe来使用
这两种方式我都用过,第一种是个技巧第二种是常用方法。如果需要我把源代码给你
作者: alhan     时间: 2004-5-12 00:00
能否给我发一份,
我知道用EMS(就是你说的himeme.sys和emm386)可以用到16M,

>1、进入保护模式修改段大小属性好退出实模式。可用到4G内存
能否给我发一份源代码。谢谢!

alhanhome@21cn.com


作者: boblhh9999     时间: 2004-5-14 00:00
XMS或EMS都是将扩展内存影射到基本内存的某一特定地址段,
如果你的程序不加修改还是无法使用扩展内存
作者: psjboy     时间: 2004-5-20 00:00
能否也发给我一份,谢谢
psjboy@tom.com
作者: victor     时间: 2004-5-20 00:00
hhmmdd的 程序通过稍加修改就可以访问 4G 的内存, 里面少了判断扩展功能了
如果检查XMS版本不低于3需要用功能号 8 和 9 的扩展功能号 88H 和 89H
作者: tiger205     时间: 2004-5-23 00:00
2、同过加载himem.sys或emm386.exe来使用256m内存,
的源代码么?
能否发一个给我?
tiger205@163.net
作者: victor     时间: 2004-5-24 00:00
这个程序只需要 himem.sys, 与 emm386.exe 无关, 可访问所有的内存 (4G)

// --- xms.h

#ifndef _Head_XMS_H_
#define _Head_XMS_H_

#ifndef FarPtr
  #define FarPtr(seg,ofs)  ((void _seg *)(seg) + (void near *)(ofs))
  #define GetSeg(p)        ((unsigned)(void _seg *)(void far *)(p))
  #define GetOfs(p)        ((unsigned)(p))
#endif

class far TXmsMem
{
public:
  typedef struct
   {
     unsigned long Size;          //must be EVEN number
              int  SourHandle;    //0: Conventional Memory
     unsigned long SourOffset;    //Offset/Conv. Mem. Address
              int  DestHandle;    //0: Conventional memory
     unsigned long DestOffset;    //Offset/Conv. Mem. Address
   }XMMStrcut;

  int far DriverAvailable(void); //return true if xms driver installed
  int far ExtendedVersion(void); //return true if > 64M memory supported

  unsigned far GetVersion(void); //return BCD XMS Version
  unsigned far GetRevision(void); //return BCD XMS Driver Revision
  unsigned long far GetBlockFreeXMS(void); //(kb) ErrCode -> _XMS_Err
  unsigned long far GetTotalFreeXMS(void); //(kb) ErrCode -> _XMS_Err

  int far AllocXMS(int far *XMSHandle, unsigned long kbyte); //(kb) 0:error, ErrCode -> _XMS_Err
  int far FreeXMS(int XMSHandle); //0:error, ErrCode -> _XMS_Err

  //Size must be an EVEN number
  //return 0 -> Error, ErrCode -> _XMS_Err
  int far MemCpy(int hD, unsigned long oD, int hS, unsigned long oS, unsigned long Size);

  int far LockXMSBlock(int Handle, long *Addr);
  int far UnLockXMSBlock(int Handle);

  far TXmsMem();

private:
  static void far (*_XMS_Proc)(void);
  static unsigned far _XMS_Version;
  int far fXMSDriverInstalled(void);
  void far fInitXMSProc(void);
};
extern TXmsMem far xms;

#endif


//--- xms.cpp


#include "xms.h"

void far (*TXmsMem::_XMS_Proc)(void) = 0;
unsigned far TXmsMem::_XMS_Version = 0x0000;
TXmsMem far xms;

far TXmsMem::TXmsMem()
{
  if(!DriverAvailable())
   {
     if(fXMSDriverInstalled())
       fInitXMSProc();
     if(DriverAvailable())
       _XMS_Version=GetVersion();
   }
}

int far TXmsMem:riverAvailable(void)
{
   return _XMS_Proc!=0;
}

int far TXmsMem::ExtendedVersion(void)
{
   return _XMS_Version>=0x0300;
}

int far TXmsMem::fXMSDriverInstalled(void) //called only in XMS.CPP, not a public proc.
{
   asm mov ax,0x4300
   asm int 0x2f
   return _AL==0x80;
}

void far TXmsMem::fInitXMSProc(void)
{
   unsigned int Sgmt,Ofst;
   asm mov ax,0x4310
   asm int 0x2f
   asm mov Ofst,bx
   asm mov bx,es
   asm mov Sgmt,bx
   _XMS_Proc=(void far(*)(void)) FarPtr(Sgmt,Ofst);
}

unsigned far TXmsMem::GetVersion(void)
{
   asm xor ah,ah
   _XMS_Proc();
   return _AX;
}

unsigned far TXmsMem::GetRevision(void)
{
   asm xor ah,ah
   _XMS_Proc();
   return _BX;
}

unsigned long far TXmsMem::GetBlockFreeXMS(void) //return Size (kb); if Error, ErrCode -> _XMS_Err
{
   if(ExtendedVersion())
    {
      unsigned FreeHi, FreeLo;
      asm mov ah, 0x88
      asm xor bl, bl
      _XMS_Proc();
      asm mov FreeLo, ax         //OPSIZ:
      asm db 0x66,0xc1,0xe8,0x10 //SHR EAX 10H
      asm mov FreeHi, ax
      return ((long)FreeHi< _XMS_Err
{
   if(ExtendedVersion())
    {
      unsigned FreeHi, FreeLo;
      asm mov ah, 0x88
      asm xor bl, bl
      _XMS_Proc();
      asm mov FreeLo, dx         //OPSIZ:
      asm db 0x66,0xc1,0xea,0x10 //SHR EDX 10H
      asm mov FreeHi, dx
      return ((long)FreeHi< Success, 0 -> Error, ErrCode -> _XMS_Err
{
   int Handle, AllocErr;
   unsigned kbhi = kbyte>>16;
   unsigned kblo = kbyte&0x0000ffff;

   if(ExtendedVersion())
    {
      asm mov ah, 0x89
      asm mov dx, kbhi           //OPSIZ:
      asm db 0x66,0xc1,0xe2,0x10 //SHL EDX, 10H
      asm mov dx, kblo
      _XMS_Proc();
      asm mov AllocErr,ax
      //asm mov _XMS_Err,bl
      asm mov Handle,dx
      *XMSHandle=Handle;
      return AllocErr;
    }
   else
    {
      asm mov ah, 9
      asm mov dx, kblo
      _XMS_Proc();
      asm mov AllocErr,ax
      //asm mov _XMS_Err,bl
      asm mov Handle,dx
      *XMSHandle=Handle;
      return AllocErr;
    }
}

int far TXmsMem::FreeXMS(int XMSHandle)  //return 1 -> Success, 0 -> Error, ErrCode -> _XMS_Err
{
   asm mov ah,0x0a
   asm mov dx,XMSHandle
   _XMS_Proc();
   //asm mov _XMS_Err,bl
   return _AX;
}

int far TXmsMem::MemCpy(int hD, unsigned long oD, int hS, unsigned long oS, unsigned long Size)
{
   //Size must be an EVEN number //return 1 -> Success, 0 -> Error, ErrCode -> _XMS_Err
   XMMStrcut XMSS;
   int XMSSSgmt, XMSSOfst;
   void far (*XMS_Proc)(void)=_XMS_Proc;

   XMSS.Size=Size;         //must be EVEN number
   XMSS.SourHandle=hS;
   XMSS.SourOffset=oS;
   XMSS.DestHandle=hD;
   XMSS.DestOffset=oD;
   XMSSSgmt=GetSeg(&XMSS);
   XMSSOfst=GetOfs(&XMSS);

   asm push ds
   asm push es
   asm mov si,XMSSSgmt
   asm mov ds,si
   asm mov si,XMSSOfst
   asm mov ah,0x0b
   XMS_Proc();
   asm pop es
   asm pop ds
   //asm mov _XMS_Err,bl
   return _AX;
}

int far TXmsMem::LockXMSBlock(int Handle, long *Addr)
{
   unsigned int HighWord,LowWord,ErrCode;
   asm mov ah,0x0c
   asm mov dx,Handle
   _XMS_Proc();
   asm mov ErrCode,ax
   asm mov HighWord,dx
   asm mov LowWord,bx
   //asm mov _XMS_Err,bl
   *Addr=((unsigned long)HighWord<<16)+(unsigned long)LowWord;
   return ErrCode;
}

int far TXmsMem::UnLockXMSBlock(int Handle)
{
   asm mov ah,0x0d
   asm mov dx,Handle
   _XMS_Proc();
   //asm mov _XMS_Err,bl
   return _AX;
}


//-- 使用:

int XmsHandle;
if(!xms.AllocXMS(&XmsHandle,260)) //分配内存
{
  //错误
}

//复制数据(访问XMS)

char Buf[BufSize];

//把 Buf 的 Bytes 字节复制到 XmsHandle 的第 XMSOffset 字节开始的内存位置
xms.MemCpy(XmsHandle,XMSOffset, 0,(long)Buf, Bytes);

//把XmsHandle 的 XMSOffset 开始的 Bytes 字节复制到 Buf 地址
xms.MemCpy(0,(long)Buf, XmsHandle,XMSOffset, Bytes);

//复制内存函数的句柄为零,偏移量为常规内存的地址
//复制内存函数的句柄不为零,偏移量为访问这个句柄的扩展内存的开始位置

xms.FreeXMS(XmsHandle); //释放内存, 退出程序的时候必须释放 XMS 内存
  //如果程序退出时忘记释放了,只有重新启动才可以释放了
作者: tianxiapanda     时间: 2005-8-21 22:01
同过加载himem.sys或emm386.exe来使用  谁有c的源代码




欢迎光临 中国DOS联盟论坛 (http://cndos.fam.cx/forum/) Powered by Discuz! 2.5