コンピューティングにおいて、PEEK(ピーク)[注釈 1]とPOKE(ポーク)[注釈 2]は、いくつかの高水準プログラミング言語で使用されるコマンドで、メモリーアドレスで参照される特定のメモリセルの内容にアクセスするために使用する[1][2]。BASICのものがよく知られているが、PascalやCOMAL
(英語版)など他のプログラミング言語にも同様のコマンドがある。このコマンドは、C言語などにおけるポインタに匹敵する役割を持っている。PEEKとPOKEは、初期のパーソナルコンピュータにおいて様々な目的を果たすために考案され、特に、メモリ空間にマッピングされたハードウェアレジスタを変更するために使用された。また、プログラマはこのコマンドを使用して、ソフトウェアをコピーしたり、特定のソフトウェアのプログラミングの意図を回避したりすることもある(例えば、ゲームプログラムを操作してユーザがチートできるようにするなど)。今日では、BASICのような高水準言語を使用して、低水準でメモリを制御することはあまりなく、PEEK、POKEというコマンドの概念は一般的に時代遅れとみなされている。
英語においては、peekやpokeという言葉が、プログラミングにおけるメモリアクセスを指す動詞(poked, peekedなど)として口語的に使われることがある。 PEEK関数とPOKEコマンドは、通常、以下のように直接モード
文法
引数のaddressとvalueは、評価される式がそれぞれ有効なメモリアドレスまたは値に対応する限り、複雑な式を含んでいても良い。ここで言う「有効なアドレス」とは、コンピュータのアドレス空間内のアドレスであり、「有効な値」とは、(一般的には)ゼロから最小アドレス可能なユニット(メモリセル)が保持することができる最大符号なし数までの符号なし値である。 POKEまたはPEEKされるアドレス位置は、通常のメモリセルや、対応するチップ(I/Oユニット、サウンドチップ、ビデオグラフィックスチップなど)のメモリマップされたハードウェアレジスタ、CPU自体のメモリマップされたレジスタを参照することができる(これにより、強力な機械語モニタやデバッグツール、シミュレーションツールをソフトウェアで実装することが可能になる)。以下は、POKEによる対応チップ制御の一例として、コモドール64の内蔵VIC-II
メモリセルとハードウェアレジスタ
以下は、Atari 8ビット・コンピュータでANTIC(英語版)ディスプレイドライバに、全てのテキストを上下逆さまにするように指示するコマンドである。POKE 755, 4
ハードに紐付けられたメモリ位置は機種によって異なるため、様々な機種の「メモリマップ」は重要な文書である。定型的な例として、アタリのコンピュータの64キロバイトのメモリ全体をロケーションごとにマッピングした本『マッピング・オブ・アタリ(英語版)』が出版されている。
一般的に、ユーザプログラム、ユーザデータ、オペレーティングシステムのコードとデータ、メモリマップされたハードウェアユニットのために指定されたメモリアドレス領域は、機種によって異なる。このため、PEEK関数やPOKEコマンドは本質的に非移植性であり、これらを使用したプログラムは、そのプログラムが書かれたシステム以外ではほぼ確実に動作しない。 多くの8ビットコンピュータ用ゲームにおいては、ゲームをメモリにロードし、起動する前に特定のメモリアドレスを変更して、無制限のライフ、無敵化、敵からの不可視化などのチートを行うことができた。このような変更は、POKEコマンドを使って行われた。コモドール64、ZX Spectrum、Amstrad CPCでは、関連するカートリッジやMultiface
チートとしてのPOKE
例えば、ZX Spectrum向けの『ナイト・ロアー』では、以下のコマンドで無敵化することができた。POKE 47196, 201
この場合、値201はRET命令に相当するので、衝突判定をトリガーする前に、ゲームがサブルーチンから早期に復帰する。
『ユア・シンクレア(英語版)』などの雑誌には、ゲームにおけるそのようなPOKEコマンドが掲載されていた。このようなコードは、一般的に、機械語コードをリバースエンジニアリングして、ライフ数、衝突の検出などに関連するメモリアドレスを識別することで発見されていた。
POKEによるチートの使用は、最近のゲームでは難しくなっている。最近のオペレーティングシステムは、外部プログラムからの非共有メモリへのアクセスができないようするために、仮想記憶化によるメモリ保護を行っている(例えば、アプリケーションごとにページテーブルを分けるなど)。
初期のBASICが動作するほとんどのコンピュータは8ビットプロセッサを使用していたため、1つのPEEKまたはPOKEの値は0から255の間のものだった。16ビットマシンにおいて16ビットの整数値を読み書きするには、PEEKやPOKEを2回実施する必要がある。アドレスAの16ビット整数値を読み出すためには、PEEK A+256*PEEK(A+1)とする必要があり、アドレスAに16ビット整数Vを書き込むためには、POKE A,(V AND 255)に続けてPOKE (A+1),TRUNC(V/256)を実行する必要がある。 IBM PCやAmigaなどの16・32ビットマシンでは、16ビット値を一度に読み書きできるDPEEKやDPOKEのようなコマンドが公式で用意されていた[3]。Sinclair QLでは、16・32ビット値の読み書きができるPEEK_W/PEEK_L、POKE_W/POKE_Lコマンドがあった。Atari STシリーズでは、コマンド名称は8ビットのコマンドと同様だが、読み書きするビット幅を指定することができた。また、いくつかの8ビットマシンには、16ビット幅のPEEKとPOKEを行うBASIC方言があった。例えば、東ドイツの"Kleincomputer" KC85/1(別名 Z9001)やKC87には、DEEK、DOKEコマンドがあった[4]。
16ビットマシンのPEEKとPOKE
Size:16 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)』
担当:undef