難解度「AA」
※このページ全体の難解度です。

バイト列

トグル系項目に限らず、ファンネルライトやダブルリストなどでも広く用いられる「バイト列」ですが、これはバイト単位で記述した処理の集まりです。例を示します。
2EFFC0E0 2E FF C0E0 2? DD ?? 5E *+ 02 1FFF DD 5E *+ 04 1FFFFFFF DD *< FF :: 01 *> *< FF :: 01 :: FF *> *: 00500000 FF *_ 01?00010 $4 [:0x400000:]+0x500 $$ *{ FF :: 01 *} *{ FF :: 01 :: FF *} *[ 0x20 :: FF00 *] <_ A020 :: FFCC _>
バイト列では、値は全て16進数ですので、「0x」を付ける必要はありません。また、16進数といっても、「9」や「A」のように1桁で表せるものは「09」「0A」として、必ず2文字区切りにしてください。なお、1バイトスペースは無視されますので、例の1行目と2行目は同じものになります。
2EFFC0E0 | 16進数の2E, FF, C0, E0 が連続していることを意味しています。書き込み処理なら、この通りに書き込まれます。
2E FF C0E0 | 1バイトスペースは無視されますので、「2EFFC0E0」と同義です。
2? ?D ?? | '?'によるマスクも可能です。比較処理なら、「2?」は、20〜2F のどれにでも合致します。書き込み処理なら、「2?」は、一旦現在の値を所得し、2FとのANDを取ってマスクされた値を書き込みます。「?D」「??」も同様に解釈されます。
5E *+ 02 1FFF DD | "*+"は、相対ジャンプ命令です。
*+ 使用バイト数 ジャンプバイト数
という書式で書きます。 仮に処理開始のアドレスを0x400000 とすると、ここでは、 アドレス0x400000 に5E を処理して1バイト進み、 ジャンプ命令によって1FFFバイト進め、 アドレス0x402000 にDD を処理する。というバイト列になります。
5E *+ 04 1FFFFFFF DD | ジャンプ命令(*+)を、4バイトのジャンプ量で使用した例です。 注意点として、ジャンプ量はリトルエンディアン表記になります。4バイトのジャンプ量指定で0x2Fしか飛ばさない場合、「*+ 04 0000002F」といった書き方になるわけです。
*< FF :: 01 *> |
難解度「AA+」
"*<"は、条件分岐命令です。
*< 条件式のバイト列 :: 真のとき処理するバイト列 :: 偽のとき処理するバイト列 *> ////////////////////　↑実際は一行で書きます
という書式で書きます。偽のとき処理するバイト列は、必要が無ければ直前の「::」と併せて省いて構いません。 仮に処理開始のアドレスを0x400000 とすると、ここでは、 アドレス0x400000 の値がFF であれば、 アドレス0x400001 に01 を処理する。というバイト列になります。（FFでない場合は、何もしません） ただし、ここでいう「条件分岐」は、「経路分岐」にあたります。下の表を見て下さい。
| AA BB 3F 3F |
→DD EE |
| 55 CC 20 44 |
"DD EE"と続くメモリデータがあったとき、その次のメモリデータが"AA"のときと、それ以外のときで、以降の処理を分けたいとしましょう。このようなときに、経路分岐型の条件分岐命令を用います。 今回の例で言えば、“DD EE *< AA :: BB 3F 3F :: CC 20 44 *>”などといった形になるでしょう。注意して欲しいのは、もしこのバイト列で書き込み処理を行った場合、3バイト目の値が"AA"のときは、4バイト目からBB 3F 3Fに書き換え、3バイト目がAAでないときは、同じく4バイト目からCC 20 44と書き換えます。「条件式を評価した結果、読み書きを行うアドレスは、条件式で評価したメモリデータの次から」なのです。 ※あるアドレスの値がFFなら、そのアドレスの値を00に書き換えたい、といった処理は、経路分岐型の条件分岐ではなく、後述する「条件付き置換」を利用します。
*< FF :: 01 :: FF *> | 条件式の偽の処理も行う場合の例です。 仮に処理開始のアドレスを0x400000 とすると、ここでは、 アドレス0x400000 の値がFF であれば、 アドレス0x400001 に01 を処理し、FF でないなら アドレス0x400001 にFF を処理する。というバイト列になります。
*: 00500000 FF | 「*+」が相対ジャンプ命令であることは前述しましたが、「*:」は絶対ジャンプ命令です。絶対ジャンプは直接アドレスを指定するため、続くバイトは4バイト固定です。
*: ジャンプ先アドレス
という書式を用います。この例では、呼び出し元の項目がどんなアドレスを指定していようとも、アドレス0x500000に、FFを書き込む処理を指します。
*_ 01?00010 | バイト列では、16進数表記のためにデータをバイト単位で記述していきますが、この場合、ビット単位のマスク処理を記述することが出来ません。そこで、バイトではなくビット単位で値を書くときに、ビット展開命令「*_」を使用します。 「*_」と書くと、その後ろから8文字分を、マスクを考慮しながら1バイトに組み直します。なお、上位のビットから順に記述します。(8→001000)
*_ 展開したビット値
という書式を用います。当たり前ですが、展開したビット値を記述するので、 0 か 1 か ? しか使えません。
$4 [:0x400000:]+0x500 $$ |
難解度「AA+」
'*'から始まる命令群は、「組み替え型」の命令になります。条件分岐やアドレスの移動、ビット展開などがそれにあたりますね。これとは別に、'$'から始まる命令もあり、これらは「置き換え型」の命令となります。 「$1」「$2」「$3」「$4」は、それぞれから「$$」までを、アドレスコーディング表記の文字列と見なし、数値へと変換処理します。（詳しいアドレスコーディングの書き方は、《A-アドレス》を参照。）さらにその数値を、「$1」ならば1バイト分のバイト列（00〜FF）に、「$2」ならば2バイト分の文字列（0000〜FFFF）に、といった具合に、指定したバイト数のバイト列へと置き換える命令になります。 ここでは、アドレス0x400000の4バイトの値に0x500を加算した値を、4バイト分のバイト列として利用しています。 なお、バイト列は2文字単位が原則ですが、アドレスコーディング部分は、自由に書いて構いません。
*{ FF :: 01 *} |
難解度「AA+」
"*{"は、条件付き置換命令です。
*{ 条件式のバイト列 :: 真のとき処理するバイト列 :: 偽のとき処理するバイト列 *} ////////////////////　↑実際は一行で書きます
という書式で書きます。条件分岐（経路分岐）命令と非常に似ていますが、条件式を評価した結果、次に読み書きするアドレスに差があります。あるアドレスの値がFFなら、そのアドレスの値を01に書き換えたいといった処理をバイト列で行うとき、条件分岐命令(*{::*})では非常に分かりづらい書き方をしなくてはなりません。そこを簡潔に処理できるのが、この条件付き置換命令です。 仮に処理開始のアドレスを0x400000 とすると、ここでは、 アドレス0x400000 の値がFF であれば、 アドレス0x400000 に01 を処理する。というバイト列になります。（FFでない場合は、何もしません） なお、現在ON(真)であるかOFF(偽)であるかの判定時には、真のバイト列で評価します。このため、書き込みを指示しても、対象位置の値が条件式で真とならない場合は、真の値が書き込まれず、当然、再評価時にもON(真)とはならないので注意。
*{ FF :: 01 :: FF *} | 条件式の偽の処理も行う場合の例です。 仮に処理開始のアドレスを0x400000 とすると、ここでは、 アドレス0x400000 の値がFF であれば、 アドレス0x400000 に01 を処理し、FF でないなら アドレス0x400000 にFF を処理する。というバイト列になります。
*[ 0x20 :: FF00 *] |
難解度「AA+」
"*["は、反復命令です。
*[ 反復サイズのアドレス式 :: 反復するバイト列 *]
という書式で書きます。あるバイト列を、必要回数分繰り返したい、という場合に使用します。（簡易的なFOR構文） 「反復サイズのアドレス式」には、反復する総バイトサイズを、アドレス式で書きます。仮に8を指定したとすれば、8バイト反復します。もし、「反復するバイト列」が6バイト分だった場合、生成されるバイト列は、1回反復分の6バイト＋最初の2バイト分となります。アドレス式なので、頭に'_'を付ければ、アドレスコーディングを用いることもできます。詳しいアドレスの書き方は、《A-アドレス》を参照。 「反復するバイト列」には、文字通り繰り返したいバイト列を指定して下さい。
<_ A020 :: FFCC _> | "<_"は、マスクバイト命令です。 バイト列は原則として16進数表記のため、F?や?Aのように、上位・下位8ビット単位でしかマスク指定ができません。これを1ビット単位で行いたい場合は、ビット展開命令(*_)を用いるのですが、対象が数バイトに及ぶ場合、非常に分かりにくくなります。そんなときは、このマスクバイト命令を用います。
<_ マスクバイト列 :: 処理バイト列 _>
という書式を用います。 これによって、処理バイト列をマスクバイト列でマスクした書き込みが行えます。ただし、「マスクバイト列」および「処理バイト列」は、純粋な2文字単位の16進数でなければなりません。?やその他の命令を埋め込むことはできません。
ジャンプ命令や条件分岐命令など、少々理解に苦しむところもあるかとは思いますが、使いこなせば結構複雑な処理もバイト列だけで記述することが出来ます。ま、それでも普通は「2EFFC0E0」などの、単純なバイト数値で事足りるでしょうけども(^^;

ねくすと　せくしょん⇒
≪せくしょん　ばっく