2017/01/14 13:00- compiler seminer [前回] 機械語によるプログラミング # - 「昔はこうだったぁ..」 # - 「tool がないとどうなるか ?」を体験する事により # 「tool の有難み」を実感してもらおう.. # どんな機能が必要か (実現すべきか ?) # アマチュアの発想 (まず、自分がユーザ) # 「プロの料理人は味見しないが、アマはしないと駄目」 「何が、問題だったか ?」 を問いたい 機械語でプログラムを書く上で、何が「困った」か その「コマッタ」所を tool でサポートする <辛かった所> ASCII メモリマネージメント プログラムとデータの address 計算 ? -> 機能追加をする アセンブリ言語で記述されたプログラム | | アセンブラ v 機械語のプログラム | | CPU エミュレター v 実行 == <辛かった所> !! 気になった点 !! ex-001 !! 似たような事を何度も行っている !! 入力してから、「数字」を「数値」に変換 !! 「数値」を「数字」にしている !! 定数 ( 48 ) をどうするか ? !! 「'0' 」 ASCII Code を直接かける !! ラベルが使いたい !! 「定数名」が扱えると嬉しい !! メモリを初期化する疑似命令 !! メモリの領域を確保する疑似命令 !! ex-002 !! 共通化 !! 条件文で、分岐が生じたので、ラベルが.. ASCII メモリマネージメント プログラムとデータの address 計算 ? -> 機能追加をする [機能拡張] - ASCII を表現する 既に実現済 構文 : ' + 一文字 + ' 意味 : その一文字の ASCII Code - 似たような事を何度も行っている サブルーチンコール ( CPU の機能を追加 ) 命令: 「CALL 番地」で、サブルーチンコール 「RET 」で、元に戻る # IBM 360 CPU : サブルーチンコールがない # ex 命令 : pc と acc を交換する # call : acc に番地をいれて ex # サブルーチン acc をメモリに保存 # サブルーチン毎に帰り場所のアドレスを保存する # この場所が一つなので、再帰呼出ができない (Fortran) # ret : メモリから address もどし ex 実装: call addr 元 pc を stack いれ、 pc に addr をいれる ret stack から addr をとりだし、pc にいれる -> stack を実装する必要がある stack の実装の一番簡単な方法は 配列 + Stack Pointer 「配列」= 実メモリ 慣習的にスタックはメモリの後ろを利用する Label 機能の追加 Label : 場所に付けた名前の事で、アドレスを表現する アドレスの計算を、アセンブラに任せられる どこに使うか どう実現するか 文字列と値(整数値)の対応なので、 set/get があればよい set : 上書きはなくてもよい(実現はする) <仕様> set : ラベル名と値を指定し、ラベル名の値を決める get : ラベル名を指定し、そのラベル名に対応する値を返す 例外 : どれも、不適切だがサボろう (共通) 領域が足りなくなる error stop (本当はよくないが..) (set) 多重定義 上書き (get) 未定義 [当初案] -1(NOT_FOUND) を返す address は「非負の数」なので、 未定義かどうか判定できる !! 「address は『非負の数』」は「保証」されていない(仕様変更されるかもしれない) !! 危険なアプローチ [実施案] エラーにする かわりに search_label を使う やっぱり「エラー」は別扱い 前方参照の問題 後で、定義されるラベルを前(方) で参照すると ? (後方参照:定義されてから、利用される -> 問題なし) label: <= 定義 ... goto label <= 利用 (前方参照:定義される前に、利用される -> 問題が..) goto label <= 利用 ... label: <= 定義 解決方法 伝統的やりかた : 2 pass 1 pass 目で label の値をきめ 2 pass 目で、code を作る 最近 : 1 pass 定義されていないラベルの管理を行う label の実装 label 定義 構文 :