メモリーアクセスするユーザーインタフェースはメモリー内容の確認および設定用のコマンドを備えています。次の操作はユーザーインタフェースを使用して行います。
任意の仮想アドレスの読み取り、書き込み。
仮想アドレスの物理アドレスへの割り当て。
メモリー演算子を使用すると、任意のメモリー位置からの読み取り、任意のメモリー位置への書き込みが行えます。以降の例に示すメモリーアドレスはすべて仮想アドレスです。
8 ビット、16 ビット、32 ビット (システムによっては 64 ビット) のさまざまな操作ができます。一般的に、c (文字) という 接頭辞は 8 ビット (1 バイト) の操作を示し、w (ワード) という接頭辞は 16 ビット (doublet) の操作を示し、l (ロングワード) という接頭辞は 32 ビット (quadlet) の操作を示します。x という接頭辞は 64 ビット (octlet) 操作を示します。
waddr、qaddr、oaddr は境界の制約をもつアドレスを示します。たとえば、qaddr は 32 ビット (4 バイト) 境界を示し、したがってそのアドレス値は次の例に示すように 4 の倍数でなければなりません。
ok 4028 l@ ok 4029 l@ Memory address not aligned ok |
OpenBoot に実装されている Forth インタプリタはできるだけ ANS の Forth 標準に準拠しています。明示的に 16 ビット または 32 ビット (システムによっては 64 ビット) を取り出す場合は、@ の代わりにそれぞれ w@、l@、または x@ を使用してください。メモリーやデバイスレジスタへのアクセスコマンドもこの規則に従います。
表 4-11 にメモリーアクセス用のコマンドを示します。
表 4-11 メモリーアクセスコマンド
コマンド |
スタックダイアグラム |
説明 |
---|---|---|
! |
( x a-addr -- ) |
数値を a-addr に格納します。 |
+! |
( nu a-addr -- ) |
nu を a-addr に格納されている数値に加算します。 |
@ |
( a-addr -- x ) |
数値を a-addr から取り出します。 |
2! |
( x1 x2 a-addr -- ) |
2 つの数値を a-addr に格納します。x2 が下位アドレス。 |
2@ |
( a-addr -- x1 x2 ) |
2 つの数値を a-addr から取り出します。x2 が下位アドレス。 |
blank |
( addr len -- ) |
addr からの len バイトを空白文字 (10 進の 32) に設定します。 |
c! |
( byte addr -- ) |
byte を addr に格納します。 |
c@ |
( addr -- byte ) |
byte を addr から取り出します。 |
cpeek |
( addr -- false | byte true ) |
addr の 1 バイトを取り出します。アクセスが成功した場合はそのデータと true を返し、読み取りエラーが発生した場合は false を返します。 |
cpoke |
( byte addr -- okay? ) |
byte を addr に格納します。アクセスが成功した場合は true を返し、書き込みエラーが発生した場合は false を返します。 |
comp |
( addr1 addr2 len -- diff? ) |
2 つのバイト配列を比較します。両配列が等しい場合は diff? = 0、異なる最初のバイトにおいて、addr1 の文字列の方が小さい場合は diff? = -1、それ以外の場合は diff? = 1 になります。 |
dump |
( addr len -- ) |
addr から len バイトのメモリーを表示します。 |
erase |
( addr len -- ) |
addr から len バイトのメモリーを 0 に設定します。 |
fill |
( addr len byte -- ) |
addr から len バイトのメモリーを値 byte に設定します。 |
l! |
( q qaddr -- ) |
quadlet q を qaddr に格納します。 |
l@ |
( qaddr -- q ) |
quadlet q を qaddr から取り出します。 |
lbflips |
( qaddr len -- ) |
指定された領域の各 quadlet 内のバイトを逆に並べ替えます。 |
lwflips |
( qaddr len -- ) |
指定された領域の各 quadlet をスワップします。 |
lpeek |
( qaddr -- false | quad true ) |
quadlet を qaddr から取り出します。アクセスが成功した場合はそのデータと true を返し読み取りエラーが発生した場合は false を返します。 |
lpoke |
( q qaddr -- okay? ) |
quadlet 8 を qaddr に格納します。アクセスが成功した場合は true を返し、書き込みエラーが発生した場合は false を返します。 |
move |
( src-addr dest-addr len -- ) |
src-addr から dest-addr に len バイトをコピーします。 |
off |
( a-addr -- ) |
a-addr に false を格納します。 |
on |
( a-addr -- ) |
a-addr に true を格納します。 |
unaligned-l! |
( q addr -- ) |
quadlet q を任意の境界に格納します。 |
unaligned-l@ |
( addr -- q ) |
quadlet q を任意の境界で取り出します。 |
unaligned-w! |
( w addr -- ) |
doublet w を任意の境界に格納します。 |
unaligned-w@ |
( addr -- w ) |
doublet w を任意の境界で取り出します。 |
w! |
( w waddr -- ) |
doublet w を waddr に格納します。 |
w@ |
( waddr -- w) |
doublet w を waddr から取り出します。 |
<w@ |
( waddr -- n ) |
doublet n を waddr から符号拡張して取り出します。 |
wbflips |
( waddr len -- ) |
指定された領域の各 doublet 内のバイトをスワップします。 |
wpeek |
( waddr -- false | w true ) |
doublet w の数値を waddr から取り出します。アクセスが成功した場合はそのデータとtrue を返し、読み取りエラーが発生した場合は false を返します。 |
wpoke |
( w waddr -- okay? ) |
doublet w の数値を waddr に格納します。アクセスが成功した場合はそのデータと true を返し、読み取りエラーが発生した場合は false を返します。 |
表 4-12 に示すメモリーアクセス用コマンドは 64 ビットの OpenBoot 実装専用です。
表 4-12 64 ビットメモリーアクセス機能
コマンド |
スタックダイアグラム |
説明 |
---|---|---|
<l@ |
( qaddr -- n ) |
quadlet を qaddr から符号を拡張して取り出します。 |
x@ |
( oaddr -- o ) |
octlet を 64 ビット 境界アドレスから取り出します。 |
x! |
( o oaddr -- ) |
octlet を 64 ビット 境界アドレスに格納します。 |
xbflips |
( oaddr len -- ) |
指定された領域の各 octlet 内の 8 バイトを逆に並べ替えます。len が/x の整数倍でない場合は、動作は不定です。 |
xlflips |
( oaddr len -- ) |
指定された領域の各 octlet 内の 2 つの quadlet をスワップします。各 quadlet 内の 4 バイトは逆に並べ替えられません。len が /x の整数倍でない場合は、動作は不定です。 |
xwflips |
( oaddr len -- ) |
指定された領域の各 octlet 内の 4 つの doublet を逆に並べ替えます。各 doublet 内の 2 バイトはスワップされません。len が /x の整数倍でない場合は、動作は不定です。 |
dump コマンドは特に便利です。このコマンドは、メモリーの領域をバイト値、ASCII 値の両方で表示します。次の例は、仮想アドレス 10000 からの 20 バイトを表示します。
ok 10000 20 dump (仮想アドレス 10000 からの 20 バイトを表示) ¥/ 1 2 3 4 5 6 7 8 9 a b c d e f v123456789abcdef 10000 05 75 6e 74 69 6c 00 40 4e d4 00 00 da 18 00 00 .until.@NT..Z... 10010 ce da 00 00 f4 f4 00 00 fe dc 00 00 d3 0c 00 00 NZ..tt..‾¥..S... ok |
一部の実装は、メモリーを16、32、64 の各ビット値として表示する、dump のバリエーションをサポートしています。sifting dump (「辞書の検索」を参照) を使用すれば、システムにそのようなバリエーションがあるかどうかを確認できます。
(たとえば、@ を使用して) 無効なメモリー位置をアクセスしようとした場合は、処理はただちに終了し、PROM が Data Access Exception または Bus Error などのエラーメッセージを表示します。
表 4-13 にメモリーマップ操作用のコマンドを示します。
表 4-13 メモリーマップコマンド
コマンド |
スタックダイアグラム |
説明 |
---|---|---|
alloc-mem |
( len -- a-addr ) |
len バイトの空きメモリーを割り当てます。割り当てた仮想アドレスを返します。 |
free-mem |
( a-addr len -- ) |
alloc-mem で割り当てられていたメモリーを開放します。 |
次の画面は alloc-mem と free-mem の使用例です。
alloc-mem が 4000 バイトのメモリーを割り当てます。その予約領域の開始アドレス (ef7a48) が表示されます。
dump が ef7a48 から始まるメモリー 20 バイトの内容を表示します。
次に、このメモリー領域を値 55 でみたします。
最後に、free-mem が、割り当てられた ef7a48 からの 4000 バイトのメモリーを返します。
ok ok 4000 alloc-mem . ef7a48 ok ok ef7a48 constant temp ok temp 20 dump 0 1 2 3 4 5 6 7 ¥/ 9 a b c d e f 01234567v9abcdef ef7a40 00 00 f5 5f 00 00 40 08 ff ef c4 40 ff ef 03 c8 ..u_..@..oD@.o.H ef7a50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ef7a60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ok temp 20 55 fill ok temp 20 dump 0 1 2 3 4 5 6 7 ¥/ 9 a b c d e f 01234567v9abcdef ef7a40 00 00 f5 5f 00 00 40 08 55 55 55 55 55 55 55 55 ..u_..@.UUUUUUUU ef7a50 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU ef7a60 55 55 55 55 55 55 55 55 00 00 00 00 00 00 00 00 UUUUUUUU........ ok ok temp 4000 free-mem ok |
前項で説明の仮想メモリーアクセス用のオペレータ (コマンド) を使用してデバイスレジスタをアクセスした場合、信頼性が欠けることがあります。デバイスレジスタアクセス用には特別なオペレータ (コマンド) があります。それらのオペレータ (コマンド) の場合は、使用する前にマシンを正しく設定する必要があります。これについての詳細は、『Writing FCode 3.x Programs』を参照してください。