2016-05-07 38 views
0

配列aを以下のARMプログラムに移植しようとしていますが、プログラムはiの値を入力するときに問題なく実行されましたが、現在はユーザー入力でインデックスを設定しようとしています。私の実装した_scanfは、これまで多くのプログラムで使用していた(他の多くのプログラムでも使用していた)のと同じ問題はありませんでしたが、このプログラムでは10で停止すると仮定していますが、それは続けると私は問題がどこにあるのか分からない。ARM:ユーザー入力から配列を正しく取り込む方法は?

.global main 
.func main 

main: 

    MOV R3, #0    @ initialze index variable 
    BL writeloop   @ call write function 
    BL readloop    @call read function (prints a) 

writeloop: 


    CMP R3, #10   @ check to see if we are done iterating 
    BEQ writedone   @ exit loop if done 
    LDR R1, =a    @ get address of a 
    LSL R2, R3, #2   @ multiply index*4 to get array offset 
    ADD R2, R1, R2   @ R2 now has the element address 
    BL _scanf 
    MOV R4,R0 
    STR R4, [R2]   @ write input to a[i] 
    ADD R3, R3, #1   @ increment index 
    B writeloop   @ branch to next loop iteration 
writedone: 
    MOV R3, #0    @ initialze index variable 
readloop: 
    CMP R3, #10   @ check to see if we are done iterating 
    BEQ readdone   @ exit loop if done 
    LDR R1, =a    @ get address of a 
    LSL R2, R3, #2   @ multiply index*4 to get array offset 
    ADD R2, R1, R2   @ R2 now has the element address 
    LDR R1, [R2]   @ read the array at address 
    PUSH {R3}    @ backup register before printf 
    PUSH {R1}    @ backup register before printf 
    PUSH {R2}    @ backup register before printf 
    MOV R2, R1    @ move array value to R2 for printf 
    MOV R1, R3    @ move array index to R1 for printf 
    BL _printf    @ branch to print procedure with return 
    POP {R2}    @ restore register 
    POP {R1}    @ restore register 
    POP {R3}    @ restore register 
    ADD R3, R3, #1   @ increment index 
    B readloop   @ branch to next loop iteration 
readdone: 
    MOV R3,#0    @reset counter (i) 


_scanf: 
    PUSH {LR}    @ store the return address 
    PUSH {R1}    @ backup regsiter value 
    LDR R0, =format_str  @ R0 contains address of format string 
    SUB SP, SP, #4   @ make room on stack 
    MOV R1, SP    @ move SP to R1 to store entry on stack 
    BL scanf    @ call scanf 
    LDR R0, [SP]   @ load value at SP into R0 
    ADD SP, SP, #4   @ remove value from stack 
    POP {R1}    @ restore register value 
    POP {PC}    @ restore the stack pointer and return 




_exit: 
    MOV R7, #4    @ write syscall, 4 
    MOV R0, #1    @ output stream to monitor, 1 
    MOV R2, #21    @ print string length 
    LDR R1, =exit_str  @ string at label exit_str: 
    SWI 0     @ execute syscall 
    MOV R7, #1    @ terminate syscall, 1 
    SWI 0     @ execute syscall 

_printf: 
    PUSH {LR}    @ store the return address 
    LDR R0, =printf_str  @ R0 contains formatted string address 
    BL printf    @ call printf 
    POP {PC}    @ restore the stack pointer and return 



.data 

format_str:  .asciz  "%d" 

.balign 4 
a:    .skip  40 
printf_str:  .asciz  "a[%d] = %d\n" 
exit_str:  .ascii  "Terminating program.\n" 
+0

' R3'は、発信者、保存されたレジスタであるを確認したい場合があります。 PS:デバッガの使い方を学んでください。 – Jester

+0

_scanfの戻り値はR0に格納する必要があります.R3はそれと何が関係していますか? – aero

+0

'R3'はカウンタとして使用しますが、ABIに従って呼び出し元が保存されているので、' BL scanf'は好きなように変更することがあります。 – Jester

答えて

0
.global main 
.func main 

main: 

    MOV R3, #0    @ initialze index variable 
    BL writeloop   @ call write function 
    BL readloop    @call read function (prints a) 

writeloop: 


    CMP R3, #10   @ check to see if we are done iterating 
    BEQ writedone   @ exit loop if done 
    LDR R1, =a    @ get address of a 
    LSL R2, R3, #2   @ multiply index*4 to get array offset 
    ADD R2, R1, R2   @ R2 now has the element address 
    BL _scanf 
    MOV R4,R0 
    STR R4, [R2]   @ write input to a[i] 
    ADD R3, R3, #1   @ increment index 
    B writeloop   @ branch to next loop iteration 
writedone: 
    MOV R3, #0    @ initialze index variable 
readloop: 
    CMP R3, #10   @ check to see if we are done iterating 
    BEQ readdone   @ exit loop if done 
    LDR R1, =a    @ get address of a 
    LSL R2, R3, #2   @ multiply index*4 to get array offset 
    ADD R2, R1, R2   @ R2 now has the element address 
    LDR R1, [R2]   @ read the array at address 
    PUSH {R3}    @ backup register before printf 
    PUSH {R1}    @ backup register before printf 
    PUSH {R2}    @ backup register before printf 
    MOV R2, R1    @ move array value to R2 for printf 
    MOV R1, R3    @ move array index to R1 for printf 
    BL _printf    @ branch to print procedure with return 
    POP {R2}    @ restore register 
    POP {R1}    @ restore register 
    POP {R3}    @ restore register 
    ADD R3, R3, #1   @ increment index 
    B readloop   @ branch to next loop iteration 
readdone: 
    MOV R3,#0    @reset counter (i) 


_exit: 
    MOV R7, #4    @ write syscall, 4 
    MOV R0, #1    @ output stream to monitor, 1 
    MOV R2, #21    @ print string length 
    LDR R1, =exit_str  @ string at label exit_str: 
    SWI 0     @ execute syscall 
    MOV R7, #1    @ terminate syscall, 1 
    SWI 0     @ execute syscall 

@ ---- Moved below _exit, added R2 and R3 to PUSH and POP 
_scanf: 
    PUSH {LR}    @ store the return address 
    PUSH {R1, R2, R3}    @ backup regsiter value 
    LDR R0, =format_str  @ R0 contains address of format string 
    SUB SP, SP, #4   @ make room on stack 
    MOV R1, SP    @ move SP to R1 to store entry on stack 
    BL scanf    @ call scanf 
    LDR R0, [SP]   @ load value at SP into R0 
    ADD SP, SP, #4   @ remove value from stack 
    POP {R1, R2, R3}    @ restore register value 
    POP {PC}    @ restore the stack pointer and return 

_printf: 
    PUSH {LR}    @ store the return address 
    LDR R0, =printf_str  @ R0 contains formatted string address 
    BL printf    @ call printf 
    POP {PC}    @ restore the stack pointer and return 



.data 

format_str:  .asciz  "%d" 

.balign 4 
a:    .skip  40 
printf_str:  .asciz  "a[%d] = %d\n" 
exit_str:  .ascii  "Terminating program.\n" 

あなたはBLのscanf`は、その値を破壊します `ようhttp://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf第5章、14ページ

関連する問題