2016-03-28 9 views
0

これは宿題です。私は今かなり間違っていることを理解しようとしています。割り当ては次のとおりARMループcmp問題

はCで次のコードを検討:

int foo(int a, int b) 
{ 
if (a > b) return 0; 
if (a == b) return b; 
return a + foo(a+1, b); 
} 

をアセンブリ内でこの機能を実装します。 関数から分岐した後、出力は次のようになります。次に、ユーザは、4 を入力した場合10:4 10 49

END

ユーザーは10、その後4に入った場合:

ENDを

私のコードので、遠い:

@main program 
_start:   
    mov sp,#0x100000  @ set up stack 

    ldr r4,=0x101f1000  
    @ ASCII codes stored 
    @ at [r4] get printed 

    @ get input 
    bl get_int 
    mov r5, r0 
    bl get_int 
    mov r6, r0 

    @ mov a to r0 b to r1 
     mov r0, r5 
     mov r1, r6 

    @ branch to the function you write 
     bl foo 

    @ print the number in r0 after branching back from your function 
     bl print10 

     @ branch to exit 
     b my_exit 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
@  Your code starts here  @ 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 

foo: 
     cmp r0,r1 
     blt Less 
     bge More 
     mov r0,r1 
     b Exit 
Less: 
     mov r3,r0 
     add r0,r0,#1 
     add r3,r3,r0 
     cmp r0,r1 
     blt More 
     mov r0,r3 
More: 
     mov r0,#0 
Exit: 
     bx lr 

私が抱えている問題は、入力した数字に関係なく、常に0の出力が得られます。

+0

「Less:」で何をしようとしているのか分かりませんが、正しくはありません。あなたがしなければならないことは、引数 'a + 1、b'を使って' foo'を呼び出し、その結果に 'a'の現在の値を返します。 – Michael

+0

'bge'は'の正しい条件ではありません(https://community.arm.com/groups/processors/blog/2010/07/16/condition-codes-1-condition-flags-and-codes) (a == bまたはR0 == R1)を返したい場合は、単に 'bgt'だけです。 'foo'の残りの部分は再帰または* inline *を使い、再帰は使わないことができます。私は[コンパイラーが何をしているか](https://godbolt.org/g/ivsdCn)を調べるだろう。 –

+0

ありがとうございます。私はそれをbgtに変更し、私が間違っていたことをより正確に特定することができました。最終的に私はそれをL2に変え、L2ではそれをやった。私は必要な結果を得るためにそれを得ました。ありがとうございました – Fireurza

答えて

1

あなたが欠けているのは、パラメータを渡して値を返す方法です。 ARM ABIには、相当:

int less(int a, int b) 

次のようになります。

  • a(最初のパラメータ)はR0
  • bに渡される(第二パラメータ)R1
  • リターンで渡されます値をr0に書き込む必要があります
  • mov 〜pc関数から復帰するには

だからless関数を呼び出すために、以下を行う必要があります。 - R0 にaを移動 - R1 にbを移動する - 機能(bllt)を呼び出し - bl(支店及びリンク)を呼び出していることを確認してください代わりにシンプルでb(支店)。 bl後の命令のアドレスがリターン を可能にするために、ブランチとリンクフォームのコピーは - また、あなたは関数を呼び出すとき、r0-r3が破損されることをcarrefulする必要がR0

から結果を取得します。また、他のレジスタを変更する必要がある場合は、それらをスタックにプッシュして復帰する前にリストアする必要があります。