コンパイラ資料 実行時環境.

Slides:



Advertisements
Similar presentations
コンパイラ演習 第 6 回 2005/11/17 大山 恵弘 佐藤 秀明. 今回の内容 実マシンコード生成 – アセンブリ生成 (emit.ml) – スタブ、ライブラリとのリンク 末尾呼び出し最適化 – 関数呼び出しからの効率的なリターン (emit.ml) –[ 参考 ]CPS 変換 種々の簡単な拡張.
Advertisements

2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
2006/10/26 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
2006/11/9 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
ソフトウェアを美味しく 解析する方法 Security Ark
App. A アセンブラ、リンカ、 SPIMシミュレータ
ソフトウェアとのインターフェース.
コンパイラ資料 中間コード a.
プログラミング言語論 第4回 手続きの引数機構 変数の有効範囲
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
2006/11/02 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
コンパイラ演習 第 4 回 (2011/10/27) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴
アルゴリズムとデータ構造1 2009年6月25日
第4回放送授業.
アルゴリズムとデータ構造 第2回 線形リスト(復習その2).
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
関数 関数とスタック.
コンパイラの解析 (4) 例外処理.
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
言語プロセッサ2007 平成19年9月26日(水) (Ver.2 平成19年10月3日変更)
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
目的コードの生成 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第9章.
セキュリティ(3) 05A2013 大川内 斉.
プログラミング言語論 第9回 Hoare論理の練習問題 手続きの引数機構 変数の有効範囲
コンピュータ系実験Ⅲ 「ワンチップマイコンの応用」 第1週目 アセンブリ言語講座
プログラミング入門2 第11回 情報工学科 篠埜 功.
アルゴリズムとデータ構造 2010年6月28日
アルゴリズムとデータ構造1 2005年6月28日
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
A Provably Sound TAL for Back-end Optimization について
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
フロントエンドとバックエンドのインターフェース
プログラミング言語論 第5回 手続きの引数機構 変数の有効範囲
オブジェクト指向プログラミングと開発環境
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
JAVAバイトコードにおける データ依存解析手法の提案と実装
参照されないリテラル 長谷川啓
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
コンピュータアーキテクチャ 第 2 回.
コンピュータアーキテクチャ 第 4 回.
ポインタとポインタを用いた関数定義.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
コンピュータアーキテクチャ 第 2 回.
コンピュータアーキテクチャ 第 5 回.
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
コンピュータアーキテクチャ 第 4 回.
第5回 プログラミングⅡ 第5回
第4回 CPUの役割と仕組み2 命令の解析と実行、クロック、レジスタ
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
コンピュータアーキテクチャ 第 5 回.
卒業論文に向けて(3) 学部4年生 島本 大輔 2004年11月11日.
X64 函数呼び出し規約 長谷川啓
Inline 展開のアルゴリズム 長谷川啓
コンパイラ 第12回 実行時環境 ― 変数と関数 ― 38号館4階N-411 内線5459
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
演算子のオーバーロード.
プログラミング演習I 2003年6月11日(第9回) 木村巌.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
プログラミング言語論 プログラミング言語論 演習5 解答と解説 演習5 解答と解説 1 1.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
6.5 最終コード生成 (1)コードの形式 ①絶対2進コード(AB : absolute binary) 命令後のオペランドが絶対番地指定。
プログラミング 2 静的変数.
Presentation transcript:

コンパイラ資料 実行時環境

本日のメニュー: 関数の翻訳 関数によるスタック利用の詳細 関数定義・呼び出しの翻訳(AST→IR) x86 MASM assembler 本日のメニュー: 関数の翻訳 関数によるスタック利用の詳細 x86 MASM assembler スタック領域(フレーム)の管理・利用のコード 関数定義・呼び出しの翻訳(AST→IR) FUN, ARGS, CALL, RTNノード

実行時環境 activation record 関数呼び出しを持つ言語の場合  関数の呼び出しごとに割り当てられるメモリ領域のこと、またその領域に格納される情報 通常はスタックを用いるのでactivation recordのことをスタックフレームまたは単にフレームとよぶ。

関数定義と関数呼び出し int foo(int x) //関数定義、呼び出し元(親) { int y; if(x=0)y:=1; else y=x+ bar(x-1);//関数呼び出し(子) return y; //リターン文 }

今のフレーム(自分) 自分を呼び出した親のフレーム フレームのレイアウト 上: 低アドレス 下: 高アドレス 引数0 ←esp  スタックポインタ 上: 低アドレス … 引数m-1 spills 今のフレーム(自分) 局所変数 退避callee-save 退避ebp ←ebp フレームポインタ 戻りアドレス 引数0 … 自分を呼び出した親のフレーム 下: 高アドレス 引数n-1 フレームのレイアウト

