2

スタックにプッシュすることで、4以外の追加の引数を使用するように関数をプログラムしようとしています(私のバージョンのmipsは$ a0〜 $ a3しかサポートしていないため)が、私のコードは正しくありません。これがメインの私のコードです(スニペット):

li $t0,40 #temp value for our 5th arg.

addi $sp, $sp, -4 #decrement stack pointer by 4
sw $t0, 0($sp) #save the value of $t0 on the stack.

jal printf

これは一時的な値を40に設定し、スタックにスペースを与えて保存します。その後、私の関数が呼び出されます。これが機能するかどうかを確認するためのテストとして、これらの一時引数$ a0〜 $ a3を対応する保存済みレジスタに移動するときの関数内で、次のコードがあります。

lw $t0, 0($sp) 
addi $sp, $sp, 4
move $a0,$t0

li $v0, 1
syscall

...しかし、それは0を出力するだけで、40は出力しないので、何か間違ったことをしています。どんな助けでも大歓迎です(そして賛成)

4

3 に答える 3

3

最も一般的な32ビットMIPS呼び出し規約$a0,$a1,$a2では、スペースはとのスタックに予約されている$a3ため、呼び出された関数はで5番目の引数を見つけることを期待する必要があります16($sp)

これらを理解する最も簡単な方法は、関数の空のバージョンをCで記述し、.oファイルを逆アセンブルして、引数がコンパイラーによってどのように渡されるかを理解することです。

于 2012-04-18T18:11:07.397 に答える
0

そのコードは絶対に正しいので、問題は他の場所にあります。私の推測では、コード内のその時点までスタックポインターが正しく管理されていないか、printfスタックをポップオフする前にエラーが発生しています。デバッガーを使用して何が起こっているかを確認してみませんか?可能であれば、問題を示すすべての無関係なコードを取り除いた実行可能なプログラムを投稿してください。これは、あなたがやろうとしていることを実行し、同じ命令を使用する、動作するMIPSプログラムです。

于 2012-04-18T20:36:24.850 に答える
0

上でリンクした完全なコードを見ることから、あなたが扱っている2つの問題があります。

1)標準のMIPS o32呼び出し規約に引数(特に4つ以上)を使用するようにスタックが適切に設定されていません。他の答えは、これを助けるためにあなたを指し示すのに良い仕事をします。

2)使用している「printf」は、標準の呼び出し規約をまったく使用していません。コメントが表示された場合:

## printf--
## A simple printf-like function. Understands just the basic forms
## of the %s, %d, %c, and %% formats, and can only have 3 embedded
## formats (so that all of the parameters are passed in registers).
## If there are more than 3 embedded formats, all but the first 3 are
## completely ignored (not even printed).
## Register Usage:
## $a0,$s0 - pointer to format string
## $a1,$s1 - format argument 1 (optional)
## $a2,$s2 - format argument 2 (optional)
## $a3,$s3 - format argument 3 (optional)
## $s4 - count of formats processed.
## $s5 - char at $s4.
## $s6 - pointer to printf buffer

スタックに何も渡されることは期待されていません。($ s0-6はスタックに関連していないことに注意してください)。この関数に$a0->フォーマット文字列と3つの引数($ a1、$ a2、および$ a3)を提供できます。これらのコメントは、$ s0〜 $ s6を破壊することを示唆していることに注意してください。ただし、不完全なコードから、トレースせずにどれだけ復元されるかを言うことができます。要するに、あなたが見つけたこのprintfは便利かもしれませんが、あなたが学ぶべきスタック規則を使用しておらず、かなり制限されています。あなたがそれを使用する許可を持っていると仮定して、変更する許可を取得することについて見て、そしてただインターフェースを何か正気に書き直してください。一度に3つ以上の変数を出力する必要がある場合は、関数を複数回呼び出す必要があることに注意してください(そうであれば、ラッパーを作成するだけです)。

于 2012-04-23T21:32:45.130 に答える