0

この関数が戻る必要があるときに繰り返し自分自身を呼び出す理由について、私は立ち往生しています。

Initialize:
    stmfd sp!, {R0-R4,lr}
    mov R4, #0  @used for storing 0
    mov R0, #2
    mov R5, #0
    ldr R1, =sieve
    ldr R1, [R1]
    ldr R2, =primes
    ldr R2, [R2]
    str R4, [R1], #4    @intialize first and second elements in sieve to 0
    str R4, [R1]
    mov R4, #1  @used for storing 1
setToOne:
    str R4, [R1], #4
    add R0, R0, #1
    cmp R0, #MAX
    blt setToOne
    ldmfd sp!, {R0-R4,pc}   @For somereason Initialize repeats as if lr points back to its begining (instead of where it's called from)

「あなたの投稿にはコードセクションを説明するコンテキストがあまりありません。シナリオをより明確に説明してください」と書かれているため、プログラム全体を投稿することはできません。

4

2 に答える 2

2

R5最初に保存せずに上書きしています。なぜ関数自体を呼び出す必要があるのか​​ わかりませんが、おそらく何らかの奇妙な結果が生じるでしょう。

補足として、C からこの関数を呼び出す場合R0-R3、これらはスクラッチ レジスタであるため、保存する必要はありません。アセンブリから呼び出す場合は、もちろん独自の呼び出し規則を作成して保存する必要がある場合があります。

于 2012-04-21T14:39:17.677 に答える
0

MAX のいくつかの異なる値を使用してコードを試してみましたが、正常に動作しています。Initialize は、それを呼び出した命令 (bl Initialize) の直後に命令に戻ります。このコード スニペットの外ですべてを正しく行っていると仮定すると、犯人は STR 命令にあるようです。疑似ldrを使用して、R1のふるいの値を取得しています。sieve は、「塗りつぶし」なしで .skip を使用したときに暗黙的にゼロとして初期化されたメモリ チャンクを指します。今ldr R1, [R1]、R1 にゼロをロードしているを使用しており、後でstr R4, [R1], #4アドレス ZERO のワードをゼロに設定しています。今、あなたが実装しようとしているロジックはわかりませんが、あなたのコメントを@initializeする場合、ふるいの最初と2番目の要素を0にしますあなたのコードはあなたがしたいことをしていません。コードをメモリに配置する方法によっては、独自のコードの一部をゼロで上書きする可能性があります。Initialize がゼロのメモリ アドレスにあり、スタック上の lr の値をゼロで上書きしている可能性があります。私は勝手な推測をしているだけです。実装しようとしているロジックの情報とコードの詳細を提供していただければ、より適切にサポートできたかもしれません。試してみることができることの 1 つは、完了したらldr R1, =sieve、R1 を STR 用に取っておき、代わりにldr R1, [R1]他のレジスタを使用することです。ldr R6, [R1]呼び出し元コードで R6 をどのように使用しているかによって、R6 をPUSHする必要がある場合とない場合があります。スタック上。これは正確な答えではありません。これをコメントセクションに入れたかったのですが、そうするのに十分な権限がありません。

于 2012-04-22T10:06:23.023 に答える