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 并等于 r4 时跳到结束,即 5。

但显然不是。

谢谢!

4

1 回答 1

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”的位置。

于 2013-10-18T03:55:22.860 回答