0

我对为什么这个函数在它应该返回时反复调用它自己感到困惑。

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)

好的,我不能发布整个程序,因为它说“您的帖子没有太多上下文来解释代码部分;请更清楚地解释您的场景。”

4

2 回答 2

2

您正在覆盖R5而不先保存它。我不明白为什么它应该让函数自己调用,但它可能会给出某种奇怪的结果。

附带说明,如果您从 C 中调用此函数,R0-R3则不需要保存,因为它们是暂存寄存器。如果您从程序集中调用它,您当然可以创建自己的调用约定,这可能需要保存它们。

于 2012-04-21T14:39:17.677 回答
0

我用几个不同的 MAX 值尝试了你的代码,它工作正常:Initialize 在调用它的指令之后返回指令(bl Initialize)。假设您在此代码段之外正确地执行了所有操作,那么罪魁祸首似乎是您的 STR 指令。您正在使用 psedu ldr 获得 R1 中筛子的值。sieve 指向当您使用 .skip 而没有“填充”时隐式初始化为零的内存块。现在您正在使用ldr R1, [R1]在 R1 中加载零,然后您正在执行将str R4, [R1], #4地址零处的字归零。现在我不知道您要实现什么逻辑,但是如果我按照您的评论@initialize 筛子中的第一个和第二个元素为 0那么你的代码没有做你想做的事。根据您在内存中排列代码的方式,您可能会用零覆盖您自己的代码的一部分。可能是您的 Initialize 位于零内存地址,并且您正在用零覆盖堆栈上 lr 的值。我只是在胡乱猜测。如果您提供了有关您尝试实现的逻辑的一些信息以及更多代码,那么我可能能够更好地帮助您。您可以尝试的一件事是,一旦完成ldr R1, =sieve,请将 R1 留给您的 STR,并使用您ldr R1, [R1]喜欢的其他寄存器ldr R6, [R1]。根据您在调用者代码中使用 R6 的方式,您可能需要也可能不需要PUSH R6在堆栈上。这不是一个确切的答案,我想把它放在评论部分,但我没有足够的权限这样做。

于 2012-04-22T10:06:23.023 回答