我很困惑为什么这个函数应该在它返回时反复调用它。
Initialize:
stmfd sp!, {R0-R4,lr}
mov R4, #0 @used for storing 0
mov R0, #2
mov R5, #0
ldr R1, =sieve
ldr R1, [R1]
ldr R2, =primes
ldr R2, [R2]
str R4, [R1], #4 @intialize first and second elements in sieve to 0
str R4, [R1]
mov R4, #1 @used for storing 1
setToOne:
str R4, [R1], #4
add R0, R0, #1
cmp R0, #MAX
blt setToOne
ldmfd sp!, {R0-R4,pc} @For somereason Initialize repeats as if lr points back to its begining (instead of where it's called from)
好的我无法发布整个程序,因为它说“你的帖子没有太多的上下文来解释代码部分;请更清楚地解释你的场景。”
答案 0 :(得分:2)
您首先覆盖R5
而不保存。我不明白为什么它应该让函数调用本身,但它可能会产生某种奇怪的结果。
作为旁注,如果从C调用此函数,则R0-R3
不需要保存,因为它们是临时寄存器。如果你从汇编中调用它,你当然可以创建自己的调用约定,这可能需要保存它们。
答案 1 :(得分:0)
我用几个不同的MAX值尝试了你的代码,它运行正常:初始化
正在返回到调用它之后的指令(bl Initialize)。假设你在这个代码片段之外正确地做了一切,罪魁祸首似乎是你的STR指令。您正在使用psedu ldr获得R1中的筛子值。筛选指向在没有“填充”的情况下使用.skip时隐式初始化为零的内存块。现在您使用的是ldr R1, [R1]
,它在R1中加载零,之后您正在执行str R4, [R1], #4
,这会将地址归零ZERO。现在我不知道你想要实现什么逻辑但是如果我将你的评论 @intialize第一和第二个元素筛选为0 那么你的代码没有按照你想要它做的。根据您在内存中安排代码的方式,您可能会用零覆盖自己代码的一部分。
可能是您的Initialize为零内存地址,并且您正在用零覆盖堆栈上的lr值。我只是在猜测。如果您提供了一些有关您要实现的逻辑和更多代码的信息,那么我可能能够更好地帮助您。您可以尝试的一件事是,一旦完成ldr R1, =sieve
,请将R1放在一边,放弃STR并使用ldr R1, [R1]
中的其他注册表,例如ldr R6, [R1]
。根据您在呼叫者代码中使用R6的方式,您可能需要也可能不需要在堆栈上 PUSH R6 。这不是一个确切的答案,我想把它放在评论部分,但我没有足够的权限这样做。