
武蔵野個別指導塾の特徴
高校情報I 命令の実行—記憶した手順を順番に取り出す仕組みを表で追う|武蔵野個別指導塾

小さな加算機の命令表を動かし、読出し・解釈・実行に沿って命令位置と作業値の変化を追います。
よくあるのは、高校生が命令と処理対象の値を区別できず、命令番号の2を足す数の2だと考えてしまう場面です。番号が指す先に書かれた命令と、その命令が扱うデータは別のものです。紙の手順書で「2番を読む」と言われても、2を計算に使うとは限らないのと同じです。
どこを問われるか
命令を順に実行する問題には、少なくとも次の3つの見方があります。どれも、処理する前と後を区別すると追いやすくなります。
- 命令の位置が与えられたとき、次に取り出す命令を答える型です。番号は手順書の場所を表し、その場所の内容を答えます。
- 途中の作業値と記憶領域の値を表に埋める型です。読み取った値を足しても、保存の命令が実行されるまでは記憶領域の値は変わりません。
- 意図した結果と実行結果が違うとき、最初に食い違う命令と修正方法を答える型です。最後の数だけを見るより、途中の状態を比べると原因を絞れます。
ここでは命令番号を0から始め、命令は上から順に1つずつ処理します。計算対象は整数、結果も整数です。命令を書いた表と、名前付きのデータを入れる領域を分けます。これらは学習用の概念モデルで、実在する機械の命令形式やCPUの細かな内部動作を再現するものではありません。
取り出す場所と計算する値を分ける
命令の実行は、概念的に読出し、解釈、実行の順で考えます。読出しでは現在の命令位置が示す命令を取り出します。解釈では、その命令が読み込みなのか加算なのかなどを見分け、対象の名前を確かめます。実行では指定された操作を行い、通常は次の命令へ進みます。実機の内部ではこの説明より複雑な進め方もありますが、ここでは1命令ずつ完了するモデルです。
図1のように、命令位置は命令表を指し、命令に書いた名前はデータ領域を指します。作業値は計算の途中結果です。命令位置が1であることと、作業値が1であることは、たまたま数が同じでも意味が違います。

図1では命令位置0から「読込 A」を取り出し、データ領域のAにある4を作業値に移します。0を作業値へ入れる操作ではありません。名前Aも数4そのものではなく、4を置いた場所を指定する目印です。
このモデルで使う命令は4種類です。読込は指定された領域の値を作業値に入れ直します。加算は指定された領域の値を作業値に足します。保存は作業値を指定された領域に書き込みます。停止は処理を終えます。作業値の初期値は0で、保存先は既に存在する領域とします。入力時に与えた領域の値は、保存の実行前まで変わりません。
命令表は0番から途切れずに並べ、最後に停止命令を置きます。停止以外は実行後に命令位置を1進めます。実行開始時の位置は0です。命令表が空なら最初の命令を取り出せず、正常終了ではなく命令位置の異常とします。命令の名前が不明、命令の形が不正、指定した領域がない、またはデータが整数でない場合も、原因を示して停止します。異常が起きた命令は実行しません。異常以前に保存された値がある場合は、その値は残る約束です。
モデルの試行には上限回数も設けます。上限は実行済みの命令数で数え、停止命令も1回に含めます。上限に達した後は次の命令を取り出さず時間切れとします。これは実際の秒数を測った結果ではなく、安全に試すための回数制限です。分岐命令のないこのモデルでは、正常な命令が進むたびに位置が1増えるので、有限の命令表なら停止、表の範囲外、または回数制限に達します。
基本例題: 2つの値を足して保存する
領域Aに4、Bに7、Cに0が入っています。AとBの合計をCに保存する命令表を作り、命令ごとの作業値と、最後のCを整数で答えてください。AとBは変更しない条件です。手計算では4と7の合計は11なので、期待するCは11です。
番号 命令
0 読込 A
1 加算 B
2 保存 C
3 停止
図2のように、命令は表の番号順に取り出します。図の矢印は、読込と加算で参照する値、保存で書き込む値の向きを示します。命令番号1はBの値7に足される数ではありません。

