问题描述
我的主要源文件:
L0 LDR R0,=prompt
BL WriteString ;print prompt
BL ReadInt ;R0 = n
CMP R0,#0
BGE L1
LDR R0,=res0 ; invalid input
BL WriteString
B L0
L1 MOV R1,#2
L2 UDIV R2,R0,R1
MLS R2,R1,R2,R0
CBZ R2,L3
BL WriteInt
ADD R1,#1
CMP R1,R0
BLT L2
L3 SUB R0,#1
CBZ R0,L0 ;Error: A1176E: Branch offset 0xFFFFFFC8 out of range.
B L1
prompt DCB "Enter a positive integer: ",0
res0 DCB 13,10,"Invalid input",13,0
ALIGN
END
我还遇到了L2跳出循环的问题。任何建议将此代码改进为可正常使用的建议。
解决方法
这个ARM developer page说
CBZ和CBNZ
限制
分支目的地必须在指令之后的4到130个字节内,并且处于相同的执行状态。
您正尝试向后分支56个字节。
您可能想使用subs r0,#1
并在标志上分支; beq
和cbz
一样紧凑,但是可以向后分支。
此外,subs
和adds
可作为16位拇指指令使用,这与sub
和add
仅具有32位编码的情况不同,因此通常您希望无论如何。