3

MIPS プログラムを書くとき、レジスタをきれいに保つ、つまりプログラムの最後にレジスタの値を 0 にクリアするのが一般的に良い習慣だと聞いたことがあります。だから私の最初の質問は、これがどのように/なぜ必要な/良い習慣なのですか?

次に、$4 と $5 に格納されたパラメーター (p1、p2) を持つ関数呼び出しがあるとします。関数定義の最後で、$4 と $5 の値をクリアする必要がありますか? 関数呼び出しの最初の値をそのままにしておくには、それ以上のことはできませんか?

次のようにパラメーターをスタックにプッシュする例も見ました。

addi $29, $29, -8
sw $4, 0($29)
sw $5, 4($29)
; At the end of our program:
addi $29, $29, 8

いつ、なぜこれが必要な/良い習慣なのですか?

最後に、プログラムでいくつかの定数、たとえば 4 と 1 を使用する場合、レジスタとスタックのどちらに保持する方がよいでしょうか? 例えば:

lis $8
.word 4
lis $9
.word 1

そして、これらの値を何らかの方法でプログラムに使用し、後でそれらを 0 にクリアします。

または、スタック ポインターを前後に移動して、スタックに格納することもできます。どちらがより良いアプローチですか?

4

2 に答える 2

3

まず、通常 は、などの代わりに$zero使用する必要があります。単純な数値よりも理解しやすく(そして覚えやすく)、アセンブラもこの表記を理解するため、この面で問題はありません。また、これは数値からコードを抽象化するため、標準が変更された場合(たとえば、$zeroは$0ではなく$256)、コードは正しくアセンブルされます。$0$v0–$v1$2–$3

すべてのCPUアーキテクチャには、呼び出しを行うためにレジスタを使用する方法と、関数内でレジスタを操作する方法に関するいくつかの規則があります。これは呼び出し規約と呼ばれます。ここで、MIPS呼び出し規約の簡単な説明を見ることができます。

レジスタをクリーンに保つこと、つまりプログラムの最後にレジスタの値を0にクリアすることは、一般的に良い習慣だと聞いています。だから私の最初の質問は、これがどのように/なぜ必要である/良い習慣であるかということです。

私は個人的にこの慣習について聞いたことがありませんが、私はそれに完全には同意しません。プログラムを開始する前に、以前の値を復元することをお勧めします。

次に、パラメーター(p1、p2)が$4と$5に格納されている関数呼び出しがある場合。関数定義の最後で、$4および$5以上の値をクリアして、関数呼び出しの開始時のままにしておく必要がありますか?

関数呼び出しの開始時のままにしておく必要があります。呼び出し元にとって、このレジスタを変更しても意味がありません。

スタック上のスペースは、呼び出し先が引数を保存する必要がある場合に備えて$ a0〜 $ a3用に予約されていますが、呼び出し元はレジスターをそこに格納しません。

このようにパラメーターをスタックにプッシュする例も見ました。いつ、なぜこれが必要/良い習慣ですか?

定義上、一時ストレージの場合はスタック。レジスタ値をバックアップする場合(たとえば、$aXまたは$sXを使用する場合)、それらをそこに配置します。以前と同じ:

呼び出し先が引数を保存する必要がある場合に備えて、スタック上のスペースは$ a0〜$a3用に予約されています

addi $sp, $sp, -8

スタックポインタレジスタを移動します(慣例により$ 29です)。これにより、スタックに8バイトが予約されます。

sw $a0, 0($sp)
sw $a1, 4($sp)

$ a0をスタックの一番上に保存し、$ a1をスタックの2番目として保存します(スタックは低いアドレスに向かって大きくなることに注意してください)。これにより、予約済みスペース(8バイト)がいっぱいになります。これは、関数入力プロトコルと呼ばれます。

; At the end of our program:
; You forgot, and it's important:
lw $a0, 0($sp)
lw $a1, 4($sp)
addi $sp, $sp, 8

保存したレジスタを復元し、スタックポインタを元の値に戻します。その後、呼び出し元はスタックとパラメーターに変更を加えません。そして、これは関数出口プロトコルと呼ばれます。

プログラムでいくつかの定数、たとえば4と1を使用する場合、それらをレジスタまたはスタックに保持する方がよいでしょうか。

ない。定数は、イミディエートオペランドとして使用する必要があります。

li $t0, C   ; Load 16-bit constant into $t0
lui $t0, C  ; Load upper 16-bit half-word of $t0
于 2013-03-02T03:31:25.097 に答える