- ベストアンサー
アセンブリ言語の問題
アセンブリ言語のプログラムの実行開始番地が0番地以外、というのはあり得ることなのでしょうか(例1:10番地よりプログラムが実行開始)。 また、データが格納されている番地からプログラムを開始することは可能なのでしょうか(例2:上記の例1の状態で、10番地には整数データである「0」が格納されている)。 授業で習っていてわからない点です。CPUなどについては先生から一切説明されていませんが、ご回答お待ちしております。 初めての質問で至らない点がございますが、ご了承ください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
数学の授業の中での課題とのことなので、CPUのアーキテクチャーなどはあまり詳しく考えなくても良いでしょう。 現在の電子計算機は、プログラムもデータもメモリ空間上に配置される、ということと、 命令は、メモリー空間の決まったアドレスから逐次読み込まれてで実行される、 という概念くらいで良いと思います。(興味があれば、フォンノイマンというワードで検索してみて、名前くらい記憶の隅に留めておいてください。現在の電子計算機は基本的にはフォンノイマン型で、上記の様な概念のものです) どのアドレスから実行されるかはCPUに依存するのですが何も説明がないということならば、とりあえず#1さんの仰るとおり、0番地から実行され、アドレスの高い方に逐次進んで行く、と仮定しておけば良いでしょう。 特定のアドレスから実行することは出来るか? これもCPUの構造に依存しますが、基本的にはリセット時、即ち最初に電源が入ったときに実行が開始されるアドレスを登録することが出来るのであれば、可能となります。(リセットベクター、割り込みベクターの定義。) データが入っているアドレスから実行することが出来るか? 出来ます。メモリ空間には先の通り、プログラムもデータも格納されていますし、プログラム開始するアドレスも変更出来るので、意図的にそうすれば可能になります。 ただし、単なるデータの羅列であれば、一般的には意味のない命令を実行していき、やがて暴走(意図しない動作)になると思います。 だいたい上記の様な概念になりますが、もう少し膨らまして、分岐命令や割り込みの制御なども概念として知っておくと良いでしょう。 プログラムの命令には分岐というものがあり、条件によってもしくは無条件にプログラムの実行アドレスを変更する命令もあります。 例えば、 Aが1より大きいなら xxxxアドレスへ分岐(ジャンプ命令) など。これにより、複雑なプログラムが記述できます。 また、割り込みという概念もあり、プログラムの実行中、ある特定の事象が発生すると、(タイマーにセットした時間が経過、ある信号入力を検出など)、強制的に割り込みベクターに記述されているアドレスにプログラムの制御を飛ばし、割り込み処理が終了すると、もとのアドレスに戻るという仕組みもあります。 この辺りをどんどん突き詰めていくと、電子計算機の機能と構造の基礎的な内容全部になってくるので、とりあえずはこの程度で良いでしょう。あるCPUのアーキテクチャに特記しても良いですが、まずは概念的なところを押えておけば良いと思います。
その他の回答 (5)
- mitoneko
- ベストアンサー率58% (469/798)
まず、コンピュータが最初に電源を投入された時に実行するアドレスは、CPUとそれに付随するハードウェアの構造により変わります。 0番地からのものもありますし、0番地以外からスタートするものもあります。 この時点で、0番地以外でスタートするプログラムは「有り」です。 また、あるOSの元で実行されるプログラムと言うことであれば、普通は、OSにより規定された範囲の任意のアドレスからプログラムはスタートすることになります。 ごく単純な仕組みを考えれば、プログラムのファイル等をOSが読み込んで、ファイル内の指定に従い、メモリーにプログラムを展開します。(これをロードと言います。) その後、OSは、読み込んだプログラムの先頭アドレス(これもファイル内に指定があるのが普通。)にジャンプすることによりプログラムに制御を渡します。 つまり、プログラムの実行開始番地は、ある程度自由に設定できるということになります。(ついでに言うと、メモリーの0番地を含む最下位の領域は、特別な領域として利用されることが多く、その意味で、0番地からスタートするプログラムはあり得ない・・・なんて結果になります。) ちなみに、保護機能の無いCPUにおいては、メモリーにあるデータは、単純に2進数の数値としてしか意味がありません。ある番地にある2進数の数字が、命令語か、それとも単なるデータかは、その番地にプログラムの制御が移るかどうか?という結果論でしか識別できません。 これは、プログラムが自分自身のプログラムを改変できると言うことを意味します。 その昔、8bitCPUを使い、プログラム言語と言えば、アセンブラを使うか、機械語の2進数を直接記述するなんてことを手でやっていた時代には、自己改変するプログラムも結構見かけました。 今でも、高度なウィルスなんかは、こうやって身を隠すなんて話も聞きます。 入力されたデータに従い、自分自身を改変することを続ければ、自分で勝手に成長するプログラムなんてのも原理的には可能ですね。ロボットの人工頭脳に適用すれば、人間と同様に成長するロボットの・・・なんて言うと夢物語になりますけどね。 じゃ、保護機能のあるって何かというと、この命令語とデータの保存されている領域を指定できるCPUを差します。指定するのは、特権モードで実行されるプログラム(普通はOSの心臓部のみです。)の仕事です。この指定が行われた後は、データと指定された領域は命令語と解釈して実行することは不可能となり(言い換えるとデータ領域にジャンプすることが出来なくなる。)、実行可能領域として指定された部分は、変更が不可能となるのが普通です。こうなると、特権モードのプログラム以外では、自己改変するプログラムは作れないと言うことになります。
お礼
ご回答ありがとうございます。具体的な例など、大変参考になりました。基本は0番地からだと考えていましたが、実用性の低い考え方なのですね。
- 中村 拓男(@tknakamuri)
- ベストアンサー率35% (674/1896)
>アセンブリ言語のプログラムの実行開始番地が0番地以外、というのはあり得ることなのでしょうか ありえます。 >データが格納されている番地からプログラムを開始することは可能なのでしょうか CPUによります。いわゆるハーバード・アーキテクチャでは プログラムとデータでアドレス空間が分かれていて、 データをプログラムとして実行できないものが多いですね。 逆に、データをプログラムとして実行できるCPUもあります(こっちが多数派)。 外部からプログラムをロードして実行するような場合、これが出来ないと困ります。
お礼
ご回答ありがとうございます。データをプログラムとして実行できるCPUがあったのですね!出された問いが、問題として破たんしているのかと思っていました(私の周りでそういう意見が多かったので)。大変参考になりました。
- Tacosan
- ベストアンサー率23% (3656/15482)
環境を明確にしないとなんとも答えようがないんだけど.... まず, 本質的に「データ」と「プログラム」の区別は無意味です. 例えば「OS上でプログラムを実行する」環境では OS が当該プログラムを「データとして」主記憶に読み込んだあと, その「『データ』が格納されている番地」からプログラムを実行します. つまり, そのような環境では「データが格納されている番地からプログラムを開始すること」は可能どころか必須といっていいでしょう. そうでない環境, 例えば実行すべきプログラムがあらかじめ全て決まっている組込みのような環境であっても「プログラムをいったん別のアドレスに移動」しておいて「そのアドレスから実行する」なんて手続をとることもあります. この場合も, 「プログラムを別のアドレスに移動する」という手順自体は「プログラムをデータとして扱ってる」わけだ. で「アセンブリ言語のプログラムの実行開始番地が0番地以外」だが, これを考えるにはそもそも「番地」に「物理番地」と「論理番地」の 2種類があることを認識しておかなければならない. 「物理番地」はハードウェア的に一意に決まるが, 「論理番地」は各プログラムごとに与えられた「番地」だからプログラムが違えば同じ「論理番地」であっても違う内容になっていてかまわない. で「物理番地」と解釈すると複数のプログラムが存在する場合には必然的に存在する. でもって「論理番地」と解釈しても存在する. 後者のわかりやすい例だと, MS-DOS における COMモデルのプログラムは 0x100番地から実行されるようなメモリ配置になっている (今どきの若者に通じるかどうかはこの際無視). もっと複雑な場合では, プログラム自身に「そのプログラムは何番地から実行するのか」が書いてあったりする.
お礼
ご回答ありがとうございます。プログラムそのものが「データ」であること、大変納得しました。 最初の質問にある通り、解かなければならない課題において、環境の説明がなかったので、あやふやな質問になってしまって申し訳ないです。もう少し検討してみます。
- TooManyBugs
- ベストアンサー率27% (1472/5321)
パワーオン、ハードウエアリセットなどならばi8086系は0xffff0番地からスタートします。0番地からは割り込みベクタですからプログラムとしては通常使用できません。 アプリケーションプログラムならばOSがスタートアドレスをプログラムカウンタにセットするだけですから0番地である必要は全くありませんしほとんどのOSでは0番地からスタートすることはありません。
お礼
ご回答ありがとうございます。いち数学的見地からの初歩的な課題であるため、実践的な(環境が明示されていない私の質問は実践云々の前に論外な気もしますが)見地からのご回答はとても参考になりました。
- trytobe
- ベストアンサー率36% (3457/9591)
ハードウェアが発生させるリセット信号が入力されたときに、どの番地から強制的に実行を開始するか、という設定ができる「割り込み」などの仕掛けがあるので、それによっては0番地以外から実行開始する、ということもできなくはありません。 ただ、いきなりそれを始めると、初学者がわけがわからなくなるので、まずは0番地からスタートするという前提でプログラミングができるようになってから、では任意のアドレスから実行できるような組み方を覚えましょう、と段階を踏むと思います。
お礼
ご回答ありがとうございます。割り込みについてもう少し勉強してみます。
お礼
ご回答ありがとうございます。データの羅列から実行するとそのまま0番地に戻るのかな?と思っていましたが、暴走するんですね。概念はとりあえず正しく理解できていたようなので(もちろん私が)、安心しました。 数学的見地から回答してくださったので、ベストアンサーに選ばせて頂きました。