2015.11.18 コンピュータアーキテクチャI 課題解答例 (第 7 回) 1. 講義ノート 4 の演習 7,演習 8 をやってください. 演習 7: main 関数の変数 g,h,i,j,k はそれぞれ$s0, ..., $s4 に割り当てられているものとする. #main 関数のコンパイル main: .... addi addi #s0, $zero, 1 #s1, $zero, 2 #g=1 #h=2 addi addi #s2, $zero, 3 #s3, $zero, 4 #i=3 #j=4 add add add $a0, $s0, $zero $a1, $s1, $zero $a2, $s2, $zero #g を引数レジスタにコピー #h を引数レジスタにコピー #i を引数レジスタにコピー add jal $a3, $s3, $zero func1 #j を引数レジスタにコピー #func1 の呼び出し.このとき$ra に戻り add $s4, $v0, $zero ...... #アドレスがセットされることに注意 #戻り値 ($v0 にある) を k に代入 演習 8: #define STACKSIZE 4096 int stack[STACKSIZE]; int stkp=-1; として, void push(int data); /*data を stack に積む.*/ int pop(); /*stack トップのデータを返す.*/ の本体を書く. void push(int data){ if(stkp<STACKSIZE-1) { stack[++stkp]=data; } else { printf("Error process"); }} int pop(){ if(stkp<0) { printf("error process"); } else { 1 return stack[stkp--]; }} 2. 講義ノート 4 の演習 9 を考えてみてください. 演習 9: func1: addi sw sw sw $sp, $sp, -12 $t1, 8($sp) #func1 のコンパイル #stack 上に 3 語分の領域を確保 #$t1 をセーブ (中間結果の保存のために使用) $t0, 4($sp) $s0, 0($sp) #$t0 をセーブ (中間結果の保存のために使用) #$s0 をセーブ (f 用に$s0 を使うため) #ここから関数本体のコンパイル add $t0, $a0, $a1 sub $t1, $a2, $a3 sub add $s0, $t0, $t1 $v0, $s0, $zero #レジスタの回復 lw $s0, 0($sp) lw $t0, 4($sp) #g+h #i-j #f=(g+h)-(i-j) #戻り値を$v0 にセット #$s0 を回復 #$t0 を回復 lw $t1, 8($sp) #$t1 を回復 #Stack pointer を呼び出し前の状態に戻す addi $sp, $sp, 12 #リターン jr $ra #$ra には戻りアドレスが入っている 2 3. 教科書の問題 2.18.4 から 2.18.6 を行え. 問題 2.18.4 a. lw から bne までが 100 回繰り返される.よって,5x100+1=501 命令実行される. b. LOOP: lw から bne まで 50 回繰り返される.よって,6x50+1=301 命令実行される. 問題 2.18.5 a. i=100; do result+=MemArray[i]; while(--i>0); b. int *p, *i; i=&MemArray[100]; p=MemArray; do {result+=p[0]; result+=p[1]; p=p+8;} while(i!=p); 言い訳:C のプログラムを書かなくなって久しいので、ひょっとすると文法違反をしているかも しれません。間違いがあったら指摘してください。 問題 2.18.6 a. addi $t1, $s0, 400 LOOP: lw add addi $s1, 0($s0) $s2, $s2, $s1 $s0, $s0, 4 bne $t1, $s0, LOOP ループ内 1 命令削減 b. addi LOOP: lw add $t1, $s0, 400 $s1, 0($s0) $s2, $s2, $s1 addi $s0, $s0, 4 bne $t1, $s0, LOOP ループ内 2 命令削減 3
© Copyright 2024 ExpyDoc