図2の結果を、各命令の直後の状態として表にすると次のようになります。Cは保存命令の直後に初めて11になります。
実行した番号 作業値 A B C 次の位置
開始前 0 4 7 0 0
0 4 4 7 0 1
1 11 4 7 0 2
2 11 4 7 11 3
3 11 4 7 11 停止
まず0番はAの4を作業値に入れます。1番はBを参照し、作業値の4に7を加えます。2番は11をCに保存し、3番で停止します。出力にCが11と表示されれば、手計算と合うだけでなく、元の条件であるAとBの合計がCに入ること、AとBが変化していないことも確かめられます。
次の自作プログラムはこの命令表を実行する学習用の模型です。命令はタプル、命令表はリスト、データ領域は辞書で表します。戻り値は「状態、停止位置、作業値、領域、実行済み命令の記録」の順です。状態が正常でないときの位置は、取り出しまたは実行に失敗した位置です。時間切れも次に試す位置を返します。停止命令で正常終了したときは停止命令の位置を返します。
def run(program, data, limit):
memory = data.copy()
pc = 0
acc = 0
trace = []
while len(trace) < limit:
if pc >= len(program):
return "位置異常", pc, acc, memory, trace
instruction = program[pc]
if instruction == ("STOP",):
trace.append((pc, acc, memory.copy()))
return "正常", pc, acc, memory, trace
if (not isinstance(instruction, tuple) or len(instruction) != 2
or instruction[0] not in ("LOAD", "ADD", "STORE")
or not isinstance(instruction[1], str)):
return "命令異常", pc, acc, memory, trace
op, name = instruction
if name not in memory or type(memory[name]) is not int:
return "領域異常", pc, acc, memory, trace
if op == "LOAD":
acc = memory[name]
elif op == "ADD":
acc = acc + memory[name]
else:
memory[name] = acc
trace.append((pc, acc, memory.copy()))
pc = pc + 1
return "時間切れ", pc, acc, memory, trace
program = [("LOAD", "A"), ("ADD", "B"), ("STORE", "C"), ("STOP",)]
result = run(program, {"A": 4, "B": 7, "C": 0}, 4)
print(result)
Python 3.14.8で上のコードを実行した結果は次の通りです。入力はコード内の命令表と領域、上限4です。期待値は正常、停止位置3、作業値11、Cが11で、実際の出力も一致しました。
('正常', 3, 11, {'A': 4, 'B': 7, 'C': 11}, [(0, 4, {'A': 4, 'B': 7, 'C': 0}), (1, 11, {'A': 4, 'B': 7, 'C': 0}), (2, 11, {'A': 4, 'B': 7, 'C': 11}), (3, 11, {'A': 4, 'B': 7, 'C': 11})])
先頭の関数定義は、命令表、データ、回数上限を受け取ります。copyで入力の辞書とは別の領域を作るため、元の辞書を直接書き換えません。pcは命令位置、accは作業値、traceは実行後の状態の記録です。初期値はそれぞれ0、0、空のリストです。
while行は、記録の個数が上限より小さい間に次の命令を扱います。位置が表の長さ以上なら取り出せないため、位置異常を返します。instructionへの代入が読出しです。STOPなら状態を記録して正常終了し、その位置を返します。次の条件は命令の形と名前を調べる解釈です。領域名も文字列であることを確かめ、形が違えば命令異常で戻ります。
opとnameに命令名と領域名を分け、領域が存在して整数かを調べます。値が見つからない場合や文字列などが入った場合は領域異常です。LOADは作業値を置き換え、ADDは現在の作業値に指定値を足し、STOREは作業値を領域へ保存します。実行後の記録にはその時点の領域の写しを入れます。写しがないと、後の保存が過去の記録にも見えてしまいます。最後にpcを1進め、上限までに停止しなければ時間切れを返します。なお、上限は0以上の整数、programはリスト、dataは辞書という前提です。
標準例題: 同じ領域を読み、上書きする
領域Pが6、Qが3です。次の命令を上限4で実行し、正常停止時のP、Q、作業値をこの順に答えてください。Pを入力と保存先の両方に使ってよいものとします。
0 読込 P
1 加算 Q
2 保存 P
3 停止
手で追うと、作業値は0、6、9、9、9と変わります。Pは保存前まで6、保存後は9で、Qは3のままです。答えはPが9、Qが3、作業値が9です。元のPの6にQの3を加えた結果をPに入れる条件に戻しても一致します。入力側と出力側に同じ名前を使えるのは、読込で元の値を取り出した後に保存するからです。保存の前に読込を置かなければ、元の値を別に保持していないこの手順では失ってしまいます。
上の関数に命令表を渡した実行でも、期待値と実際の結果は正常、位置3、作業値9、領域Pが9、Qが3でした。実行記録の各行は、番号0で作業値6、番号1で9、番号2でPが9、番号3で停止です。命令の順番が結果の意味を決めています。
発展例題: 停止の前に保存できたか
領域Dが8、Eが2、Fが0です。0番でDを読み、1番でEを加え、2番でFに保存し、3番で停止する表を考えます。上限を3にしたときの状態、次の位置、Fの値を答えてください。上限は停止命令にも適用します。
0から2までの3命令は実行できます。作業値は8から10になり、Fへ10が保存されます。しかし次の3番を取り出す前に上限に達するため、答えは時間切れ、位置3、Fは10です。期待した合計が保存されていても、正常停止の確認は別に必要です。上限4に増やせば同じ領域で正常、位置3、Fは10になります。どちらも元の8と2を合計した値は保存されていますが、状態は異なります。Pythonで実行した結果もそれぞれの期待値と一致しました。
この例では停止命令を含む実行回数を明示しました。もし停止を数えない約束なら判定が変わるので、回数の定義を変えずに表を読み替えることはできません。時間切れの結果を正常な結果として採用するかは、利用する側の約束が必要です。このモデルでは異常として返し、呼び出し側が状態を確かめます。
誤答から最初のずれを探す
基本例題のAが4、Bが7、Cが0のまま、1番を誤って「読込 B」とした場合を追います。0番の後は正しい手順と同じ作業値4です。しかし1番では4に7を足す代わりに、作業値を7で置き換えます。その後、Cへ7を保存して停止します。期待する11と食い違う最初の場所は1番です。
図3のように、誤りの原因は「読む」と「足す」の作用を同じだと扱ったことです。1番を「加算 B」に直し、初期状態から再実行します。作業値は4、11、11、11、最後のCは11となり、AとBの合計に戻りました。

