先端ソフトウェア工学II スケジュール 10/8,22,29,11/19,26:組込みプログラミン グ 担当 宮本 10/15,11/5,11/12:組込み信号処理 担当 岡田 組込みシステムとは? 組込みシステムの例 携帯電話 ゲーム機 ディジタル家電 車載機器(解釈によっては自動車そのもの) etc 定義 厳密な定義があるわけではなく、製品に組込 まれている汎用ではないディジタルシステム のことを言う。 組込みプログラミングの特色 開発環境がクロスであることが多い OSの機能が制限されている(場合によって は無い) プロセッサ周辺のデバイスを叩く必要があ ることが多い スタートアップコードを書かなければならな いこともある リソースが制限されている クロス開発とは? 開発対象(ターゲット)と開発環境(ホスト) が異なる 多くはバイナリ互換性も無い RS232C or Ether 組込みシステムの開発手順 通常のアプリケーション コーディング コンパイル デバッグ 組込みシステム コーディング クロスコンパイル ダウンロード クロスデバッグ 開発における考え方 目的を定める 制約条件を調べる 例)メモリサイズの制限 最適な実装方式の検討を行う 例)速度を向上するor電力を最小化する 例)最も支配的な処理の実装を効率化 仕様決定&コーディング トップダウンアプローチが必須 顧客が本当に必要だったもの 理解しなければならないこと プロセッサの仕組み 演算 制御 ソフトウェアとハードウェアのインターフェース オブジェクトコード リンカ ローダ デバイスドライバ スタートアップルーチン/BIOS オペレーティングシステム(OS) プロセッサの仕組み 参考書 コンピュータの構成と設計~ハードウエア とソフトウエアのインタフェース 第3版 (上) (単行本) デイビッド・A. パターソン (著), ジョン・L. ヘネシー (著), David A. Patterson (原著), John L. Hennessy (原 著), 成田 光彰 (翻訳) プロセッサの構成要素 プログラムカウンタ:命令の位置を保持 レジスタ:データを保持 メモリバス:命令・データの読み書き メモリ:命令・データを保持 命令デコーダ:命令を解釈 算術論理演算器(ALU):演算を実行 プロセッサの基本的な構造 0 メモリバス PC r0 r4 命令 デコーダ r1 r5 制御処理 メモリ r2 r6 r3 r7 7 ALU 演算処理 15 リセット メモリ 0 メモリバス PC 命令 デコーダ 制御処理 0 r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 0番地の命令のフェッチ 0 メモリバス PC 命令 デコーダ 制御処理 0 メモリ r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 1 メモリ r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 2 メモリ r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 3 メモリ r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 4 メモリ r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 分岐命令 メモリ 0 メモリバス PC 4 命令 デコーダ 制御処理 命令:PCに0を代入 r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 分岐命令 メモリ 0 メモリバス PC 0 命令 デコーダ 制御処理 PCに0を代入 r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 0番地の命令のフェッチ 0 メモリバス PC 命令 デコーダ 制御処理 0 メモリ r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 ロード命令 メモリ 0 メモリバス PC 命令 デコーダ 制御処理 1 r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 ロード命令 メモリ 0 メモリバス PC 命令 デコーダ 制御処理 1 r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 命令:r0に16番地のデータをロード 演算処理 15 ロード命令 メモリ 0 メモリバス PC 命令 デコーダ 制御処理 1 r0 0 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 命令:r0に16番地のデータをロード 演算処理 15 1 ロード命令 メモリ 0 メモリバス PC 命令 デコーダ 制御処理 1 r0 1 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 2 メモリ r0 1 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 3 メモリ r0 1 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 ロード命令 メモリ 0 メモリバス PC 命令 デコーダ 制御処理 3 r0 1 r4 0 r1 0 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 命令:r1に17番地のデータをロード 演算処理 15 2 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 4 メモリ r0 1 r4 0 r1 2 r5 0 r2 0 r6 0 r3 0 r7 0 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 4 r0 1 r4 0 r1 2 r5 0 r2 0 r6 0 r3 0 r7 0 命令:r2にr0とr1を加えて代入 メモリ 7 ALU 演算処理 15 命令実行&PCインクリメント 0 メモリバス PC 命令 デコーダ 制御処理 4 メモリ r0 1 r4 0 r1 2 r5 0 r2 3 r6 0 r3 0 r7 0 7 ALU 演算処理 15 ソフトウェアとのインターフェース アセンブリ言語 MIPS アセンブリ言語による加算 動作 a=b+c 減算 add a, b, c sub a, b, c 動作 a=b-c オペランド アセンブリ言語 MIPS アセンブリ言語による加算 動作 a=b+c 減算 add a, b, c sub a, b, c 動作 a=b-c ディスティネーション オペランド アセンブリ言語 MIPS アセンブリ言語による加算 動作 a=b+c 減算 add a, b, c sub a, b, c 動作 a=b-c ソース オペランド Cからアセンブリ言語への変換 C コード a=b+c; d=a-e; アセンブリコード add a,b,c sub d,a,e Cからアセンブリ言語への変換 C コード f=(g+h)-(i+j); アセンブリコード add t0,g,h add t1,i,j sub f,t0,t1 メモリにある値をオペランドとした演算 C コード g=h+A[8]; アセンブリコード lw $t0,8($s3) add $s1,$s2,$t0 #h は$s2に格納 lw : 1ワードをロードする命令 この場合、8+$s3のアドレスをロードする 今の例では32bitを考えているので1wordは32bit lw メモリ 0 メモリバス lw $t0,8($s3) add $s1,$s2,$t0 PC 命令 デコーダ 制御処理 0 s0 0 s4 0 s1 0 s5 0 s2 h t0 0 s3 7 t1 0 7 ALU 演算処理 15 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] lw メモリ 0 メモリバス lw $t0,8($s3) add $s1,$s2,$t0 PC 0 s0 0 s4 0 命令 デコーダ lw $t0,8($s3) s1 0 s5 0 制御処理 s2 h t0 0 s3 7 t1 0 7 ALU 演算処理 15 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] lw メモリ 0 メモリバス lw $t0,8($s3) add $s1,$s2,$t0 PC 命令 デコーダ 制御処理 0 s0 0 s4 0 s1 0 s5 0 s2 h t0 0 s3 7 t1 0 7 ALU 演算処理 15 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] lw メモリ 0 メモリバス lw $t0,8($s3) add $s1,$s2,$t0 PC 命令 デコーダ 制御処理 0 s0 0 s4 0 s1 0 s5 0 s2 h t0 A[8] s3 7 t1 0 7 ALU 演算処理 15 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] add メモリ 0 メモリバス lw $t0,8($s3) add $s1,$s2,$t0 PC 1 s0 0 s4 0 命令 デコーダ add $s1,$s2,$t0 s1 0 s5 0 制御処理 s2 h t0 A[8] s3 7 t1 0 7 ALU 演算処理 15 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] add メモリ 0 メモリバス lw $t0,8($s3) add $s1,$s2,$t0 PC 1 s0 0 s4 0 命令 デコーダ add $s1,$s2,$t0 s1 h+A[8] s5 0 制御処理 s2 h t0 A[8] s3 7 t1 0 7 ALU 演算処理 15 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] lw メモリ 0 メモリバス lw $t0,8($s3) add $s1,$s2,$t0 PC 0 s0 0 s4 0 命令 デコーダ lw $t0,8($s3) s1 0 s5 0 制御処理 s2 h t0 0 s3 7 t1 0 7 ALU 演算処理 ベースレジスタ オフセット 15 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] メモリのアドレス 通常、多くのアーキテクチャではbyteつま り8bitを単位としてアドレスを表現する。 今までの図はワードアドレスとしては正しいが バイトアドレスとしては正しくない。MIPS32を 仮定すると1word=32bit=4byte 先のアセンブリコードは本来以下のようになる。 lw $t0,32($s3) add $s1,$s2,$t0 #h は$s2に格納 バイトアドレス メモリ メモリバス PC r0 r4 命令 デコーダ r1 r5 制御処理 r2 r6 r3 r7 3 0 31 28 63 60 ALU 演算処理 ロードとストアが使用されるコード C コード A[0]=h+A[8]; アセンブリコード lw $t0,32($s3) add $t0,$s2,$t0 #h は$s2に格納 sw $t0,0($s3) lw メモリ 3 lw $t0,32($s3) メモリバス 0 add $t0,$s2,$t0 sw $t0,0($s3) PC 命令 デコーダ 制御処理 0 s0 0 s4 0 s1 0 s5 0 s2 h t0 0 s3 28 t1 0 31 ALU 演算処理 63 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] 28 60 lw メモリ 3 lw $t0,32($s3) メモリバス 0 add $t0,$s2,$t0 sw $t0,0($s3) PC 命令 デコーダ 制御処理 0 s0 0 s4 0 s1 0 s5 0 s2 h t0 A[8] s3 28 t1 0 31 ALU 演算処理 63 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] 28 60 add メモリ 3 lw $t0,32($s3) メモリバス 0 add $t0,$s2,$t0 sw $t0,0($s3) PC 命令 デコーダ 制御処理 1 s0 0 s4 0 s1 0 s5 0 s2 h t0 A[8] s3 28 t1 0 ALU + 演算処理 31 63 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] 28 60 add メモリ 3 lw $t0,32($s3) メモリバス 0 add $t0,$s2,$t0 sw $t0,0($s3) PC 命令 デコーダ 制御処理 1 s0 0 s4 0 s1 0 s5 0 s2 h t0 h+A[8] s3 28 t1 0 31 ALU 演算処理 63 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] 28 60 sw メモリ 3 lw $t0,32($s3) メモリバス 0 add $t0,$s2,$t0 sw $t0,0($s3) PC 命令 デコーダ 制御処理 2 s0 0 s4 0 s1 0 s5 0 s2 h t0 h+A[8] s3 28 t1 0 31 ALU 演算処理 63 A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] 28 60 sw メモリ 3 lw $t0,32($s3) メモリバス 0 add $t0,$s2,$t0 sw $t0,0($s3) PC 命令 デコーダ 制御処理 2 s0 0 s4 0 s1 0 s5 0 s2 h t0 h+A[8] s3 28 t1 0 31 ALU 演算処理 63 h+A[8] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] 28 60 コンピュータ内での命令の表現 アセンブリコード add $t0,$s1,$s2 マシンコード 000000 10001 10010 01000 000000 100000 MIPSのフィールド R形式 op rs rt rs rt rd shamt funct I形式 op constant or address 条件判定(if-then-else) C コード if(i==j) f=g+h;else f=g-h; アセンブリコード bne $s3,$s4,Else #i と j が等しくなければ Else add $s0,$s1,$s2 j Exit #Exit へジャンプ Else: sub $s0,$s1,$s2 Exit: 条件判定(while) C コード while(a[i]==k) i+=1; アセンブリコード Loop:sll $t1,$s3,2 #$3を2ビットシフト=i*4 add $t1,$t1,$s6 #ベースアドレス加算 lw $t0,0($t1)#a[i]をロード bne $t0,$s5,Exit#a[i] と k の比較 addi $s3,$s3,1 j Loop Exit: 関数呼び出し 関数実行の手順 関数からアクセス可能な場所に引数を置く 関数に制御を移す 関数に必要なメモリ資源の確保 処理の実行 呼び出し元からアクセス可能な場所に結果を置く 制御を元に戻す 関数呼び出し用レジスタ 引数用レジスタ 返り値用レジスタ $a0-$a3 $v0-$v1 アドレス退避用レジスタ $ra 関数専用命令 ジャンプ&リンク命令 jal $raにPC+4を退避して指定のアドレスをPCに セットする 関数から戻る時には jr 命令を用いる。 jr $ra; より多くのレジスタが必要な場合 スタックの利用 スタック:LIFO(Last In First Out)の待ち行列 スタックポインタ$spで指定 プッシュ 1 をプッシュ 2 をプッシュ 1 1 2 高位 アドレス $sp $sp 低位 アドレス $sp ポップ 2 をポップ 1 をプッシュ 高位 アドレス $sp $sp 低位 アドレス 1 $sp 1 2 関数の呼び出し C コード int leaf_example(int g,int h,int i,int j){ int f; f=(g+h)-(i+j); return f } 関数の呼び出し 引数を受け取る 返り値を返す $a* $v* レジスタを関数呼び出し前の状況に戻す スタックに退避 関数の呼び出し アセンブリコード leaf_example: addi $sp,$sp, -12#スタックに3つスペース確保 sw $t1,8($sp) #関数で$t1を使うのであらかじめ退避 sw $t0,4($sp)#同じく$t0を退避 sw $s0,0($sp)#同様 add $t0,$a0,$a1#$a0=g $a1=h add $t1,$a2,$a3#$a2=i $a3=j sub $s0,$t0,$t1 add $v0,$s0,$zero#f を返す$zeroは0 関数の呼び出し アセンブリコード add $t0,$a0,$a1#$a0=g $a1=h add $t1,$a2,$a3#$a2=i $a3=j sub $s0,$t0,$t1 add $v0,$s0,$zero#f を返す$zeroは0 lw $s0, 0($sp) #退避した値の復旧 lw $t0,4($sp) lw $t1,8($sp) addi $sp,$sp,12 #スタックポインタの復旧 jr $ra #呼び出し元に戻る Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 0 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 60 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 0 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 60 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 0 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 4 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 4 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 7 ALU 演算処理 28 48 52 56 60 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 8 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 8 7 ALU 演算処理 28 48 52 56 60 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 12 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 演算処理 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 48 52 56 60 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 16 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 16 s0 v0 9 0 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 16 s0 v0 9 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 20 s0 v0 9 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 20 s0 v0 9 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 24 s0 v0 9 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 24 s0 v0 9 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 7 8 9 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 24 s0 v0 -4 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 28 s0 v0 9 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 28 s0 v0 -4 0 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 28 s0 v0 -4 -4 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 32 s0 v0 -4 -4 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 32 s0 v0 -4 -4 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 32 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 36 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 1 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 36 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 40 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 5 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 40 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 44 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 44 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 48 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 44 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 60 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 48 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 60 ra ALU 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 9 8 7 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 48 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 60 ra 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 本当はここにjr$ra 8 7 ALU 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 48 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 60 ra 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 本当はここにjr$ra 8 7 ALU 60 演算処理 Func call メモリ addi $sp,$sp, -12 メモリバス 0 sw $t1,8($sp) sw $t0,4($sp) PC 命令 デコーダ 制御処理 64 s0 v0 9 -4 a2 a3 2 3 a0 0 t0 8 a1 1 t1 7 sp 60 ra 64 sw $s0,0($sp) add $t0,$a0,$a1 add $t1,$a2,$a3 sub $s0,$t0,$t1 add $v0,$s0,$zero 28 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) addi $sp,$sp,12 本当はここにjr$ra 8 7 ALU 60 演算処理 関数の呼び出し 退避 sw $t1,8($sp) #関数で$t1を使うのであらかじめ退避 sw $t0,4($sp)#同じく$t0を退避 sw $s0,0($sp)#同様 復旧 lw $s0, 0($sp) #退避した値の復旧 lw $t0,4($sp) lw $t1,8($sp) 毎回やるとウザイ $t0-$t9を復旧しなく てもよいことにする 関数の呼び出し アセンブリコード leaf_example: addi $sp,$sp, -4#スタックに1つスペース確保 sw $s0,0($sp)#同様 add $t0,$a0,$a1#$a0=g $a1=h add $t1,$a2,$a3#$a2=i $a3=j sub $s0,$t0,$t1 add $v0,$s0,$zero#f を返す$zeroは0 lw $s0, 0($sp) #退避した値の復旧 addi $sp,$sp,4 #スタックポインタの復旧 jr $ra #呼び出し元に戻る 新しいデータ用の領域割り当て 関数内の変数だがレジスタに割り付けられ ないもの 配列 データ構造 フレームポインタ $fp のを利用して対応 フレームポインタの利用 高位 アドレス $fp $sp 関数呼び出し前 関数呼び出し中 $fp=$sp として$sp を保存 $fp $fp 退避された引 数レジスタ 退避された戻りアドレス 退避されたレジ スタ 低位 アドレス $sp $sp=$fp として$sp を復旧 ローカルな配列 とデータ構造 $sp 関数呼び出し後 ヒープの利用 動的に確保可能なメモリ領域 malloc や new で確保 $sp スタック 動的データ テキストセグメント:MIPSの機械語コード 静的データセグメント:静的変数、定数、配列 $gp PC 0 静的データ テキスト 予約済み プログラムの翻訳と起動 コンパイル アセンブル リンク ロード 実行 おわり
© Copyright 2024 ExpyDoc