我正在编写一个程序,它将在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)时,它应该跳到结束。
但显然没有。
谢谢!
答案 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”的位置。