実際に誤った表を実行すると、正常、位置3、作業値7、Cは7でした。正常という状態は命令表がエラーなく終わったことを表し、目的どおりの答えを保証しません。修正後は正常、位置3、作業値11、Cは11です。図3と処理表は実行結果と一致します。
また、保存先を存在しないZと書いた場合は2番で領域異常となり、Cは0のままです。これを単に合計が0だったと解釈してはいけません。状態と停止位置を先に見れば、保存が実行されなかったとわかります。入力の辞書を修正する場合と、命令表の宛先を修正する場合のどちらが意図に合うかは、最初に定めた保存先の条件から決めます。
正常と失敗を同じ数だけ試す
一例が動くだけでは、命令の解釈や失敗の扱いまでは確かめられません。次はPython 3.14.8で、上の関数を使って試した自作の入力です。各行の期待値と実際の出力は一致しました。領域の表示は必要な値を抜き出しています。上限は実行済み命令の数です。
| 区分 | 入力と上限 | 期待値と実際の出力 |
|---|---|---|
| 正常1 | 基本例題、4 | 正常、位置3、Cは11 |
| 正常2 | STOPのみ、領域は空、1 | 正常、位置0、作業値0、領域は空 |
| 正常3 | 読込X、加算X、保存X、停止。Xは5、4 | 正常、位置3、Xは10 |
| 正常4 | 読込Y、停止。Yは-2、2 | 正常、位置1、作業値-2、Yは-2 |
| 失敗1 | 空の命令表、領域は空、1 | 位置異常、位置0、領域は空 |
| 失敗2 | 読込Z、停止。領域は空、2 | 領域異常、位置0、領域は空 |
| 失敗3 | 不明な命令 BAD、停止。領域は空、2 | 命令異常、位置0、領域は空 |
| 失敗4 | 基本例題、3 | 時間切れ、位置3、Cは11 |
正常2は1命令と空のデータ領域、正常3は同じ領域の重複参照、正常4は負の値を確認します。失敗1は命令がない境界、失敗2は未発見の領域、失敗3は壊れた命令、失敗4は回数の境界です。別に、領域Aの値を文字列にした読込も、期待どおり領域異常で止まりました。存在しても整数でなければ計算へ進めません。
外部の道具に実行を依頼する場合は、道具自体の起動失敗や途中終了も区別します。例えば実行結果が届かないときは、作業値が0だったと推測せず、出力を未取得として扱います。命令モデルの領域異常とは発生場所が違うため、入力を直しても道具の故障は解消するとは限りません。Python 3.14.8で別の処理を起動し、11を表示する正常試行では、期待値と実際の出力がともに11でした。存在しない実行ファイルを指定した失敗試行では、期待どおり起動時の例外を受け取り、計算結果は未取得でした。例外を受け取る場所を設けておくと、失敗を数値として扱わずに済みます。
一般的な成立理由も表の外で考えます。命令表と整数の領域が条件を満たし、必要な命令を実行できるだけの上限があるとします。各命令の前にはpcが次の命令を指し、accと領域はそれ以前の命令を順に実行した後の状態です。読込、加算、保存はいずれも定めた領域と作業値に対して指定の操作を行い、その後pcを1進めるので、この関係は次にも保たれます。停止に到達すればそれまでの命令を順に実行した状態が返ります。試行は実装の誤りを見つける材料ですが、この説明と区別します。
練習: まず自分で手順表を埋める
各問は上と同じ命令の規則を使います。値は整数、停止以外の命令の次は番号を1進めます。領域名がないときは領域異常、表の外に出たときは位置異常です。上限は停止を含めた実行済み命令数で、実行前の領域の値を使います。
- 領域Hが12、Jが5、Kが0です。0でHを読み、1でJを加え、2でKに保存し、3で停止します。各命令の直後の作業値と、最後のKを整数で答えてください。上限は4です。
- 領域Mが9、Nが4です。0でMを読み、1でNに保存し、2で停止します。最後のMとNを整数で答えてください。上限は3です。
- 領域Rが3、Sが8です。0でRを読み、1でSを読み、2でRに保存し、3で停止します。最後のRと作業値を答え、RとSの合計をRに保存する目的に合うか答えてください。上限は4です。
- 領域Tが2、Uが6です。0でTを読み、1で存在しないVを加え、2でUに保存し、3で停止します。上限は4です。状態、位置、作業値、Uの値を答えてください。
- 領域Wが10、Yが1です。0でWを読み、1でYを加え、2でYに保存し、3で停止します。上限は2です。状態、次の位置、作業値、Yの値を答えてください。
練習の答えと確かめ方
- 作業値は順に12、17、17、17で、Kは17です。読込で12を入れ、加算で5を足し、保存でKに17を入れ、停止では値を変えません。Pythonの実行結果は正常、位置3、作業値17、Kは17でした。12と5を合計すると17なので、Kに求めた合計が入り、HとJも元の値のままです。
- Mは9、Nも9です。読込後の作業値9をNに保存するため、Nの元の4は上書きされます。実行結果は正常、位置2、作業値9、MとNはともに9でした。元のMをNへ写すという命令の意味と照合できます。加算命令がないので13にはなりません。
- Rは8、作業値は8で、目的には合いません。0番の後は3ですが、1番の読込で8に置き換わり、2番でRに8を保存します。実行結果は正常、位置3、Rが8、Sが8でした。元の3と8の合計は11なので目的との差が見えます。1番を加算に変えて初期値から再実行するとRは11で、元の値の合計と合います。
- 領域異常、位置1、作業値2、Uは6です。0番は実行できるので2を読みますが、1番にはVがなく、その加算と後の保存は実行されません。Pythonでも同じ状態でした。Uを確かめると初期値6のままであり、保存に到達していないという説明と一致します。
- 時間切れ、位置2、作業値11、Yは1です。読込と加算の2回で上限に達し、保存はまだ行いません。Pythonでも同じ状態でした。Wと元のYの合計は11ですが、Yの保存値は1のままです。上限を4にして初期状態から実行すると正常、位置3、Yは11となり、保存まで進めた違いが確認できます。
手順を追うときの要点
命令位置は次の命令の場所であり、計算する値とは別です。 読出しで命令を取り出し、解釈で操作と対象を見分け、実行で状態を変えます。 作業値の変化と、記憶領域への保存を別の列に記録します。 停止、異常、時間切れを区別し、出力を元の条件へ戻して確かめます。
説明が止まった場所を見つける
命令番号を計算に使ってしまうときは、まず「今読む表の行」と「その行が指定する領域」を指で別々に示してみます。読込と加算が混ざるときは、作業値が既にある状態から両方を実行し、置き換えと加算の違いを口に出して説明します。結果が同じになる入力だけでは違いが隠れるので、両方の値を0以外にして比べます。
個別指導では、完成した答えより、どの行でどの値が変わったと本人が説明するかを見ます。例えば加算直後に保存先まで変えた表なら、保存命令を実行する前後の2行を並べて確認します。異常の問題で最後まで表を埋めた場合は、失敗した命令が実行されたかを条件へ戻します。命令の場所とデータの場所を分けた表が、処理のずれを見つける手がかりになります。
読んで終わりにするか、ここから変えるか。
武蔵境駅徒歩30秒、講師1人に生徒1人の完全1対1。授業のあいだ、先生は隣を離れません。いまの詰まりを、無料相談でそのまま話してください。
まず15分だけ電話で話したい方は、無料電話相談(15分)から。塾からお電話を差し上げます。
本気になった日が、入塾の日。
お子様の教育、迷ったら「丸投げ」してください。必ず、期待以上の結果で返します。武蔵野で育む、武蔵境で学ぶ。
電話は年中無休。365日、24時間、お電話可能。