呼び出し動作 call push ebp mov ebp, esp sub esp, (SIZE-2)*WRD, mov [ebp – WRD ], ebx mov [ebp- 2*WRD ], esi mov [ebp - 3*WRD ], edi body ←esp  mov esp, ebp pop ebp ←ebp  ret

呼び出し規約 calling convention cdecl レジスタesi, edi, ebp, ebxは呼び出し前後で値が変化してはいけない。呼び出された側で使うときは退避してから使い、おわったらもどす。(callee-save) そのほかの(汎用)レジスタは呼び出し側で退避する。(caller-save) 引数の積み込み順序は最後の引数が最初

フレームサイズの決定 フレームサイズSIZE未定のまま、次を翻訳時・レジスタ割り当て時にカウントし、IR生成完了後にSIZEを埋める 使用するcallee-save registerの個数 ローカル変数の同時使用個数の最大値 レジスタからあふれた(spill)数の最大数 caller-save退避用含む 呼び出す関数の引数の最大値(関数ごと/一律)

関数定義コードの構成 prologue epilogue 関数名のラベル(第1子から取得) (第2子から引数リスト取得) 呼び出し元ベースポインタの退避 ベースポインタ更新 スタックフレームの作成 callee-saveレジスタ退避 関数本体 エピローグラベル callee-saveレジスタ復帰 スタックフレーム解放 呼び出し元ベースポインタ復帰 リターン prologue epilogue

prologue/epilogue prologue: push ebp mov ebp, esp sub esp, (SIZE-2)*WRD mov [ebp-4], ebx, mov [ebp-8], esi mov [ebp-12], edi epilogue : mov edi, [ebp-12] mov esi, [ebp-8] mov ebx, [ebp-4] mov esp, ebp pop ebp ret 使うものだけ 使ったものだけ

関数本体からの参照(IDノードで) 自分 親 仮引数 局所変数 引数kはベースポインタのk+2個下 [ebp+(k+2)*WRD] 引数0 ←esp   仮引数 引数kはベースポインタのk+2個下  [ebp+(k+2)*WRD] (k = 0,1,…) 局所変数 出現順(i=0,…)に記号表に場所を登録  [ebp-(i+S+1)*WRD] S=使用するcallee-save reg.の数 … 引数m-1 spills 自分 局所変数 退避callee-save 退避ebp ←ebp 戻りアドレス 引数0 … 親 引数n-1

リターン文(RTNノードで) 戻り値(リターン文引数の値)をeaxに置く エピローグラベルにjmp

関数呼び出し(Call) 呼び出し側利用レジスタ退避(caller-save) 実引数をespから下(高位)に向かって順に積む 引数jは[esp+j*WRD]  (j=0,…) call XXX 戻り値取り出し, 値置き用レジスタ t にコピー movl t, eax 呼び出し側利用レジスタ復帰

呼び出し時の実引数格納場所 自分 親 引数jは [esp+j*WRD ] に格納する。 引数0 ←esp … 引数m-1 spills 局所変数 退避callee-save 退避ebp ←ebp 戻りアドレス 引数0 … 親 引数n-1

Accessの印字まとめ reg(n) : eax, ebx, ecx, edx, esi, edi (n=0,1,2,3,4,5) reg(n): [ebp-(WRD*(n-REG_SIZE+L+S+1)] (n>= REG_SIZE=6) formal(n) : [ebp+WRD*(n+2)] //退避ebpのn+2個下(n=0,1,...) local (n) : [ebp -(WRD*(n+S+1)) ] //退避ebpのn+S+1個上(n=0,1,...) arg (n) : [esp+WRD*n]   //esp以下に積む (n=0,1,...) label(n) : L_n  L=関数内の局所変数の数 S=使用したcallee-saveレジスタ数(=退避数) 上下は図の上/下(アドレスの低/高の方向)

課題:Print printf(“%d\n”, 5); print文は外部関数(Cの標準ライブラリ)を呼び出す命令列に翻訳する。 Cでつぎの関数呼び出しに対応するアセンブリコードを調べてAST/Printノードの翻訳処理を追加せよ。 printf(“%d\n”, 5); ヒント:第1引数の定数文字列を表す専用Accessを導入せよ。

課題:IR_visitor(完全版) 6章のIR_visitorに関数定義、リターン文、関数呼び出しのケースを加筆してIRへの翻訳を完成させよ。 (prologue, epilogueは定型なのでそれぞれ1つのInstrとしてよい。)