【问题标题】:Cannot break out of infinite loop in ARM assembly无法在 ARM 程序集中跳出无限循环
【发布时间】:2013-10-18 03:22:47
【问题描述】:

我正在编写一个程序,它将 ARM 程序集中的标准输入中的 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。

但显然不是。

谢谢!

【问题讨论】:

标签: assembly arm


【解决方案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”的位置。

【讨论】:

  • 我按照你说的改了代码,没有死循环,但是一输入第5个整数就立即出现分段错误。
  • 那么您应该更新问题中的代码,这里的大多数人都没有水晶球。 ;)
  • 我注意到在循环之后,您没有为 printf 设置 r0 和 r1,因此它们的值是不明确的。另外,你为 r2 设置的内容属于 r0,printf 中的第一个参数,而 r1 应该是你希望打印出来的总和。
  • 另外,在 scanf 之后,您需要先从地址“string”加载值,然后再添加到总和。即使假设 r1 没有被 scanf 或其被调用者破坏,您也只是将它的地址添加到总和中。
猜你喜欢
  • 1970-01-01
  • 2022-10-14
  • 2020-01-03
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多