实现在Windows下直接读写内存的方法
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-ICONSTO
Tags:
作者:佚名评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论