1.1 物理メモリアクセス(プログラムの構造)

 Win16はWin32と違い,低レベルへのアクセスを許しています.そのため,ハードウェアを制御したい場合や低レベルにアクセスしたい場合,Win16を使うのが手っ取り早いと言えます.

 確かに,ドライバなどを開発しWin32上から制御しないと,ほかのアプリケーションとともに動かした場合に不具合を生じることがあります.しかし,少し試したい場合などにWin16を使うと手間を省ぶくことができます.

1-1-1  プログラムファイルとプログラム構造

 プログラムファイルは三つです(表1-1).基本的に行うことは,MD.Cを入力することのみです.タッチタイプができる人であれば,1分もあれば入力できるでしょう.

<表1-1> プログラムファイル

MD.C プログラムファイル本体
MD.DEF 必ず必要なファイル.自動的に作られる
MD.MAK VisualC++用のメイクファイル.自動的に作ることができる

 プログラムは,WinMainしかありません.

<図1-1> プログラムの構造



1-1-2  プログラムの解説

 リスト1-1は,パソコンのビデオRAMにデータを直接書き込むプログラムです(図1-2)

 WindowsをVGAモードなどで使っていると,A0000H(セグメントアドレスA000H,オフセットアドレス0000H)からビデオ用のRAMが割り当てられています.このエリアに直接書き込みを行います.

変数の宣言

 unsigned int loop ;

 WORD FAR * lpScreen ;

 WORD selector ;

 上記は,何の変哲もない変数の宣言です.

アドレスの代入


 まず,ビデオRAMのアドレスを獲得しなければなりません.通常の方法では,WindowsアプリケーションからビデオRAMの物理アドレスを獲得することは不可能です.では,このプログラムはどうやっているのでしょうか.

selector = (WORD)&_A000h ;

 さあ,上の行は何をやっているのでしょう?単純に_A000hのアドレスをselectorという変数に代入しているだけです.ところで_A000hってどこにありましたっけ!そうそう,先頭のほうに以下のような宣言がありましたね.

extern BYTE NEAR CDECL _A000h ;

 そうです._A000hは外部にあります.しかし,このプログラムは本体以外に外部モジュールはありません.では_A000hっていったいどこにあるのでしょう.ここで,_A000hの話は中断して次に進みます.

lpScreen = (WORD FAR *)MAKELP( selector, 0 );

 MAKELPマクロは,セグメントセレクタとアドレスオフセットを組み合わせて,メモリアドレスを指すlong(32ビット)ポインタを作成します.i386などのプロテクトモードでは,セグメントはセグメントアドレスではなくセレクタで表されます(注1-1).

 このMKELPマクロはWin16専用です.つまり,Windowsアプリケーションであっても,ある物理メモリのセレクタさえわかっていれば,物理メモリへアクセスすることができます.本格的なOSであれば,メモリ保護例外などが発生してしまいます.しかし,Windows 9xやWindows 3.1ではこのようなことができます.

ビデオRAMへの書き込み

 for( loop = 0 ; loop < 0xFFF0 ; loop++ )

 lpScreen[loop] ^= 0xFFFF ;

 ここでは,直接ディスプレイ領域のメモリ(VRAM)と0xFFFFでXORを取っています.このコードによって,表示画面が反転します.このように,GDIを使うことなく画面をアクセスすることができます.

1-1-3  プログラムの作成方法

 Visual C++ 1.51を起動した後,MD.MAKを開いてビルドします.あるいは,Visual C++をインストールしたときに,*.MAKが関連づけられるので,MD.MAKをダブルクリックして,Visual C++を起動する方法もあります(注1-2)


注:1-1 セレクタやディスクプリンタについては,i386アーキテクチャの解説書を参照してください.

注:1-2 Win32ではこのプログラムをビルドすることはできません.


Copyright 2000 北山 洋幸

新刊のご案内


Copyright 1997-2001 CQ Publishing Co.,Ltd.