Function 手臂功能不能正常恢复
我无法理解为什么这个函数在返回时会反复调用selfFunction 手臂功能不能正常恢复,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
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。。。您是在仿真器或某种设备上运行它吗?