家们网!                                                   鼎誉推广助手 长沙网站制作 长沙营销型网站建设 长沙成交型网站建设 更多友情
  •  

        Windows以它一致的图形用户界面、完善的内存管理等特点,已被广大用户所接受,但在Windows下,计算机已运行在保护模式,虽然Windows已提供了一整套的内存管理函数,用户还是不可访问指定地址的内存,致使许多中、小型企业开发的计算机插件无法在Windows下使用,因为编写驱动程序是很费事的。他们仅希望能直接读、写电路板所占的内存即可。本文介绍的是在Windows 3.1下,用Borland C++ 3.1编程环境,实现用户对内存直接读写的方法,读者不难将它移植到其它编程语言。 


    1.利用Windows提供的各个段选择符标号,在C源程序中将选择符标号说明为外部变量。其对照表如下:
    表1

    2.利用宏定义MAKELONG(段内偏移量,&段选择符标号)即可得到一个长指针。

    3.经上述方法得到的指针与C语言中定义的指针是一样的。

    4.如果使用的段是D000H或E000H或其它上位内存时,需改动Windows的系统配置文件SYSTEM.INI,利用字符编辑器,在[386Enh]小节中加入EmmExclude=xxxxyyyy一行,禁止Windows使用这段存储空间。值xxxx和yyyy是16位内存范围。如开发的插件占用D000H段的64K,则应加入这样一行:EmmExclude=d000-dfff。
    利用这一方法,已使我们自己开发的电路板(占用D000H段),在Windows控制下成功地运行了。考虑到读者没有相应的硬件,这里以读取中断向量、计算机ROM的制造时间和对DOS用户通讯区的读写为例,详见以下程序。对于DOS用户通讯区的内容,读者可用DOS的DEBUG程序检查(D命令)和修改(E命令)。DOS的用户通讯区在0040∶00F0H处开始,共计16个字节。在修改时请注意:从0040∶00F0H开始存放可显示ASCII码字符串,并以0结尾。
    ; MEMORY.DEF 模块定义文件
    NAME
    Memory
    DESCRIPTION’demonstrate an intergrated menu’
    EXETYPEWINDOWS
    STUB’WINSTUB.EXE’
    CODEPRELOAD MOVEABLE DISCARDABLE
    DATAPRELOAD MOVEABLE MULTIPLE
    HEAPSIZE1024
    STACKSIZE8192
    EXPORTSWndProc
    /*----------
    MEMORY.RC
    直接读写内存的资源定义文件
    ----------*/
    #include "memory.h"
    MemoryMenu MENU
    BEGIN
    POPUP"取中断向量[&I]"
    BEGIN
    MENUITEM "int 0&3h", IDM-INT03H
    MENUITEM "int &10h", IDM-INT10H
    MENUITEM "int &21h", IDM-INT21H
    END
    POPUP "ROM区域[&R]"
    BEGIN
    MENUITEM "制造时间[&T]",
    IDM-TIME
    MENUITEM "取用户通讯区[&U]", IDM-READ
    MENUITEM "存用户通讯区[&S]", IDM-WRITE
    END
    MENUITEM "\a退出[&X]",
    IDM-EXIT
    END
    /*----------
    MEMORY.H
    直接读写内存的头文件
    ----------*/
    #define IDM-INT03H 101
    #define IDM-INT10H102
    #define IDM-INT21H103
    #define IDM-TIME201
    #define IDM-READ202
    #define IDM-WRITE203
    #define IDM-EXIT300
    /*----------
    MEMORY.C
    用户对固定内存直接读写的表演程序
    ----------*/
    #include<windows.h>
    #include "memory.h"
    #include <dos.h>
    int PASCAL WinMain(HANDLE,HANDLE,LPSTR,int);
    long FAR PASCAL WndProc(HWND,UINT,UINT,LONG);
    /*----WinMain()----*/
    int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance
    ,LPSTR lpszCmdLine,int nCmdShow)
    {
    MSG
    msg;
    HWND hWnd;
    WNDCLASS wndclass;
    if (! hPrevInstance)
    {
    wndclass.style=CS-HREDRAW | CS-VREDRAW;
    wndclass.lpfnWndProc=WndProc;
    wndclass.cbClsExtra=0;
    wndclass.cbWndExtra=0;
    wndclass.hInstance=hInstance;
    wndclass.hIcon=LoadIcon(NULL,IDI-APPLICATION);
    wndclass.hCursor=LoadCursor(NULL,IDC-ARROW);
    wndclass.hbrBackground=GetStockObject(WHITE-BRUSH);
    wndclass.lpszMenuName="MemoryMenu";
    wndclass.lpszClassName="直接读写存储器";
    if (! RegisterClass (&wndclass))
    return FALSE;
    }
    hWnd=CreateWindow(
    "直接读写存储器",
    "直接读写存储器",
    WS-OVERLAPPEDWINDOW,
    CW-USEDEFAULT,
    CW-USEDEFAULT,
    CW-USEDEFAULT,
    CW-USEDEFAULT,
    NULL,
    NULL,
    hInstance,
    NULL);
    if (! hWnd)
    return FALSE;
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    while (GetMessage(&msg,N
    ULL,0,0))

    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    return msg.wParam;
    }
    /*----WndProc()----*/
    long FAR PASCAL WndProc (HWND hWnd, UINT message, UINT w
    Param,LONG lParam
    )
    {
    HDC
    hDC;
    HPEN hOldPen,hNewPen;
    RECTrect;
    TEXTMETRICtm;
    PAINTSTRUCTps;
    UINT i;
    char Strbuf[50];
    WORD far * InterruptVector;
    char far * bios;
    extern WORD-0000H;
    extern WORD-0040H;
    extern WORD-F000H;
    switch (message)
    {
    case WM-COMMAND:
    switch (wParam)
    {
    case IDM-INT03H:
    InterruptVector=(WORD far *)MAKELONG(0,&-0000H);
    wsprintf(Strbuf,"向量地址:%04X:%04XH\n",
    *(InterruptVector+0x06),
    *(InterruptVector+0x07));
    MessageBox (hWnd,Strbuf,
    "int 03h", MB-OK | MB-ICONSTOP);
    return 0;
    case IDM-INT10H:
    InterruptVector=(WORD far *)MAKELONG(0,&-0000H);
    wsprintf(Strbuf,"向量地址:%04X:%04XH\n",*(InterruptVecto
    r+0x20),
    *(InterruptVector+0x21));
    MessageBox (hWnd,Strbuf,
    "int 10h",MB OK | MB-ICONSTOP);
    return 0;
    case IDM-INT21H:
    InterruptVector=(WORD far *)MAKELONG(0,&-0000H);
    wsprintf(Strbuf,"向量地址:%04X:%04XH\n",*(InterruptVecto
    r+0x42),
    *(InterruptVector+0x43));
    MessageBox (hWnd,Strbuf,"int 21h",MB-OK | MB-ICONSTOP);
    return 0;
    case IDM-TIME:
    bios=(char far *)MAKELONG(0xfff5,&-F000H);
    MessageBox (hWnd,bios,
    "ROM制造时间",MB-OK | MB-ICONSTOP);
    return 0;
    case IDM-READ:
    bios=(char far *)MAKELONG(0xF0,&-0040H);
    MessageBox (hWnd,bios,
    "取用户通讯区内容",MB-OK | MB-ICONSTOP);
    return 0;
    case IDM-WRITE:
    bios=(char far *)MAKELONG(0xF0,&-0040H);
    for(i=0;i<10;i++) *(bios+i)='A'+i; *(bios+10)=0;
    MessageBox (hWnd,"Write 'A'-'J'char string !",
    "写用户通讯区内容",MB-OK | MB-ICONSTOP);
    return 0;
    case IDM-EXIT:
    SendMessage (hWnd,WM-CLOSE,0,0);
    return 0;
    }
    break;
    case WM-DESTROY:
    PostQuitMessage (0);
    return 0;
    default:
    break;
    }
    return DefWindowProc (hWnd,message,wParam,lParam);
    }
    /*----End Programming of Demo----*/

    ......
    本文标签: 计算机论文