Assembly 程序可以从主服务器返回吗?为什么链接寄存器的值和程序计数器的值相同?

Assembly 程序可以从主服务器返回吗?为什么链接寄存器的值和程序计数器的值相同?,assembly,arm,cpu-registers,rtos,Assembly,Arm,Cpu Registers,Rtos,更新: DNMManager_GetName函数的原型,由Codo提出 截图4 我正在研究基于ARMCortex-A8CPU的RTOS行为,使用IDE调试器提供的断点 在屏幕截图1中,我注意到当程序在main函数的入口点冻结时,链接寄存器包含0x805dcda0,这是而(1)的地址 while(1)不是main函数的调用者,但是链接寄存器包含while(1)的地址 为什么? 谁放的 截图1 下面的屏幕截图2是一个示例,显示在程序进入函数INTAITCINIT()后,链接寄存器的值更改为正确的值

更新: DNMManager_GetName函数的原型,由Codo提出

截图4
我正在研究基于ARMCortex-A8CPU的RTOS行为,使用IDE调试器提供的断点

在屏幕截图1中,我注意到当程序在
main
函数的入口点冻结时,链接寄存器包含0x805dcda0,这是
而(1)
的地址

while(1)
不是
main
函数的调用者,但是链接寄存器包含
while(1)
的地址

为什么?

谁放的

截图1 下面的屏幕截图2是一个示例,显示在程序进入函数INTAITCINIT()后,链接寄存器的值更改为正确的值,即
OS_Init()的地址

截图2
第二个问题

在程序执行期间,我发现程序计数器的值在某些时间点等于链接寄存器的值

这让我感到困惑,因为我认为这两个寄存器永远不会是相同的值

下面的屏幕截图3是两个寄存器的值相同的情况

这是怎么发生的?在什么情况下

截图3
由于您只显示了几个屏幕截图,而不是完整的代码,我只能推测

屏幕截图1:入口点

除了在Windows或Linux上,微控制器的程序不应从main()返回。无处可去。为了防止进一步的损坏,LR指向一个无止境的循环。如果您意外地从main()返回,程序流将转到该位置

屏幕截图2:intaincinit()

没有问题

屏幕截图3:PC=LR

LR包含输入函数时的返回地址。如果函数调用其他函数,则必须保存LR(通常在堆栈上)并为其分配一个新值。屏幕截图显示语句后的状态:

char name_utf8[40] = {0};
805AFECC    bl  DNMManager_GetName
如果查看汇编代码,可以看到调用memset是为了将40字节初始化为0。因此,实际上调用了另一个函数,屏幕截图显示了从memset返回后的状态。每次函数刚返回时,PC必须等于LR,因为这就是返回的工作原理。所以这里一切都好

屏幕截图4:DNMManager_GetName

屏幕截图显示了输入DNMManager_GetName()时的状态。对该函数的调用是通过以下语句进行的:

char name_utf8[40] = {0};
805AFECC    bl  DNMManager_GetName
调用后的语句(需要返回的地方)是0x805AFED0,这就是LR在屏幕截图上包含的内容


请注意,C代码中的一行导致两个函数调用,一个调用DNMManager_GetName(),另一个调用memcpy。0x805AFEE4将是第二个函数调用的返回地址。但是屏幕截图4显示了第一个函数调用的状态。

由于您只显示了几个屏幕截图,而没有显示完整的代码,我只能推测

屏幕截图1:入口点

除了在Windows或Linux上,微控制器的程序不应从main()返回。无处可去。为了防止进一步的损坏,LR指向一个无止境的循环。如果您意外地从main()返回,程序流将转到该位置

屏幕截图2:intaincinit()

没有问题

屏幕截图3:PC=LR

LR包含输入函数时的返回地址。如果函数调用其他函数,则必须保存LR(通常在堆栈上)并为其分配一个新值。屏幕截图显示语句后的状态:

char name_utf8[40] = {0};
805AFECC    bl  DNMManager_GetName
如果查看汇编代码,可以看到调用memset是为了将40字节初始化为0。因此,实际上调用了另一个函数,屏幕截图显示了从memset返回后的状态。每次函数刚返回时,PC必须等于LR,因为这就是返回的工作原理。所以这里一切都好

屏幕截图4:DNMManager_GetName

屏幕截图显示了输入DNMManager_GetName()时的状态。对该函数的调用是通过以下语句进行的:

char name_utf8[40] = {0};
805AFECC    bl  DNMManager_GetName
调用后的语句(需要返回的地方)是0x805AFED0,这就是LR在屏幕截图上包含的内容


请注意,C代码中的一行导致两个函数调用,一个调用DNMManager_GetName(),另一个调用memcpy。0x805AFEE4将是第二个函数调用的返回地址。但是屏幕截图4显示了第一次函数调用的状态。

请以文本而不是图片的形式发布。您当然可以将反汇编导出为文本日志。您的问题是什么?软件不是按预期工作吗?如果是这样,请描述您的期望和发生的情况。还是想更好地了解ARM微控制器的工作原理?或者你在寻找什么样的答案?DNMManager\u GetName
看起来像什么?它是不是
volatile char*DNMManager\u GetName(DNM\u s volatile*元素){…uint8\u t temp[40]={0};…return temp;}
?如果是这样,则返回指向堆栈上分配的内存的指针。内存在返回时即被释放。所以这将是未定义的行为。@Lundin嗨,我之所以发布图片是为了清晰。文字真的比图片更容易理解吗?@Codo是的。软件工作如预期,但我认为LR应该存储0x805AFEE4(返回地址),而不是0x805AFED0。请将其作为文本而不是图片发布。您当然可以将反汇编导出为文本日志。您的问题是什么?软件不是按预期工作吗?如果是这样,请描述您的期望和发生的情况。还是想更好地了解ARM微控制器的工作原理?或者你在寻找什么样的答案?DNMManager\u GetName看起来像什么?它是不是volatile char*DNMManager\u GetName(DNM\u s volatile*元素){…uint8\u t temp[4