Function 手臂功能不能正常恢复

Function 手臂功能不能正常恢复,function,assembly,arm,Function,Assembly,Arm,我无法理解为什么这个函数在返回时会反复调用self 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 se

我无法理解为什么这个函数在返回时会反复调用self

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)

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

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


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

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

我也看不出你的函数为什么会重复调用自己。您如何调用它?能否在ldmfd上设置断点并查看堆栈?(特别是堆叠的LR)。可能它正在崩溃(筛相对于堆栈位于何处,它有多大?)-还假设您是一个调用“Initialize”(在调用时更新LR)的“带有链接的分支”指令-否则您的LR将毫无意义。您的程序会破坏堆栈吗?反汇编是什么样子的(带有地址等),内存映射是什么样子的like@Dan第一次达到断点时LR为4100,随后所有时间为4108。我用bl来称呼它。如何知道筛子相对于烟囱的位置?我将其声明为sieve:.跳过MAXLIST*4,其中MAXLIST为100。我想这就是400字(实际上我不清楚有多少空间。skip实际上跳过了)?不,我试着保存R5,但没有任何区别。不过谢谢。奇怪的是,这是我能看到的可能出错的事情。函数是如何调用的?您是否可以调试和中断,并查看当您输入函数时,
lr
设置为什么?4100。当我将断点放在stmfd时,函数返回properlyWeird。。。您是在仿真器或某种设备上运行它吗?