0

ARM アセンブリで stdin から 5 つの整数を加算するプログラムを作成していますが、無限ループに達しており、その理由がわかりません。

基本的なことを定義することから始めます

/*defines functions*/
    .section        .rodata
promptString:
     .ascii "Enter numbers: \000"
readString:
    .ascii "%d\000"
printSum:
    .ascii  "sum=%d\n\000"
/*global varibles*/
.section        .data
    .align 2

    .comm   string,4,4
    .text
/*sets addresses*/
addrString: .word string
addrPromptString:   .word promptString
addrReadString: .word readString
addrPrintSum:   .word printSum

次に、メインを開始し、5回の反復が続くはずのループがありますが、代わりに無限ループに到達します

main:
    stmfd sp!, {fp, lr}
    mov r3,#0
    mov r2,#0
    mov r4,#5

loop:
    cmp r3,r4
    beq end

    ldr r0, addrPromptString
    bl  printf

    ldr r0, addrReadString
    ldr r1, addrString
    bl  scanf

    add r2,r2,r1
    add r3,r3,#1
    bl  loop
end:

    ldr  r2, addrPrintSum
    bl   printf

    ldmfd   sp!, {fp, pc}

私が健全な論理だと思うものでは、r3が5に達し、5であるr4と等しくなるとジャンプして終了するはずです。

しかし、明らかにそうではありません。

ありがとう!

4

1 に答える 1

1

printf と scanf が C 関数であると仮定すると、r2 と r3 のレジスタ値が上書きされる可能性があります。ARM ABI は、関数パラメーターとして使用されていない場合、これらのレジスターを一時レジスターとして使用するため、呼び出した関数によって保存される保証はありません。

ただし、ABI は、r4 から r11 までが使用される前に保存されることを想定しています。したがって、スタックに r4 から r6 を保存し、r2 と r3 の代わりに r5 と r6 を使用し、戻るときに r4 から r6 を復元すると、コードが機能する可能性があります。そうすれば、ABI に従い、printf と scanf が変数に干渉することはありません。

また、「bl ループ」と表示されている場合は、「b ループ」に置き換える必要があるため、リンク レジスタが常に「end」の位置に設定されるとは限りません。

于 2013-10-18T03:55:22.860 に答える