0

私はアセンブリ言語に非常に慣れておらず、C にもかなり慣れていません。C コードから関数呼び出しを作成する例を見てきました。アセンブリ コードには、計算を実行して値を返す関数があります (これは代入です)。 ) C コード:

#include <stdio.h>

int Func(int);

int main() 
{
int Arg;
Arg = 5;
printf("Value returned is %d when %d sent\n",Func(Arg), Arg);
}

アセンブリ コード:

.global Func
Func:    save  %sp,-800, %sp
add  %i0, -45 , %l0  
mov %l0, %i0 
ret 
restore

C コードから値を取得し、その値をアセンブリ コードの数値に加算して、新しい数値を出力します。私はこの事例を大部分理解しています。私たちの課題 (コードの変更): 「A と B の 2 つのパラメーターで Func1 を呼び出す C ソース ファイルと、Func1 と Func2 の 2 つのメソッドを含むアセンブリ ソース ファイルを作成します。Func2(Q) であるかのように、Func1 に Func2 を呼び出させます。 . Func2 はその入力引数を 2 倍にして、その 2 倍した値を Func1 に送り返す必要があります。Func1 は、値 2*A + 2*B を C メインに返す必要があります。" 私はこれを試みましたが、この解決策を見つけました(今日の時点でこれに慣れていないことを許してください)

#include <stdio.h>

int Func1(int, int);
void Func2(int, int);
int main() 
{
int Arg1 = 20;
int Arg2 = 4;
printf("Value returned is %d ",Func1(Arg1,Arg2));

}

組み立て:

.global Func1
Func1: save %sp,-800, %sp 
mov %l0, %i0
mov %l1, %i1
call Func2
nop
ret
restore

Func2: save %sp,-800, %sp
umul %i0, 2 , %l0
umul %i1, 2 , %l1
call Func1
nop

それは機能していません。私は少しも驚きません。このコードには多くの問題があると確信していますが、ここで何が起こっているか、または私が間違っていることについての完全な説明が本当に役に立ちます。

4

2 に答える 2

1

私はこれを正しく見ていますか:

In Func1, you call Func2
   which calls Func1 again
      which calls Func2 again
         which calls Func1 again
             which calls Func2 again
                 ...
Stack overflow, resulting in bad memory access and segmentation fault

明らかに、それをしないでください:)。正確に何をしたいですか?Func2からの乗算の結果を返しますか?次に、Func1からの加算の結果を返すのと同じように、それを返します。

次に、割り当ては明確に言います:

Func2(Q)であるかのようにFunc2を呼び出します。Func2は、入力引数を2倍にして、その2倍の値を送り返す必要があります

では、なぜFunc2に2つの引数を与えるのですか?有効な割り当てを想定している場合は、私が引用したこの部分のように、小さな部分で作業できます。Func2には1つの引数が必要であると書かれているので、それを信頼して1つの引数でFunc2を作成すると、1つの割り当てが完了します(その後、assignemntが無効であることが判明した場合、またはあなたをだまそうとした場合は、もちろん、それに戻る必要があります、しかし上記はかなり明確です)。


しかし、あなたを助けるために、あなたは動作するコードを持っていますよね?

.global Func
Func:    save  %sp,-800, %sp
add  %i0, -45 , %l0  
mov %l0, %i0 
ret 
restore

また、Func2の場合、-45を追加する代わりに、そのコードを2倍するように変更する必要がありますか?追加命令を次のように変更してみましたか?

imul  %i0, 2 , %l0  

(またはumulですが、Cコードでは指定し、指定intしないunsigned intので、署名されていると思います...)。


私はあなたのためにあなたのために書くつもりはありませんFunc1が、あなたはあなたがあなたのインプットをどのように得るかを見るでしょう、それは私が正しいと思います。%i0次に、戻る前に結果を生成する必要があります。小さなステップで作業します。最初に、まったく呼び出さずFunc1に戻るmakeを作成します。次に、一度呼び出してみてください。次に、最後に要求されたバージョンの呼び出しを2回記述します(または、より少なく単純なコードの場合は、共通の要素を抽出して、1回だけ呼び出す必要があります)。%i0 + %i1Func22 * %i0 + %i1Func22 * %i0 + 2 * %i1Func2Func2

于 2013-01-29T06:48:28.807 に答える
1

値をfunc1に戻すために、func2がfunc1を再度呼び出さないようにする必要があります。関数がfunc1に値を返すようにします。関数の戻り値は、ほとんどのプロセッサのABIであるレジスタi0に保存する必要があります。

  1. メインは値を使用してfunc1を呼び出します
  2. func1はi0から引数を読み取ります
  3. func1はi0の引数を使用してfunc2を呼び出します
  4. func2は引数を乗算し、%l0に保存します
  5. 値をi0に戻し、
于 2013-01-29T06:49:01.787 に答える