无法在ARM程序集中突破无限循环

时间:2013-10-18 03:22:47

标签: assembly arm

我正在编写一个程序,它将在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

然后我启动我的main并且有一个应该持续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并且变为等于r4(即5)时,它应该跳到结束。

但显然没有。

谢谢!

1 个答案:

答案 0 :(得分:1)

假设printf和scanf是C函数,则r2和r3寄存器值可能会被破坏。 ARM ABI在不用作函数参数时将这些寄存器用作临时寄存器,因此不能保证它们不会被您调用的函数保存。

但是,ABI希望r4到r11在使用之前保存。因此,如果您在堆栈中保存r4到r6,使用r5和r6代替r2和r3,并在返回时恢复r4到r6,那么你的代码可能会工作。这样,你遵循ABI和printf,scanf不会干扰你的变量。

此外,如果显示“bl loop”,则需要将其替换为“b loop”,因此并不总是将链接寄存器设置为“end”的位置。